🚀 Tanda API v2

Getting Started

Welcome to the Tanda API! This documentation steps you through authenticating to the API, as well as the various endpoints and methods supported.

Not sure where to start? Check out the quick start guide, or browse some code samples on GitHub.

There’s two ways to connect to the API. Use Authorization Code if you’re making an add-on for other Tanda users to use, or use Password if you’re building an integration just for your own account.

Authentication (Authorization Code)

Use Authorization Code authentication if you’re making an add-on for other Tanda customers to use. For example, if you are building an integration that connects your custom reporting platform to Tanda data, you’ll probably want to let lots of Tanda customers use it. This is the approach for you.

If you have a log in for the Tanda platform you have access to an Authorization code. This code is linked to your organisation and permisson levels. Just like using an account in Tanda the permission levels will give you the same access in the API, e.g. if you don’t have permission to approve a timesheet in Tanda, you won’t be able to do so via the API.

Once you have permission an a working Tanda account, you can get an application ID, secret, and redirect URI. You can get all of these from the applications page. With those details, follow these steps to authenticate a user using the Authorization Code authentication flow.

The Authorization Code approach uses the OAuth 2 authorization code grant type. If you aren’t familiar with it, this is a good, practical introduction.

https://my.tanda.co/api/oauth/authorize?scope=SCOPE1+SCOPE2&client_id=YOUR_APPLICATION_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code

1. Redirect the user to the authorize endpoint

Allow users on your website to authenticate themselves with Tanda by redirecting them to the following URL. Where APPLICATION_ID and REDIRECT_URI are the values specific to your app, and the scope parameter is the relevant Tanda OAuth2 scopes your want access to (more information: Scopes).

2. Catch the request to your redirect URI

The Tanda server will then redirect the request back to your redirect URI, with a request code in the URL parameters. So if your redirect URI is https://mysite.com/callback then the request will be made to https://mysite.com/callback?code=AUTHORIZATION_CODE.

For local testing, as the browser gets redirected to the URI, it is possible to set it to a local address (i.e. http://localhost:3000/callback) to allow you to test your OAuth web app before deploying your code.

curl https://my.tanda.co/api/oauth/token -X POST -H "Cache-Control: no-cache" \
-F "client_id=YOUR_APPLICATION_ID" \
-F "client_secret=YOUR_SECRET" \
-F "code=AUTHORIZATION_CODE" \
-F "redirect_uri=YOUR_REDIRECT_URI" \
-F "grant_type=authorization_code"

3. Make a POST request to the token endpoint

Now that you’ve got your authorization code, you can finally make the POST request to get your access token (don’t worry, this is the last step).

From your server/application make a POST request to https://my.tanda.co/api/oauth/token.

The response should look something like this:

{
  "access_token": "6833b9ecaa84ce420da3cafaa43124d241cb28b5287b72d131f6b38bcb64cd91",
  "token_type": "bearer",
  "expires_in": 7200,
  "refresh_token": "ddeb6480f06247e3635826dd5e3875ece6f64a27044516731a914897431ab446",
  "scope": "me",
  "created_at": 1457304578
}

expires_in is in seconds, so your token will last 2 hours. To learn how to refresh your token, see Refreshing your Token.

Refreshing your Token

curl https://my.tanda.co/api/oauth/token -X POST -H "Cache-Control: no-cache" \
-F "client_id=YOUR_APPLICATION_ID" \
-F "client_secret=YOUR_SECRET" \
-F "refresh_token=REFRESH_TOKEN" \
-F "redirect_uri=YOUR_REDIRECT_URI" \
-F "grant_type=refresh_token"

If you got your token using the Authorization Code authentication flow, and it expires, then using the the refresh_token you got above, you are able to refresh it by making a POST request to https://my.tanda.co/api/oauth/token.

The response should look something like this:

{
  "access_token": "ddeb6480f06247e3635826dd5e3875ece6f64a27044516731a914897431ab446",
  "token_type": "bearer",
  "expires_in": 7200,
  "refresh_token": "d0692903972ff6559ec5f0e3165cabd5b87f47e3613431ad53805b5397268206",
  "scope": "me",
  "created_at": 1457311778
}

You can now go on using this new access token for another 2 hours.

If your application’s access is revoked by the user, then you will need to run through the authentication process again to obtain a new access token.

Although the tokens only last for 2 hours, you can refresh your token as many times as you want. The refresh token has no expiry but can only be used once.

Authentication (Password)

Use Password authentication if you’re building an integration just for your own account. For example, if you’re building an integration for a specific customer - either as an in-house developer or as a consultant - this is the the approach for you.

If you’re using the API for a single account, the Password authentication flow is an easier way to get set up. You can authenticate via the command line using your Tanda login details, or you can just set up an access token through the Tanda API management page.

Access tokens generated using Password authentication never expire, but can be revoked from the API management page.

1. Make a POST request to the token endpoint

curl https://my.tanda.co/api/oauth/token -X POST -H "Cache-Control: no-cache" \
-F "username=USER_EMAIL" \
-F "password=USER_PASSWORD" \
-F "scope=SCOPE1 SCOPE2" \
-F "grant_type=password"

From your server/application make a POST request to https://my.tanda.co/api/oauth/token with the user’s email and password.

The response should look something like this:

{
  "access_token": "6833b9ecaa84ce420da3cafaa43124d241cb28b5287b72d131f6b38bcb64cd91",
  "token_type": "bearer",
  "scope": "me",
  "created_at": 1457304578
}

Password authenticated tokens have no expiry. They can also be created and revoked from the access tokens page.

Making Requests

Once either of the above authentication methods have been completed, you’ll have an access token (in the case of Authorization Code authentication, the token will only last for 2 hours).

Your access token will look something like this: 6833b9ecaa84ce420da3cafaa43124d241cb28b5287b72d131f6b38bcb64cd91. From here on out all requests you make to the Tanda v2 API must include the token in the header like so:

curl --header "Authorization: bearer 6833b9ecaa84ce420da3cafaa43124d241cb28b5287b72d131f6b38bcb64cd91" \
https://my.tanda.co/api/v2/users/me
Authorization: bearer 6833b9ecaa84ce420da3cafaa43124d241cb28b5287b72d131f6b38bcb64cd91

See the right hand sidebar for an example of a request that gets information about the user that just authenticated.

Invalid Subscriptions

If you receive a 402 response status with this message:

Your account is locked out for billing purposes, and cannot use the API!

This indicates that the customer’s account does not have a valid credit card or other billing method set, and their free trial has ended. Therefore they will not be able to access some components of Tanda either through the website or the API.

You can query the current user endpoint to check if a user has a valid subscription.

Rate Limiting

If you reach the rate limit, you’ll get the following 429 response:

Headers

X-RateLimit-Limit:       200
X-RateLimit-RateLimited: true
X-RateLimit-Remaining:   0
X-RateLimit-Reset:       1461211225

Body

{
  "error": "API rate limit exceeded!"
}

Requests to the API are rate limited to 200 requests, per 1 minute for each requester.

A requester is defined through the following workflow:

  • Is the request using a Password Access Token?
    • Yes? Then the requester is the current user (meaning all requests made though any of my password tokens are counted together).
    • No? The the requester is the combination of the OAuth app and current user.

When making requests to the API, the following headers will be added to the response:

X-RateLimit-Limit:     200
X-RateLimit-Remaining: 52
X-RateLimit-Reset:     1461211225
  • X-RateLimit-Limit is the your rate limit

  • X-RateLimit-Remaining is the remaining number of requests you can make before you will be rate limited

  • X-RateLimit-Reset is when the rate limit will be reset

If have reached the rate limit, then an additional header will be present:

X-RateLimit-RateLimited: true

Here’s an example to make things a little clearer:

  • I have multiple Password Access Tokens with different scopes, token_1, token_2.

  • I have an OAuth app, which is used by user_1, user_2 and myself.

  • user_2 has also created an OAuth app which I am using.

This is the maximum number of requests that can be made in a single minute:

  • 199 requests with token_1

  • 1 request with token_2 (I have 200 requests/min for all my Password Access Tokens)

  • 200 requests on my behalf through user_2's OAuth app

  • 200 requests on my behalf through my OAuth app

  • 200 requests on user_1's behalf through my OAuth app

  • 200 requests on user_2's behalf through my OAuth app

In summary the distinct requesters in this example are:

  • Me through my Password Access Tokens

  • Me through user_2's OAuth app

  • Me through my OAuth app

  • user_1 through my OAuth app

  • user_2 through my OAuth app

Caching

curl --header "If-None-Match: 17f1542065ae37d0963a608fd632b4615a288ceb" --header "Authorization: bearer 6833b9ecaa84ce420da3cafaa43124d241cb28b5287b72d131f6b38bcb64cd91" \
https://my.tanda.co/api/v2/users/me

The Tanda API supports the If-None-Match HTTP header. All API responses will include an ETag response header. You can use the value of this header in future requests to the same endpoint by passing it to the If-None-Match request header. If the content the API would return has not changed, you will get back a 304 Not Modified response.

The right sidebar has an example of an ETag being included in a request. For more information about ETags and If-None-Match, see Mozilla’s guide.

TLS Version

The Tanda API only supports TLS version 1.2 or higher. If your API client attempts to connect with a lower version of TLS or SSL then you will recieve a TLS handshake error.

Scopes

In both the Authorization Code and Password authentication methods, you are required to include a scope parameter. Here is a complete list of the scopes in the Tanda API, additionally, in this documentation each endpoint specifies which scope/s it requires.

Scope Endpoints Description
me Users, Shift Reminders Access information about the current user
roster Rosters, Schedules, Schedule Swap Plans, Custom Events Manage roster, schedule information, shift swaps and custom events
timesheet Timesheets, Shifts Manage timesheet and shift information
department Locations, Teams (Departments), Shift Details, Custom Events Manage location, department (team), and shift detail information
user Users, Award Tags, Clock Ins Manage personal information about your employees (without wages)
cost Users, Timesheets, Shifts, Rosters, Schedules, WageComparisons Mange information about your employee’s wage, and see costs for timesheets and rosters
leave Leave Requests, Leave Balances Manage leave requests and balances
unavailability Unavailability Manage unavailability
datastream Data Streams, Data Stream Joins, Store Stats Manage your data streams and store stats
device Devices, Clock Ins Manage timeclock information, and read clock ins for devices
qualifications Qualifications Manage qualifications
settings Settings, Award Templates Manage account settings and award related configuration
organisation Organisations View & create client organisations
sms SMS Send SMS
personal Personal Details Manage your personal details (without Bank Details, TFN, etc)
financial Personal Details, Users Access financial data about your employees (Bank Details, TFN, etc)
platform Platform Get platform data

Not only will you need the relevant scopes to access the endpoints, but also the correct system permissions in Tanda. For more information see each endpoint group.

By selecting only the bare minimum scopes that your application needs, users will feel more comfortable authorizing your application.

For example: If you had all scopes selected but your application simply collects information about users (using the User endpoint, and user scope) people will question why your application needs to have access to timesheet data (timesheet scope) and will be less likely to approve it.

Dates and Times

All dates in the Tanda API are rendered in YYYY-MM-DD format. Any request you make must use YYYY-MM-DD format for all dates.

All times in the Tanda API are rendered as Unix time, this is to avoid confusion as there can be users with different timezones in the same organisation. A user’s timezone can be retrieved from the both the User endpoint and the Current User endpoint. Any request you make must use Unix time for all times.

Our user guide has more information on working with unix times through the API.

Update Timestamps

As well as the fields listed in the API examples below, every API response will also include an updated_at timestamp. This represents the last time that an object was updated. Like all other times returned by the API, it will be formatted as a Unix timestamp.

Many GET endpoints support an updated_after querystring parameter. Use this to filter results API-side by the updated_at field. Some endpoints also support a show_costs parameter, and return a last_costed_at field. If you pass both show_costs and updated_after, we will compare to both the updated_at and last_costed_at field when filtering.

An example may illustrate this better. Say you have a shift, and at 10am you change its start time. Then, at 11am, costing details for the shift’s employee are changed, which causes the cost of the shift to update. The shift’s updated_at will be 10am, while its last_costed_at will be 11am. If you make a call to the shift GET endpoint with updated_after of 10:30am, the shift will not be returned. But if you include the show_costs parameter when making the call, the shift will be returned since it was last costed after 10:30am.

Audit Trails

Every change made in Tanda through the API is logged and added to the in-Tanda audit trail. By default, changes will be marked as being made by “API v2”, with the user ID that corresponds to the authenticated user. If you’re building an integration that requires more fine tuned auditing (for example, a token is shared by multiple users, but you’re able to identify which user is responsible for a particular action), you can customise the user ID and audit trail name that are displayed. Email developers@tanda.co and we can help you set this up.

Code Samples

We have a repository of code samples available on GitHub. Here’s some guides you might find helpful:

Show us what you built!

If you’ve built something neat using the API, we’d love to see it. If you’ve already been chatting to someone from our team, odds are they’d love to see a demo of your integration. Or if you haven’t met any of our team before, a good way to introduce yourself is to email developers@tanda.co.

General

Current User

GET https://my.tanda.co/api/v2/users/me
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "name": "Lenny Leonard",
  "email": "lenny.leonard@springfieldpowerplant.com",
  "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "organisation": "Moe's Tavern",
  "organisation_id": 126546,
  "locale": "en-US",
  "country": "United States",
  "permissions": [
    "employee",
    "manager"
  ],
  "valid_subscription": true,
  "user_ids": [
    1,
    2,
    123456
  ],
  "organisations": [
    {
      "name": "Moe's Tavern",
      "id": 1,
      "user_id": 1,
      "locale": "en-US",
      "country": "United States"
    },
    {
      "name": "Bob's Burgers",
      "id": 2,
      "user_id": 1,
      "locale": "en-US",
      "country": "United States"
    },
    {
      "name": "Dave's Doors",
      "id": 3,
      "user_id": 123456,
      "locale": "en-AU",
      "country": "Australia"
    }
  ],
  "updated_at": 1478650040
}

Get Current User
GET/api/v2/users/me

Gets information about the current user (i.e. the user that has been authenticated).

The following fields are returned:

  • id - the user’s unique ID.

  • name - the user’s name.

  • email - the user’s email.

  • photo - if present, a link to a photo of the user.

  • time_zone - the name of the time zone the user is in - uses zone names from the IANA Time Zone Database. See our user guide for more on using times with the Tanda API.

  • utc_offset - the UTC offset for the current user, this can be used as a compliment to the time zone name. See our user guide for more on using times with the Tanda API.

  • organisation - the name of the currently authenticated organisation. A user can belong to one or more organisations. Unless otherwise specified on the individual endpoint, only data from this organisation will be returned by any API calls using the current access token.

  • organisation_id - the ID of the currently authenticated organisation. A user can belong to one or more organisations. Unless otherwise specified on the individual endpoint, only data from this organisation will be returned by any API calls using the current access token.

  • locale - the locale of the user.

  • country - the country the user’s organisation is based in.

  • permissions - The user’s privilege levels in the system, from the set of ['organisation_admin', 'payroll_officer', 'roster_manager', 'manager', 'employee', 'partner'].

  • valid_subscription - If true, the user will be able to access other API endpoints.

  • user_ids - User IDs associated with this user. This array will contain more than one item if the user has multiple profiles. If you want to get all data relating to a person across all their workplaces, use these. If you need to restrict your API call to a specific user, you can use the X-User-Id header and one of these IDs.

  • organisations - Organisations at which this user has profiles, based on user_ids. If your application needs to deal with people who may work at more than one Tanda organisation, you should use this. If you need to restrict your API call to a specific organisation, you can use the X-Organisation-Id header and one of these IDs. Note that a user may have multiple profiles within the same organisation.

This method requires the me scope (see Scopes for more information).


Rosters

Rosters are the container for scheduled shifts, each roster runs for 1 week and contains Schedules. For actual times worked, please see Timesheets or Shifts.

Rosters are not created directly. Instead a roster will be created when creating through the Schedules endpoint.

No special Tanda permissions are required to use the roster endpoint.

Roster

GET https://my.tanda.co/api/v2/rosters/70074?show_costs=true
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 70074,
  "schedules": [
    {
      "date": "2016-03-02",
      "schedules": [
        {
          "id": 31337157,
          "roster_id": 70074,
          "user_id": 123456,
          "start": 1456902000,
          "finish": 1456916400,
          "breaks": [
            {
              "start": 1456909200,
              "finish": 1456911000
            }
          ],
          "automatic_break_length": 30,
          "department_id": 111,
          "shift_detail_id": 36,
          "cost": 20.19,
          "last_published_at": 1457002800,
          "acceptance_status: `not_accepted`": "Hello, world!",
          "record_id": 532432,
          "needs_acceptance": true,
          "creation_method": "manual",
          "creation_platform": "web"
        }
      ]
    }
  ],
  "start": "2016-02-29",
  "finish": "2016-03-07",
  "cost": 1200.2,
  "meta": {
    "page": 1,
    "page_size": 100,
    "total": 53360,
    "total_pages": 534
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the roster"
    },
    "schedules": {
      "type": "array",
      "description": "The roster broken down by days"
    },
    "start": {
      "type": "string",
      "description": "The date of the first day of the roster"
    },
    "finish": {
      "type": "string",
      "description": "The date of the last day of the roster"
    },
    "cost": {
      "type": "number",
      "description": "The total cost of the roster, if `show_costs=true` parameter is set"
    },
    "meta": {
      "type": "object",
      "properties": {
        "page": {
          "type": "number",
          "description": "The page number of data when DailyScheduleData is paginated."
        },
        "page_size": {
          "type": "number",
          "description": "The number of records per page when DailyScheduleData is paginated."
        },
        "total": {
          "type": "number",
          "description": "The total number of records in a query when DailyScheduleData is paginated."
        },
        "total_pages": {
          "type": "number",
          "description": "The total number of pages in a paginated query when DailyScheduleData is paginated."
        }
      },
      "description": "The pagination metadata, if `page` and `page_size` parameters are set"
    }
  },
  "required": [
    "id",
    "schedules",
    "start",
    "finish"
  ]
}

Get Roster
GET/api/v2/rosters/{id}{?show_costs}

Get a roster by id.

This method requires the roster scope (see Scopes for more information).

If you are using show_costs=true, the cost scope is also required.

URI Parameters
HideShow
id
number (required) Example: 70074

The id of the roster

show_costs
boolean (optional) Example: true

Whether to show the costs for the roster (defaults to false)


Current Roster

GET https://my.tanda.co/api/v2/rosters/current?show_costs=true
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 70074,
  "schedules": [
    {
      "date": "2016-03-02",
      "schedules": [
        {
          "id": 31337157,
          "roster_id": 70074,
          "user_id": 123456,
          "start": 1456902000,
          "finish": 1456916400,
          "breaks": [
            {
              "start": 1456909200,
              "finish": 1456911000
            }
          ],
          "automatic_break_length": 30,
          "department_id": 111,
          "shift_detail_id": 36,
          "cost": 20.19,
          "last_published_at": 1457002800,
          "acceptance_status: `not_accepted`": "Hello, world!",
          "record_id": 532432,
          "needs_acceptance": true,
          "creation_method": "manual",
          "creation_platform": "web"
        }
      ]
    }
  ],
  "start": "2016-02-29",
  "finish": "2016-03-07",
  "cost": 1200.2,
  "meta": {
    "page": 1,
    "page_size": 100,
    "total": 53360,
    "total_pages": 534
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the roster"
    },
    "schedules": {
      "type": "array",
      "description": "The roster broken down by days"
    },
    "start": {
      "type": "string",
      "description": "The date of the first day of the roster"
    },
    "finish": {
      "type": "string",
      "description": "The date of the last day of the roster"
    },
    "cost": {
      "type": "number",
      "description": "The total cost of the roster, if `show_costs=true` parameter is set"
    },
    "meta": {
      "type": "object",
      "properties": {
        "page": {
          "type": "number",
          "description": "The page number of data when DailyScheduleData is paginated."
        },
        "page_size": {
          "type": "number",
          "description": "The number of records per page when DailyScheduleData is paginated."
        },
        "total": {
          "type": "number",
          "description": "The total number of records in a query when DailyScheduleData is paginated."
        },
        "total_pages": {
          "type": "number",
          "description": "The total number of pages in a paginated query when DailyScheduleData is paginated."
        }
      },
      "description": "The pagination metadata, if `page` and `page_size` parameters are set"
    }
  },
  "required": [
    "id",
    "schedules",
    "start",
    "finish"
  ]
}

Get the Current Roster
GET/api/v2/rosters/current{?show_costs}

Get the current roster.

This method requires the roster scope (see Scopes for more information).

If you are using show_costs=true, the cost scope is also required.

URI Parameters
HideShow
show_costs
boolean (required) Example: true

Whether to show the costs for the roster (defaults to false)


Roster that Contains Date

GET https://my.tanda.co/api/v2/rosters/on/2016-03-02?show_costs=true
Responses200204
Headers
Content-Type: application/json
Body
{
  "id": 70074,
  "schedules": [
    {
      "date": "2016-03-02",
      "schedules": [
        {
          "id": 31337157,
          "roster_id": 70074,
          "user_id": 123456,
          "start": 1456902000,
          "finish": 1456916400,
          "breaks": [
            {
              "start": 1456909200,
              "finish": 1456911000
            }
          ],
          "automatic_break_length": 30,
          "department_id": 111,
          "shift_detail_id": 36,
          "cost": 20.19,
          "last_published_at": 1457002800,
          "acceptance_status: `not_accepted`": "Hello, world!",
          "record_id": 532432,
          "needs_acceptance": true,
          "creation_method": "manual",
          "creation_platform": "web"
        }
      ]
    }
  ],
  "start": "2016-02-29",
  "finish": "2016-03-07",
  "cost": 1200.2,
  "meta": {
    "page": 1,
    "page_size": 100,
    "total": 53360,
    "total_pages": 534
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the roster"
    },
    "schedules": {
      "type": "array",
      "description": "The roster broken down by days"
    },
    "start": {
      "type": "string",
      "description": "The date of the first day of the roster"
    },
    "finish": {
      "type": "string",
      "description": "The date of the last day of the roster"
    },
    "cost": {
      "type": "number",
      "description": "The total cost of the roster, if `show_costs=true` parameter is set"
    },
    "meta": {
      "type": "object",
      "properties": {
        "page": {
          "type": "number",
          "description": "The page number of data when DailyScheduleData is paginated."
        },
        "page_size": {
          "type": "number",
          "description": "The number of records per page when DailyScheduleData is paginated."
        },
        "total": {
          "type": "number",
          "description": "The total number of records in a query when DailyScheduleData is paginated."
        },
        "total_pages": {
          "type": "number",
          "description": "The total number of pages in a paginated query when DailyScheduleData is paginated."
        }
      },
      "description": "The pagination metadata, if `page` and `page_size` parameters are set"
    }
  },
  "required": [
    "id",
    "schedules",
    "start",
    "finish"
  ]
}
Headers
Content-Type: application/json

Get Roster that Contains Date
GET/api/v2/rosters/on/{date}{?show_costs}

Get the roster that contains a date, will return a 204 response if there is no roster.

This method requires the roster scope (see Scopes for more information).

If you are using show_costs=true, the cost scope is also required.

URI Parameters
HideShow
date
string (required) Example: 2016-03-02

The date that’s contained in the roster you are looking for.

show_costs
boolean (optional) Example: true

Whether to show the costs for the roster (defaults to false)

page
number (optional) Example: 1

The page number for your nested schedule list

page_size
number (optional) Example: 50

The number of nested schedules retrieved per page. Maximum 100 per page.


Sales Targets

GET https://my.tanda.co/api/v2/rosters/sales_targets/type/2018-02-26
Responses200
Headers
Content-Type: application/json
Body
{
  "target": "1234.56",
  "created_at": 1519621685,
  "updated_at": 1519621685,
  "user_entered": true
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "target": {
      "type": "string",
      "description": "Value of the sales target. null if there is no roster for the given date."
    },
    "created_at": {
      "type": [
        "number",
        "null"
      ],
      "description": "When the user-entered sales target was first created, if there is one. Otherwise null."
    },
    "updated_at": {
      "type": [
        "number",
        "null"
      ],
      "description": "When the user-entered sales target was last updated, if there is one. Otherwise null."
    },
    "user_entered": {
      "type": "boolean",
      "description": "Whether or not the default projection was overridden with a user-entered value."
    }
  },
  "required": [
    "created_at",
    "updated_at",
    "user_entered"
  ]
}

Get Sales Target
GET/api/v2/rosters/sales_targets/{type}/{date}

Get the sales target for a given roster with no filter.

This method requires the roster scope (see Scopes for more information).

URI Parameters
HideShow
type
string (required) 

There are two possible values: day and week.

date
string (required) Example: 2018-02-26

A date within the roster you are looking for.


Sales Targets for Team (Department)

GET https://my.tanda.co/api/v2/rosters/sales_targets/type/2018-02-26?department_id=123
Responses200
Headers
Content-Type: application/json
Body
{
  "target": "1234.56",
  "created_at": 1519621685,
  "updated_at": 1519621685,
  "user_entered": true
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "target": {
      "type": "string",
      "description": "Value of the sales target. null if there is no roster for the given date."
    },
    "created_at": {
      "type": [
        "number",
        "null"
      ],
      "description": "When the user-entered sales target was first created, if there is one. Otherwise null."
    },
    "updated_at": {
      "type": [
        "number",
        "null"
      ],
      "description": "When the user-entered sales target was last updated, if there is one. Otherwise null."
    },
    "user_entered": {
      "type": "boolean",
      "description": "Whether or not the default projection was overridden with a user-entered value."
    }
  },
  "required": [
    "created_at",
    "updated_at",
    "user_entered"
  ]
}

Get Target for Team
GET/api/v2/rosters/sales_targets/{type}/{date}{?department_id}

Get the sales target for a given roster filtered to a team.

You must either be an Admin or General Manager, or have read access to the team you are requesting.

This method requires the roster scope (see Scopes for more information).

URI Parameters
HideShow
type
string (required) 

There are two possible values: day and week.

date
string (required) Example: 2018-02-26

A date within the roster you are looking for.

department_id
number (optional) Example: 123

The ID of a team to filter the roster to.


Sales Targets for Location

GET https://my.tanda.co/api/v2/rosters/sales_targets/type/2018-02-26?location_id=456
Responses200
Headers
Content-Type: application/json
Body
{
  "target": "1234.56",
  "created_at": 1519621685,
  "updated_at": 1519621685,
  "user_entered": true
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "target": {
      "type": "string",
      "description": "Value of the sales target. null if there is no roster for the given date."
    },
    "created_at": {
      "type": [
        "number",
        "null"
      ],
      "description": "When the user-entered sales target was first created, if there is one. Otherwise null."
    },
    "updated_at": {
      "type": [
        "number",
        "null"
      ],
      "description": "When the user-entered sales target was last updated, if there is one. Otherwise null."
    },
    "user_entered": {
      "type": "boolean",
      "description": "Whether or not the default projection was overridden with a user-entered value."
    }
  },
  "required": [
    "created_at",
    "updated_at",
    "user_entered"
  ]
}

Get Target for Location
GET/api/v2/rosters/sales_targets/{type}/{date}{?location_id}

Get the sales target for a given roster filtered to a location.

You must either be an Admin or General Manager, or have read access to the location you are requesting.

This method requires the roster scope (see Scopes for more information).

URI Parameters
HideShow
type
string (required) 

There are two possible values: day and week.

date
string (required) Example: 2018-02-26

A date within the roster you are looking for.

location_id
number (optional) Example: 456

The ID of a location to filter the roster to.


Schedules

Schedules represent planned shifts for a user and are contained in a Roster, for actual times worked please see Timesheets or Shifts.

No special Tanda permissions are required to view schedules, however only the schedules that would be visible through the UI are visible through the API.

To create or change schedules, the user must be a team manager, roster manager, or admin. In the case of the team manager, the shift must be for someone in the user’s managed teams.

Employees can only see published schedules. Specifying ids of unpublished schedules, or using the published_only flag will not change this.

Looking to just get the roster for an individual employee? Check out our user guide for a workflow.

Schedules

GET https://my.tanda.co/api/v2/schedules?ids=1,2,31337157&show_costs=true&include_names=false&include_colleagues=false&platform=false
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 31337157,
    "roster_id": 70074,
    "user_id": 123456,
    "start": 1456902000,
    "finish": 1456916400,
    "breaks": [
      {
        "start": 1456909200,
        "finish": 1456911000
      }
    ],
    "automatic_break_length": 30,
    "department_id": 111,
    "shift_detail_id": 36,
    "cost": 20.19,
    "last_published_at": 1457002800,
    "acceptance_status: `not_accepted`": "Hello, world!",
    "record_id": 532432,
    "needs_acceptance": true,
    "creation_method": "manual",
    "creation_platform": "web"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Schedules
GET/api/v2/schedules{?ids,show_costs,include_names,include_colleagues,platform}

Get multiple schedules by id.

This method requires the roster scope (see Scopes for more information).

If you are using show_costs=true or show_award_interpretation=true, the cost scope is also required.

URI Parameters
HideShow
ids
string (required) Example: 1,2,31337157

Comma separated list of schedule ids

show_costs
boolean (optional) Example: true

Whether to show the costs for the schedule (defaults to false).

show_award_interpretation
boolean (optional) Example: true

Whether to show costs breakdown for the schedule (defaults to false).

include_names
boolean (optional) Example: false

If true, the department name and shift detail name (not just ID) will be included in the response. Defaults to false.

include_colleagues
boolean (optional) Example: false

If true, shifts for colleagues will be returned. If false, only shifts for the current user will be returned. Defaults to false.

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false).

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified schedules

published_only
boolean (optional) Example: false

Only retrieve schedules that have been published. Useful for managers to see only published schedules, where they would usually see any schedule. Defaults to false.

show_vacant_only
boolean (optional) Example: false

Only retrieve schedules that are vacant. Defaults to false.


GET https://my.tanda.co/api/v2/schedules?user_ids=1,2,123456&from=2016-03-02&to=2016-03-02&show_costs=true&include_names=false
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 31337157,
    "roster_id": 70074,
    "user_id": 123456,
    "start": 1456902000,
    "finish": 1456916400,
    "breaks": [
      {
        "start": 1456909200,
        "finish": 1456911000
      }
    ],
    "automatic_break_length": 30,
    "department_id": 111,
    "shift_detail_id": 36,
    "cost": 20.19,
    "last_published_at": 1457002800,
    "acceptance_status: `not_accepted`": "Hello, world!",
    "record_id": 532432,
    "needs_acceptance": true,
    "creation_method": "manual",
    "creation_platform": "web"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Schedules by User
GET/api/v2/schedules{?user_ids,from,to,show_costs,include_names}

Get multiple schedules by user IDs, from, and to date. From and to date are required, while user IDs are optional. If no user IDs are provided, all visible schedules (based on the current user’s permission levels) will be returned.

This method requires the roster scope (see Scopes for more information).

If you are using show_costs=true, the cost scope is also required, and you must have access to see wages for all user IDs provided.

URI Parameters
HideShow
user_ids
string (required) Example: 1,2,123456

Comma separated list of user ids. You can pass user IDs from multiple different organisations, for example if you want to get all schedules for a particular person across companies.

from
string (required) Example: 2016-03-02

From date to lookup schedules in. If provided, from and to can be at most 7 days apart.

to
string (required) Example: 2016-03-02

To date to lookup schedules in. If provided, from and to can be at most 7 days apart.

show_costs
boolean (optional) Example: true

Whether to show the costs for the schedule (defaults to false).

show_award_interpretation
boolean (optional) Example: true

Whether to show costs breakdown for the schedule (defaults to false).

include_names
boolean (optional) Example: false

If true, the department name and shift detail name (not just ID) will be included in the response. Defaults to false.

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified schedules


POST https://my.tanda.co/api/v2/schedules
RequestsCreate ScheduleCreate vacant Schedule
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "start": 1456903800,
  "finish": 1456911000,
  "department_id": 111,
  "automatic_break_length": 30
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 31337158,
  "roster_id": 70074,
  "user_id": 123456,
  "start": 1456903800,
  "finish": 1456911000,
  "breaks": [],
  "automatic_break_length": 30,
  "department_id": 111,
  "shift_detail_id": null,
  "last_published_at": null,
  "last_acknowledged_at": null,
  "acceptance_status": "not_accepted"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the schedule"
    },
    "roster_id": {
      "type": "number",
      "description": "The id of the roster"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who is assigned the schedule"
    },
    "start": {
      "type": "number",
      "description": "The start of the schedule"
    },
    "finish": {
      "type": "number",
      "description": "The end of the schedule"
    },
    "breaks": {
      "type": "array",
      "description": "The breaks taken in the schedule"
    },
    "automatic_break_length": {
      "type": "number",
      "description": "Length of automatic break in minutes"
    },
    "department_id": {
      "type": "number",
      "description": "The department (team) id for the schedule"
    },
    "shift_detail_id": {
      "type": "number",
      "description": "The shift detail id for the schedule"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the schedule, if `show_costs=true` parameter is set"
    },
    "last_published_at": {
      "type": "number",
      "description": "When the schedule was last published to its given employee"
    },
    "acceptance_status: `not_accepted`": {
      "type": "string",
      "description": "The current status of the schedule"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "needs_acceptance": {
      "type": "boolean",
      "description": "Has the schedule been accepted by the employee?"
    },
    "creation_method": {
      "type": "string",
      "description": "How the schedule was created."
    },
    "creation_platform": {
      "type": "string",
      "description": "Where the schedule was created."
    }
  },
  "required": [
    "id",
    "roster_id"
  ]
}
Headers
Content-Type: application/json
Body
{
  "start": 1456903800
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 31337158,
  "roster_id": 70074,
  "user_id": null,
  "start": 1456903800,
  "finish": null,
  "breaks": [],
  "automatic_break_length": null,
  "department_id": null,
  "shift_detail_id": null,
  "last_published_at": null,
  "last_acknowledged_at": null,
  "acceptance_status": "not_accepted"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the schedule"
    },
    "roster_id": {
      "type": "number",
      "description": "The id of the roster"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who is assigned the schedule"
    },
    "start": {
      "type": "number",
      "description": "The start of the schedule"
    },
    "finish": {
      "type": "number",
      "description": "The end of the schedule"
    },
    "breaks": {
      "type": "array",
      "description": "The breaks taken in the schedule"
    },
    "automatic_break_length": {
      "type": "number",
      "description": "Length of automatic break in minutes"
    },
    "department_id": {
      "type": "number",
      "description": "The department (team) id for the schedule"
    },
    "shift_detail_id": {
      "type": "number",
      "description": "The shift detail id for the schedule"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the schedule, if `show_costs=true` parameter is set"
    },
    "last_published_at": {
      "type": "number",
      "description": "When the schedule was last published to its given employee"
    },
    "acceptance_status: `not_accepted`": {
      "type": "string",
      "description": "The current status of the schedule"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "needs_acceptance": {
      "type": "boolean",
      "description": "Has the schedule been accepted by the employee?"
    },
    "creation_method": {
      "type": "string",
      "description": "How the schedule was created."
    },
    "creation_platform": {
      "type": "string",
      "description": "Where the schedule was created."
    }
  },
  "required": [
    "id",
    "roster_id"
  ]
}

Create Schedule
POST/api/v2/schedules

This will create a Roster for the given date, if it does not already exist.

Only one of breaks and automatic_break_length can be set to non-null values.

This method requires the roster scope (see Scopes for more information).


Schedule

GET https://my.tanda.co/api/v2/schedules/31337157?show_costs=true&include_names=false&platform=false
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 31337157,
  "roster_id": 70074,
  "user_id": 123456,
  "start": 1456902000,
  "finish": 1456916400,
  "breaks": [
    {
      "start": 1456909200,
      "finish": 1456911000
    }
  ],
  "automatic_break_length": 30,
  "department_id": 111,
  "shift_detail_id": 36,
  "cost": 20.19,
  "last_published_at": 1457002800,
  "acceptance_status: `not_accepted`": "Hello, world!",
  "record_id": 532432,
  "needs_acceptance": true,
  "creation_method": "manual",
  "creation_platform": "web"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the schedule"
    },
    "roster_id": {
      "type": "number",
      "description": "The id of the roster"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who is assigned the schedule"
    },
    "start": {
      "type": "number",
      "description": "The start of the schedule"
    },
    "finish": {
      "type": "number",
      "description": "The end of the schedule"
    },
    "breaks": {
      "type": "array",
      "description": "The breaks taken in the schedule"
    },
    "automatic_break_length": {
      "type": "number",
      "description": "Length of automatic break in minutes"
    },
    "department_id": {
      "type": "number",
      "description": "The department (team) id for the schedule"
    },
    "shift_detail_id": {
      "type": "number",
      "description": "The shift detail id for the schedule"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the schedule, if `show_costs=true` parameter is set"
    },
    "last_published_at": {
      "type": "number",
      "description": "When the schedule was last published to its given employee"
    },
    "acceptance_status: `not_accepted`": {
      "type": "string",
      "description": "The current status of the schedule"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "needs_acceptance": {
      "type": "boolean",
      "description": "Has the schedule been accepted by the employee?"
    },
    "creation_method": {
      "type": "string",
      "description": "How the schedule was created."
    },
    "creation_platform": {
      "type": "string",
      "description": "Where the schedule was created."
    }
  },
  "required": [
    "id",
    "roster_id"
  ]
}

Get Schedule
GET/api/v2/schedules/{id}{?show_costs,include_names,platform}

Get a schedule by id.

If you are not able to see the schedule through the UI then you will not be able to see it through the API.

This method requires the roster scope (see Scopes for more information).

If you are using show_costs=true, the cost scope is also required.

URI Parameters
HideShow
id
number (required) Example: 31337157

The id of the schedule

show_costs
boolean (optional) Example: true

Whether to show the costs for the schedule (defaults to false)

show_award_interpretation
boolean (optional) Example: true

Whether to show costs breakdown for the schedule (defaults to false).

include_names
boolean (optional) Example: false

If true, the department name and shift detail name (not just ID) will be included in the response. Defaults to false.

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false).


PUT https://my.tanda.co/api/v2/schedules/31337157
RequestsUpdate ScheduleMake Schedule vacantGive Schedule automatic break
Headers
Content-Type: application/json
Body
{
  "start": 1456898400,
  "breaks": [
    {
      "start": 1456903800,
      "finish": 1456905600,
      "paid": false,
      "length": 30
    },
    {
      "start": 1456909200,
      "finish": 1456911000,
      "paid": true,
      "length": 30
    }
  ],
  "automatic_break_length": null,
  "department_id": null
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 31337157,
  "roster_id": 70074,
  "user_id": 123456,
  "start": 1456898400,
  "finish": 1456916400,
  "breaks": [
    {
      "start": 1456903800,
      "finish": 1456905600,
      "paid": false,
      "length": 30
    },
    {
      "start": 1456909200,
      "finish": 1456911000,
      "paid": false,
      "length": 30
    }
  ],
  "automatic_break_length": null,
  "department_id": null,
  "shift_detail_id": null,
  "last_published_at": null,
  "last_acknowledged_at": null,
  "acceptance_status": "not_accepted"
}
Headers
Content-Type: application/json
Body
{
  "user_id": nil
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 31337157,
  "roster_id": 70074,
  "user_id": null,
  "start": 1456902000,
  "finish": 1456916400,
  "breaks": [
    {
      "start": 1456909200,
      "finish": 1456911000,
      "paid": false,
      "length": 30
    }
  ],
  "department_id": 111,
  "shift_detail_id": null,
  "last_published_at": null,
  "last_acknowledged_at": null,
  "acceptance_status": "not_accepted"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the schedule"
    },
    "roster_id": {
      "type": "number",
      "description": "The id of the roster"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who is assigned the schedule"
    },
    "start": {
      "type": "number",
      "description": "The start of the schedule"
    },
    "finish": {
      "type": "number",
      "description": "The end of the schedule"
    },
    "breaks": {
      "type": "array",
      "description": "The breaks taken in the schedule"
    },
    "automatic_break_length": {
      "type": "number",
      "description": "Length of automatic break in minutes"
    },
    "department_id": {
      "type": "number",
      "description": "The department (team) id for the schedule"
    },
    "shift_detail_id": {
      "type": "number",
      "description": "The shift detail id for the schedule"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the schedule, if `show_costs=true` parameter is set"
    },
    "last_published_at": {
      "type": "number",
      "description": "When the schedule was last published to its given employee"
    },
    "acceptance_status: `not_accepted`": {
      "type": "string",
      "description": "The current status of the schedule"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "needs_acceptance": {
      "type": "boolean",
      "description": "Has the schedule been accepted by the employee?"
    },
    "creation_method": {
      "type": "string",
      "description": "How the schedule was created."
    },
    "creation_platform": {
      "type": "string",
      "description": "Where the schedule was created."
    }
  },
  "required": [
    "id",
    "roster_id"
  ]
}
Headers
Content-Type: application/json
Body
{
  "automatic_break_length": 25,
  "breaks": null
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 31337157,
  "roster_id": 70074,
  "user_id": 123456,
  "start": 1456902000,
  "finish": 1456916400,
  "breaks": [],
  "automatic_break_length": 25,
  "department_id": 111,
  "shift_detail_id": null,
  "last_published_at": null,
  "last_acknowledged_at": null,
  "acceptance_status": "not_accepted"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the schedule"
    },
    "roster_id": {
      "type": "number",
      "description": "The id of the roster"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who is assigned the schedule"
    },
    "start": {
      "type": "number",
      "description": "The start of the schedule"
    },
    "finish": {
      "type": "number",
      "description": "The end of the schedule"
    },
    "breaks": {
      "type": "array",
      "description": "The breaks taken in the schedule"
    },
    "automatic_break_length": {
      "type": "number",
      "description": "Length of automatic break in minutes"
    },
    "department_id": {
      "type": "number",
      "description": "The department (team) id for the schedule"
    },
    "shift_detail_id": {
      "type": "number",
      "description": "The shift detail id for the schedule"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the schedule, if `show_costs=true` parameter is set"
    },
    "last_published_at": {
      "type": "number",
      "description": "When the schedule was last published to its given employee"
    },
    "acceptance_status: `not_accepted`": {
      "type": "string",
      "description": "The current status of the schedule"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "needs_acceptance": {
      "type": "boolean",
      "description": "Has the schedule been accepted by the employee?"
    },
    "creation_method": {
      "type": "string",
      "description": "How the schedule was created."
    },
    "creation_platform": {
      "type": "string",
      "description": "Where the schedule was created."
    }
  },
  "required": [
    "id",
    "roster_id"
  ]
}

Update Schedule
PUT/api/v2/schedules/{id}

Only one of breaks and automatic_break_length can be set to non-null values. If automatic_break_length or breaks is already set, you will not be able to change the other unless the set field is cleared (can be done in the same request by setting the currently set field to null).

This method requires the roster scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 31337157

The id of the schedule


DELETE https://my.tanda.co/api/v2/schedules/31337157
Responses200
Headers
Content-Type: application/json

Delete Schedule
DELETE/api/v2/schedules/{id}

This method requires the roster scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 31337157

The id of the schedule


Schedule Versions

GET https://my.tanda.co/api/v2/schedules/31337157/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"Schedule\"",
    "changes": [
      {
        "field": "start",
        "previous": 1456898400,
        "updated": 1456902000
      },
      {
        "field": "finish",
        "previous": 1456912800,
        "updated": 1456916400
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Schedule Versions
GET/api/v2/schedules/{id}/versions

If you are not able to see the schedule through the UI then you will not be able to see it through the API.

This method requires the roster scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 31337157

The id of the schedule

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified schedule versions


Timesheets

Timesheets are the container for actual shifts worked, a timesheet can be for a period of 1 or 2 weeks depending on how the organisation pays their staff. Each timesheet contains many Shifts. For rostered times, please see Rosters or Schedules.

Timesheets are not created directly. Instead a timesheet will be created when creating through the Shifts endpoint.

Regular employees can only see their own timesheets, roster managers and admins can see all timesheets, and department managers can only see timesheets for staff that they manage.

All methods require the timesheet scope (see Scopes for more information).

Exporting Timesheets

You can download a timesheet in an export format to be imported into a payroll system by providing the export_format URI parameter. This works with any of the timesheet endpoints.

For example, making a call to /api/v2/timesheets/7007?export_format=myob will return a MYOB-compatible export of the timesheet, and /api/v2/timesheets/on/2016-03-02?export_format=myob will return a MYOB-compatible export of all timesheets for that date range.

By default all timesheets will be returned. Provide the approved_only parameter to limit your export to approved timesheets (this is the default behaviour in the Tanda UI). For example, /api/v2/timesheets/7007?export_format=myob&approved_only=true.

The content-type of these responses will not be application/json as they are for other API calls - it will depend on the export format requested, but will generally be text/plain or text/csv.

Timesheets will have their status set to exported when accessed through this endpoint. If you don’t want this to happen, include the skip_status_update parameter - eg. /api/v2/timesheets/7007?export_format=myob&skip_status_update=true. Alternatively, use the update timesheeet endpoint to reset their status.

Current Timesheets

GET https://my.tanda.co/api/v2/timesheets/current?show_costs=true&show_award_interpretation=true
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 7007,
    "user_id": 123456,
    "start": "2016-02-29",
    "finish": "2016-03-14",
    "status": "approved",
    "shifts": [
      {
        "id": 1337,
        "timesheet_id": 7007,
        "user_id": 123456,
        "date": "2016-03-02",
        "start": 1456902118,
        "break_start": 1456908143,
        "break_finish": 1456909812,
        "break_length": 27,
        "breaks": [
          {
            "id": 42,
            "shift_id": 1337,
            "start": 1456908143,
            "finish": 1456909812,
            "length": 27,
            "paid": false,
            "selected_automatic_break_id": 73647
          }
        ],
        "finish": 1456916286,
        "status": "PENDING",
        "allowances": [
          {
            "id": 456789,
            "name": "Hazardous Environment Allowance",
            "value": 0.5,
            "cost": 1.75
          }
        ],
        "tag": "Head Technician",
        "tag_id": 65421,
        "cost": 20.1,
        "award_interpretation": [
          {
            "units": 6.45,
            "date": "2016-02-29",
            "export_name": "ORD 1x",
            "secondary_export_name": "LOAD",
            "pay_class": "P1",
            "ordinary_hours": true,
            "cost": 16.125,
            "from": 1456902000,
            "to": 1456916400
          }
        ],
        "department_id": 808,
        "metadata": "My special metadata",
        "leave_request_id": 333,
        "record_id": 532432,
        "approved_by": 123455,
        "approved_at": "1456988518",
        "notes": [
          {
            "body": "Goals were kicked this shift 💪",
            "author": "Mike Richards"
          }
        ]
      }
    ],
    "cost": 102.15,
    "award_interpretation": [
      {
        "units": 6.45,
        "date": "2016-02-29",
        "export_name": "ORD 1x",
        "secondary_export_name": "LOAD",
        "pay_class": "P1",
        "ordinary_hours": true,
        "cost": 16.125,
        "from": 1456902000,
        "to": 1456916400
      }
    ],
    "notes": [
      {
        "body": "Goals were kicked this shift 💪",
        "author": "Mike Richards"
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Current Timesheets
GET/api/v2/timesheets/current{?show_costs,show_award_interpretation}

If you are using show_costs=true or show_award_interpretation=true, the cost scope is required.

URI Parameters
HideShow
show_costs
boolean (optional) Example: true

Whether to show the costs for the timesheet (defaults to false)

show_award_interpretation
boolean (optional) Example: true

Whether to show award interpretation for the timesheet (defaults to false)

show_notes
boolean (optional) Example: true

Whether to show notes for the timesheet (defaults to false). Note that notes can exist at the timesheet level or the shift level, and these can be found through notes arrays on the respective objects.

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified timesheets

report_location_id
number (optional) Example: 111

The ID of a location for which to filter timesheets to. If provided, only returns timesheets if the timesheet’s user’s default team (report_department_id) is set, and it is a team within this location.

export_format
string (optional) Example: myob

The format in which timesheet data should be exported. See the Exporting Timesheets section above for more information.

skip_status_update
boolean (optional) Example: true

If true, timesheets will not have their status set to exported as part of the export. Default is false. Only used if export_format is provided.

approved_only
boolean (optional) Example: true

If true, only approved timesheets will be returned. Default is false.


Timesheets on Date

GET https://my.tanda.co/api/v2/timesheets/on/2016-03-02?show_costs=true&show_award_interpretation=true
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 7007,
    "user_id": 123456,
    "start": "2016-02-29",
    "finish": "2016-03-14",
    "status": "approved",
    "shifts": [
      {
        "id": 1337,
        "timesheet_id": 7007,
        "user_id": 123456,
        "date": "2016-03-02",
        "start": 1456902118,
        "break_start": 1456908143,
        "break_finish": 1456909812,
        "break_length": 27,
        "breaks": [
          {
            "id": 42,
            "shift_id": 1337,
            "start": 1456908143,
            "finish": 1456909812,
            "length": 27,
            "paid": false,
            "selected_automatic_break_id": 73647
          }
        ],
        "finish": 1456916286,
        "status": "PENDING",
        "allowances": [
          {
            "id": 456789,
            "name": "Hazardous Environment Allowance",
            "value": 0.5,
            "cost": 1.75
          }
        ],
        "tag": "Head Technician",
        "tag_id": 65421,
        "cost": 20.1,
        "award_interpretation": [
          {
            "units": 6.45,
            "date": "2016-02-29",
            "export_name": "ORD 1x",
            "secondary_export_name": "LOAD",
            "pay_class": "P1",
            "ordinary_hours": true,
            "cost": 16.125,
            "from": 1456902000,
            "to": 1456916400
          }
        ],
        "department_id": 808,
        "metadata": "My special metadata",
        "leave_request_id": 333,
        "record_id": 532432,
        "approved_by": 123455,
        "approved_at": "1456988518",
        "notes": [
          {
            "body": "Goals were kicked this shift 💪",
            "author": "Mike Richards"
          }
        ]
      }
    ],
    "cost": 102.15,
    "award_interpretation": [
      {
        "units": 6.45,
        "date": "2016-02-29",
        "export_name": "ORD 1x",
        "secondary_export_name": "LOAD",
        "pay_class": "P1",
        "ordinary_hours": true,
        "cost": 16.125,
        "from": 1456902000,
        "to": 1456916400
      }
    ],
    "notes": [
      {
        "body": "Goals were kicked this shift 💪",
        "author": "Mike Richards"
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Timesheets on Date
GET/api/v2/timesheets/on/{date}{?show_costs,show_award_interpretation}

If you are using show_costs=true or show_award_interpretation=true, the cost scope is required.

URI Parameters
HideShow
date
date (required) Example: 2016-03-02

The date included in the timesheet to find

show_costs
boolean (optional) Example: true

Whether to show the costs for the timesheet (defaults to false)

show_award_interpretation
boolean (optional) Example: true

Whether to show award interpretation for the timesheet (defaults to false)

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified timesheets

report_location_id
number (optional) Example: 111

The ID of a location for which to filter timesheets to. If provided, only returns timesheets if the timesheet’s user’s default team (report_department_id) is set, and it is a team within this location.

export_format
string (optional) Example: myob

The format in which timesheet data should be exported. See the Exporting Timesheets section above for more information.

skip_status_update
boolean (optional) Example: true

If true, timesheets will not have their status set to exported as part of the export. Default is false. Only used if export_format is provided.

approved_only
boolean (optional) Example: true

If true, only approved timesheets will be returned. Default is false.

page
number (optional) Example: 1

The page number for your timesheet list

page_size
number (optional) Example: 50

The number of timesheets retrieved per page. The maximum is 100 timesheets per request.


Current Timesheet for User

GET https://my.tanda.co/api/v2/timesheets/for/123456/current?show_costs=true&show_award_interpretation=true
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 7007,
  "user_id": 123456,
  "start": "2016-02-29",
  "finish": "2016-03-14",
  "status": "approved",
  "shifts": [
    {
      "id": 1337,
      "timesheet_id": 7007,
      "user_id": 123456,
      "date": "2016-03-02",
      "start": 1456902118,
      "break_start": 1456908143,
      "break_finish": 1456909812,
      "break_length": 27,
      "breaks": [
        {
          "id": 42,
          "shift_id": 1337,
          "start": 1456908143,
          "finish": 1456909812,
          "length": 27,
          "paid": false,
          "selected_automatic_break_id": 73647
        }
      ],
      "finish": 1456916286,
      "status": "PENDING",
      "allowances": [
        {
          "id": 456789,
          "name": "Hazardous Environment Allowance",
          "value": 0.5,
          "cost": 1.75
        }
      ],
      "tag": "Head Technician",
      "tag_id": 65421,
      "cost": 20.1,
      "award_interpretation": [
        {
          "units": 6.45,
          "date": "2016-02-29",
          "export_name": "ORD 1x",
          "secondary_export_name": "LOAD",
          "pay_class": "P1",
          "ordinary_hours": true,
          "cost": 16.125,
          "from": 1456902000,
          "to": 1456916400
        }
      ],
      "department_id": 808,
      "metadata": "My special metadata",
      "leave_request_id": 333,
      "record_id": 532432,
      "approved_by": 123455,
      "approved_at": "1456988518",
      "notes": [
        {
          "body": "Goals were kicked this shift 💪",
          "author": "Mike Richards"
        }
      ]
    }
  ],
  "cost": 102.15,
  "award_interpretation": [
    {
      "units": 6.45,
      "date": "2016-02-29",
      "export_name": "ORD 1x",
      "secondary_export_name": "LOAD",
      "pay_class": "P1",
      "ordinary_hours": true,
      "cost": 16.125,
      "from": 1456902000,
      "to": 1456916400
    }
  ],
  "notes": [
    {
      "body": "Goals were kicked this shift 💪",
      "author": "Mike Richards"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the timesheet"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "start": {
      "type": "string",
      "description": "The start date of the timesheet"
    },
    "finish": {
      "type": "string",
      "description": "The end date of the timesheet"
    },
    "status": {
      "type": "string",
      "description": "One of `pending`, `approved`, `exported`"
    },
    "shifts": {
      "type": "array",
      "description": "The shifts on the timesheet"
    },
    "cost": {
      "type": "number",
      "description": "The total cost of the timesheet, if `show_costs=true` parameter is set"
    },
    "award_interpretation": {
      "type": "array",
      "description": "Award interpretation output, if `show_award_interpretation=true` parameter is set"
    },
    "notes": {
      "type": "array",
      "description": "Notes on the timesheet"
    }
  },
  "required": [
    "id",
    "user_id",
    "start",
    "finish",
    "status",
    "shifts"
  ]
}

Get Current Timesheet for User
GET/api/v2/timesheets/for/{user_id}/current{?show_costs,show_award_interpretation}

If you are using show_costs=true or show_award_interpretation=true, the cost scope is required.

URI Parameters
HideShow
user_id
number (required) Example: 123456

The user’s id, me can also be used to reference the current user

show_costs
boolean (optional) Example: true

Whether to show the costs for the timesheet (defaults to false)

show_award_interpretation
boolean (optional) Example: true

Whether to show award interpretation for the timesheet (defaults to false)

approved_only
boolean (optional) Example: true

If true, only approved timesheets will be returned. Default is false.


Timesheet for User on Date

GET https://my.tanda.co/api/v2/timesheets/for/123456/on/2016-03-02?show_costs=true&show_award_interpretation=true
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 7007,
  "user_id": 123456,
  "start": "2016-02-29",
  "finish": "2016-03-14",
  "status": "approved",
  "shifts": [
    {
      "id": 1337,
      "timesheet_id": 7007,
      "user_id": 123456,
      "date": "2016-03-02",
      "start": 1456902118,
      "break_start": 1456908143,
      "break_finish": 1456909812,
      "break_length": 27,
      "breaks": [
        {
          "id": 42,
          "shift_id": 1337,
          "start": 1456908143,
          "finish": 1456909812,
          "length": 27,
          "paid": false,
          "selected_automatic_break_id": 73647
        }
      ],
      "finish": 1456916286,
      "status": "PENDING",
      "allowances": [
        {
          "id": 456789,
          "name": "Hazardous Environment Allowance",
          "value": 0.5,
          "cost": 1.75
        }
      ],
      "tag": "Head Technician",
      "tag_id": 65421,
      "cost": 20.1,
      "award_interpretation": [
        {
          "units": 6.45,
          "date": "2016-02-29",
          "export_name": "ORD 1x",
          "secondary_export_name": "LOAD",
          "pay_class": "P1",
          "ordinary_hours": true,
          "cost": 16.125,
          "from": 1456902000,
          "to": 1456916400
        }
      ],
      "department_id": 808,
      "metadata": "My special metadata",
      "leave_request_id": 333,
      "record_id": 532432,
      "approved_by": 123455,
      "approved_at": "1456988518",
      "notes": [
        {
          "body": "Goals were kicked this shift 💪",
          "author": "Mike Richards"
        }
      ]
    }
  ],
  "cost": 102.15,
  "award_interpretation": [
    {
      "units": 6.45,
      "date": "2016-02-29",
      "export_name": "ORD 1x",
      "secondary_export_name": "LOAD",
      "pay_class": "P1",
      "ordinary_hours": true,
      "cost": 16.125,
      "from": 1456902000,
      "to": 1456916400
    }
  ],
  "notes": [
    {
      "body": "Goals were kicked this shift 💪",
      "author": "Mike Richards"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the timesheet"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "start": {
      "type": "string",
      "description": "The start date of the timesheet"
    },
    "finish": {
      "type": "string",
      "description": "The end date of the timesheet"
    },
    "status": {
      "type": "string",
      "description": "One of `pending`, `approved`, `exported`"
    },
    "shifts": {
      "type": "array",
      "description": "The shifts on the timesheet"
    },
    "cost": {
      "type": "number",
      "description": "The total cost of the timesheet, if `show_costs=true` parameter is set"
    },
    "award_interpretation": {
      "type": "array",
      "description": "Award interpretation output, if `show_award_interpretation=true` parameter is set"
    },
    "notes": {
      "type": "array",
      "description": "Notes on the timesheet"
    }
  },
  "required": [
    "id",
    "user_id",
    "start",
    "finish",
    "status",
    "shifts"
  ]
}

Get Timesheet for User on Date
GET/api/v2/timesheets/for/{user_id}/on/{date}{?show_costs,show_award_interpretation}

If you are using show_costs=true or show_award_interpretation=true, the cost scope is required.

URI Parameters
HideShow
user_id
number (required) Example: 123456

The user’s id, me can also be used to reference the current user

date
date (required) Example: 2016-03-02

The date included in the timesheet to find

show_costs
boolean (optional) Example: true

Whether to show the costs for the timesheet (defaults to false)

show_award_interpretation
boolean (optional) Example: true

Whether to show award interpretation for the timesheet (defaults to false)

approved_only
boolean (optional) Example: true

If true, only approved timesheets will be returned. Default is false.


Timesheet

GET https://my.tanda.co/api/v2/timesheets/7007?show_costs=true&show_award_interpretation=true
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 7007,
  "user_id": 123456,
  "start": "2016-02-29",
  "finish": "2016-03-14",
  "status": "approved",
  "shifts": [
    {
      "id": 1337,
      "timesheet_id": 7007,
      "user_id": 123456,
      "date": "2016-03-02",
      "start": 1456902118,
      "break_start": 1456908143,
      "break_finish": 1456909812,
      "break_length": 27,
      "breaks": [
        {
          "id": 42,
          "shift_id": 1337,
          "start": 1456908143,
          "finish": 1456909812,
          "length": 27,
          "paid": false,
          "selected_automatic_break_id": 73647
        }
      ],
      "finish": 1456916286,
      "status": "PENDING",
      "allowances": [
        {
          "id": 456789,
          "name": "Hazardous Environment Allowance",
          "value": 0.5,
          "cost": 1.75
        }
      ],
      "tag": "Head Technician",
      "tag_id": 65421,
      "cost": 20.1,
      "award_interpretation": [
        {
          "units": 6.45,
          "date": "2016-02-29",
          "export_name": "ORD 1x",
          "secondary_export_name": "LOAD",
          "pay_class": "P1",
          "ordinary_hours": true,
          "cost": 16.125,
          "from": 1456902000,
          "to": 1456916400
        }
      ],
      "department_id": 808,
      "metadata": "My special metadata",
      "leave_request_id": 333,
      "record_id": 532432,
      "approved_by": 123455,
      "approved_at": "1456988518",
      "notes": [
        {
          "body": "Goals were kicked this shift 💪",
          "author": "Mike Richards"
        }
      ]
    }
  ],
  "cost": 102.15,
  "award_interpretation": [
    {
      "units": 6.45,
      "date": "2016-02-29",
      "export_name": "ORD 1x",
      "secondary_export_name": "LOAD",
      "pay_class": "P1",
      "ordinary_hours": true,
      "cost": 16.125,
      "from": 1456902000,
      "to": 1456916400
    }
  ],
  "notes": [
    {
      "body": "Goals were kicked this shift 💪",
      "author": "Mike Richards"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the timesheet"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "start": {
      "type": "string",
      "description": "The start date of the timesheet"
    },
    "finish": {
      "type": "string",
      "description": "The end date of the timesheet"
    },
    "status": {
      "type": "string",
      "description": "One of `pending`, `approved`, `exported`"
    },
    "shifts": {
      "type": "array",
      "description": "The shifts on the timesheet"
    },
    "cost": {
      "type": "number",
      "description": "The total cost of the timesheet, if `show_costs=true` parameter is set"
    },
    "award_interpretation": {
      "type": "array",
      "description": "Award interpretation output, if `show_award_interpretation=true` parameter is set"
    },
    "notes": {
      "type": "array",
      "description": "Notes on the timesheet"
    }
  },
  "required": [
    "id",
    "user_id",
    "start",
    "finish",
    "status",
    "shifts"
  ]
}

Get Timesheet
GET/api/v2/timesheets/{id}{?show_costs,show_award_interpretation}

If you are using show_costs=true or show_award_interpretation=true, the cost scope is required.

URI Parameters
HideShow
id
number (required) Example: 7007

The id of the timesheet

show_costs
boolean (optional) Example: true

Whether to show the costs for the timesheet (defaults to false)

show_award_interpretation
boolean (optional) Example: true

Whether to show award interpretation for the timesheet (defaults to false)

show_notes
boolean (optional) Example: true

Whether to show notes for the timesheet (defaults to false)

approved_only
boolean (optional) Example: true

If true, only approved timesheets will be returned. Default is false.


PUT https://my.tanda.co/api/v2/timesheets/7007
RequestsUpdate Timesheet
Headers
Content-Type: application/json
Body
{
  "status": "pending"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 7007,
  "user_id": 123456,
  "start": "2016-02-29",
  "finish": "2016-03-14",
  "status": "exported",
  "shifts": [
    {
      "id": 1337,
      "timesheet_id": 7007,
      "user_id": 123456,
      "date": "2016-03-02",
      "start": 1456902118,
      "break_start": 1456908143,
      "break_finish": 1456909812,
      "break_length": 27,
      "breaks": [
        {
          "id": 42,
          "shift_id": 1337,
          "start": 1456908143,
          "finish": 1456909812,
          "length": 27,
          "paid": false,
          "selected_automatic_break_id": 73647
        }
      ],
      "finish": 1456916286,
      "status": "PENDING",
      "allowances": [
        {
          "id": 456789,
          "name": "Hazardous Environment Allowance",
          "value": 0.5,
          "cost": 1.75
        }
      ],
      "tag": "Head Technician",
      "tag_id": 65421,
      "cost": 20.1,
      "award_interpretation": [
        {
          "units": 6.45,
          "date": "2016-02-29",
          "export_name": "ORD 1x",
          "secondary_export_name": "LOAD",
          "pay_class": "P1",
          "ordinary_hours": true,
          "cost": 16.125,
          "from": 1456902000,
          "to": 1456916400
        }
      ],
      "department_id": 808,
      "metadata": "My special metadata",
      "leave_request_id": 333,
      "record_id": 532432,
      "approved_by": 123455,
      "approved_at": "1456988518",
      "notes": [
        {
          "body": "Goals were kicked this shift 💪",
          "author": "Mike Richards"
        }
      ]
    }
  ],
  "cost": 102.15,
  "award_interpretation": [
    {
      "units": 6.45,
      "date": "2016-02-29",
      "export_name": "ORD 1x",
      "secondary_export_name": "LOAD",
      "pay_class": "P1",
      "ordinary_hours": true,
      "cost": 16.125,
      "from": 1456902000,
      "to": 1456916400
    }
  ],
  "notes": [
    {
      "body": "Goals were kicked this shift 💪",
      "author": "Mike Richards"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the timesheet"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "start": {
      "type": "string",
      "description": "The start date of the timesheet"
    },
    "finish": {
      "type": "string",
      "description": "The end date of the timesheet"
    },
    "status": {
      "type": "string",
      "description": "One of `pending`, `approved`, `exported`"
    },
    "shifts": {
      "type": "array",
      "description": "The shifts on the timesheet"
    },
    "cost": {
      "type": "number",
      "description": "The total cost of the timesheet, if `show_costs=true` parameter is set"
    },
    "award_interpretation": {
      "type": "array",
      "description": "Award interpretation output, if `show_award_interpretation=true` parameter is set"
    },
    "notes": {
      "type": "array",
      "description": "Notes on the timesheet"
    }
  },
  "required": [
    "id",
    "user_id",
    "start",
    "finish",
    "status",
    "shifts"
  ]
}

Update Timesheet
PUT/api/v2/timesheets/{id}

Use this endpoint to change a timesheet’s status. Three values are accepted: pending, approved, or exported.

If a timesheet is exported it cannot be edited and its costs are locked. If you are exporting data out of timesheets through the API to be costed externally, you should mark those timesheets as exported at that time.

URI Parameters
HideShow
id
number (required) Example: 7007

The id of the timesheet


Shifts

Shifts represent actual times worked for a user and are contained in a Timesheet. For rostered times, please see Rosters or Schedules.

A user can see all the shifts on each timesheet that they can see. Shifts can be created, updated and deleted by staff if they have the ability to see their own timesheets (a system setting). All shifts can be created, updated and deleted by roster managers and admins, and department managers can create, update and delete shifts for staff that they manage.

Shifts

GET https://my.tanda.co/api/v2/shifts?ids=1,2,1337&user_ids=1,2,123456&from=2016-03-02&to=2016-03-02&show_costs=true&show_award_interpretation=true&report_location_id=111&platform=false
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 1337,
    "timesheet_id": 7007,
    "user_id": 123456,
    "date": "2016-03-02",
    "start": 1456902118,
    "break_start": 1456908143,
    "break_finish": 1456909812,
    "break_length": 27,
    "breaks": [
      {
        "id": 42,
        "shift_id": 1337,
        "start": 1456908143,
        "finish": 1456909812,
        "length": 27,
        "paid": false,
        "selected_automatic_break_id": 73647
      }
    ],
    "finish": 1456916286,
    "status": "PENDING",
    "allowances": [
      {
        "id": 456789,
        "name": "Hazardous Environment Allowance",
        "value": 0.5,
        "cost": 1.75
      }
    ],
    "tag": "Head Technician",
    "tag_id": 65421,
    "cost": 20.1,
    "award_interpretation": [
      {
        "units": 6.45,
        "date": "2016-02-29",
        "export_name": "ORD 1x",
        "secondary_export_name": "LOAD",
        "pay_class": "P1",
        "ordinary_hours": true,
        "cost": 16.125,
        "from": 1456902000,
        "to": 1456916400
      }
    ],
    "department_id": 808,
    "metadata": "My special metadata",
    "leave_request_id": 333,
    "record_id": 532432,
    "approved_by": 123455,
    "approved_at": "1456988518",
    "notes": [
      {
        "body": "Goals were kicked this shift 💪",
        "author": "Mike Richards"
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Shifts
GET/api/v2/shifts{?ids,user_ids,from,to,show_costs,show_award_interpretation,report_location_id,platform}

Get multiple shifts by IDs, user IDs, or from/to dates. You need to provide at least one of these parameters (ids, user_ids, or from + to). If you provide more than one, or any of the other parameters below, only shifts that meet all criteria will be returned.

This method requires the timesheet scope (see Scopes for more information).

If you are using show_costs=true or show_award_interpretation=true, the cost scope is also required.

URI Parameters
HideShow
ids
string (optional) Example: 1,2,1337

Comma separated list of shift IDs

user_ids
string (optional) Example: 1,2,123456

Comma separated list of user IDs

from
string (optional) Example: 2016-03-02

From date to lookup shifts in

to
string (optional) Example: 2016-03-02

To date to lookup shifts in

show_costs
boolean (optional) Example: true

Whether to show the costs for the shift (defaults to false)

show_award_interpretation
boolean (optional) Example: true

Whether to show award interpretation for the shifts (defaults to false)

show_associated_tag
boolean (optional) Example: true

Whether to show the associated tag for the shifts (defaults to false)

show_notes
boolean (optional) Example: true

Whether to show notes for the shifts (defaults to false)

report_location_id
number (optional) Example: 111

The ID of a location for which to filter shifts to. If provided, only returns shifts if the shifts’s user’s default team (report_department_id) is set, and it is a team within this location. Note that it is possible for a shift’s user’s default location to be different to the location at which a shift was worked. This parameter always filters based on the user. For example if a user can work at locations A and B, they default to A, but work at B, a call with report_location_id=A will return that user’s shifts worked at location B.

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false).

page
number (optional) Example: 1

The page number for your shifts list

page_size
number (optional) Example: 50

The number of shifts retrieved per page. The maximum is 100 shifts per request.

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified shifts


POST https://my.tanda.co/api/v2/shifts
RequestsCreate ShiftCreate Shift with breaksCreate approved ShiftCreate Shift with Allowances
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "date": "2016-03-12",
  "start": 1457741040,
  "finish": 1457762640,
  "department_id": 808,
  "metadata": "My special metadata"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 9665,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-12",
  "start": 1457741040,
  "break_start": null,
  "break_finish": null,
  "break_length": null,
  "finish": 1457762640,
  "status": "PENDING",
  "allowances": [],
  "tag": null,
  "tag_id": null,
  "department_id": 808,
  "department_export_name": "abc123",
  "metadata": "My special metadata",
  "leave_request_id": null
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift"
    },
    "timesheet_id": {
      "type": "number",
      "description": "The id of the timesheet that the shift belongs on"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "date": {
      "type": "string",
      "description": "The date the shift was worked"
    },
    "start": {
      "type": "number",
      "description": "The start of the shift"
    },
    "break_start": {
      "type": "number",
      "description": "The start of the break"
    },
    "break_finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "break_length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_finish - break_start) / 60`, see Shifts section)"
    },
    "finish": {
      "type": "number",
      "description": "The end of the shift"
    },
    "status": {
      "type": "string",
      "description": "One of `PENDING`, `APPROVED`"
    },
    "allowances": {
      "type": "array",
      "description": "The allowances that apply to the shift"
    },
    "tag": {
      "type": "string",
      "description": "The name of the tag on the shift  (can use `tag_id` instead)"
    },
    "tag_id": {
      "type": "number",
      "description": "The id of the tag on the shift (can use `tag` instead)"
    },
    "department_id": {
      "type": "number",
      "description": "The ID for the team this shift was worked in"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "timesheet_id",
    "user_id",
    "date",
    "status",
    "allowances"
  ]
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "date": "2016-03-12",
  "start": 1457741040,
  "finish": 1457762640,
  "break_start": 1457751660,
  "break_finish": 1457753280,
  "metadata": "My special metadata"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 9665,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-12",
  "start": 1457741040,
  "break_start": 1457751660,
  "break_finish": 1457753280,
  "break_length": 27,
  "finish": 1457762640,
  "status": "PENDING",
  "allowances": [],
  "tag": "Head Technician",
  "tag_id": 65421,
  "department_id": 808,
  "record_id": 532432,
  "metadata": "My special metadata"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift"
    },
    "timesheet_id": {
      "type": "number",
      "description": "The id of the timesheet that the shift belongs on"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "date": {
      "type": "string",
      "description": "The date the shift was worked"
    },
    "start": {
      "type": "number",
      "description": "The start of the shift"
    },
    "break_start": {
      "type": "number",
      "description": "The start of the break"
    },
    "break_finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "break_length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_finish - break_start) / 60`, see Shifts section)"
    },
    "finish": {
      "type": "number",
      "description": "The end of the shift"
    },
    "status": {
      "type": "string",
      "description": "One of `PENDING`, `APPROVED`"
    },
    "allowances": {
      "description": "The allowances that apply to the shift"
    },
    "tag": {
      "type": "string",
      "description": "The name of the tag on the shift  (can use `tag_id` instead)"
    },
    "tag_id": {
      "type": "number",
      "description": "The id of the tag on the shift (can use `tag` instead)"
    },
    "department_id": {
      "type": "number",
      "description": "The ID for the team this shift was worked in"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "metadata": {
      "type": "string"
    }
  },
  "required": [
    "id",
    "timesheet_id",
    "user_id",
    "date",
    "status",
    "allowances"
  ]
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "date": "2016-03-12",
  "start": 1457741040,
  "finish": 1457762640,
  "status": "APPROVED",
  "tag": null
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 9665,
  "timesheet_id": 7007,
  "user_id": 123456,
  "start": 1457741040,
  "break_start": null,
  "break_finish": null,
  "break_length": null,
  "finish": 1457762640,
  "status": "APPROVED",
  "allowances": [],
  "tag": null,
  "tag_id": null,
  "metadata": null,
  "leave_request_id": null
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift"
    },
    "timesheet_id": {
      "type": "number",
      "description": "The id of the timesheet that the shift belongs on"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "date": {
      "type": "string",
      "description": "The date the shift was worked"
    },
    "start": {
      "type": "number",
      "description": "The start of the shift"
    },
    "break_start": {
      "type": "number",
      "description": "The start of the break"
    },
    "break_finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "break_length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_finish - break_start) / 60`, see Shifts section)"
    },
    "finish": {
      "type": "number",
      "description": "The end of the shift"
    },
    "status": {
      "type": "string",
      "description": "One of `PENDING`, `APPROVED`"
    },
    "allowances": {
      "type": "array",
      "description": "The allowances that apply to the shift"
    },
    "tag": {
      "type": "string",
      "description": "The name of the tag on the shift  (can use `tag_id` instead)"
    },
    "tag_id": {
      "type": "number",
      "description": "The id of the tag on the shift (can use `tag` instead)"
    },
    "department_id": {
      "type": "number",
      "description": "The ID for the team this shift was worked in"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "timesheet_id",
    "user_id",
    "date",
    "status",
    "allowances"
  ]
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "date": "2016-03-12",
  "start": 1457741040,
  "finish": 1457762640,
  "allowances": [
    {
      "id": 987654,
      "value": 1
    }
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 9665,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-12",
  "start": 1457741040,
  "break_start": null,
  "break_finish": null,
  "break_length": null,
  "finish": 1457762640,
  "status": "PENDING",
  "allowances": [
    {
      "id": 987654,
      "value": 1
    }
  ],
  "tag": null,
  "tag_id": null,
  "metadata": null,
  "leave_request_id": null
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift"
    },
    "timesheet_id": {
      "type": "number",
      "description": "The id of the timesheet that the shift belongs on"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "date": {
      "type": "string",
      "description": "The date the shift was worked"
    },
    "start": {
      "type": "number",
      "description": "The start of the shift"
    },
    "break_start": {
      "type": "number",
      "description": "The start of the break"
    },
    "break_finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "break_length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_finish - break_start) / 60`, see Shifts section)"
    },
    "finish": {
      "type": "number",
      "description": "The end of the shift"
    },
    "status": {
      "type": "string",
      "description": "One of `PENDING`, `APPROVED`"
    },
    "allowances": {
      "type": "array",
      "description": "The allowances that apply to the shift"
    },
    "tag": {
      "type": "string",
      "description": "The name of the tag on the shift  (can use `tag_id` instead)"
    },
    "tag_id": {
      "type": "number",
      "description": "The id of the tag on the shift (can use `tag` instead)"
    },
    "department_id": {
      "type": "number",
      "description": "The ID for the team this shift was worked in"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "timesheet_id",
    "user_id",
    "date",
    "status",
    "allowances"
  ]
}

Create Shift
POST/api/v2/shifts

Create a shift for a user, with specified times, on a specified date.

This will create a timesheet for the user for the given pay period, if one doesn’t exist already. The shift object that is returned will have both an id (to use for Shift lookups) and a timesheet_id (for Timesheet lookups).

When a shift is created, the times provided for the start, finish, break_start, and break_finish keys will be rounded to the nearest minute. To avoid potentially confusing, you can round them before passing them to the API.

This method requires the timesheet scope (see Scopes for more information).


Shift

GET https://my.tanda.co/api/v2/shifts/1337?show_costs=true&show_award_interpretation=true&platform=false
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1337,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-02",
  "start": 1456902118,
  "break_start": 1456908143,
  "break_finish": 1456909812,
  "break_length": 27,
  "breaks": [
    {
      "id": 42,
      "shift_id": 1337,
      "start": 1456908143,
      "finish": 1456909812,
      "length": 27,
      "paid": false,
      "selected_automatic_break_id": 73647
    }
  ],
  "finish": 1456916286,
  "status": "PENDING",
  "allowances": [
    {
      "id": 456789,
      "name": "Hazardous Environment Allowance",
      "value": 0.5,
      "cost": 1.75
    }
  ],
  "tag": "Head Technician",
  "tag_id": 65421,
  "cost": 20.1,
  "award_interpretation": [
    {
      "units": 6.45,
      "date": "2016-02-29",
      "export_name": "ORD 1x",
      "secondary_export_name": "LOAD",
      "pay_class": "P1",
      "ordinary_hours": true,
      "cost": 16.125,
      "from": 1456902000,
      "to": 1456916400
    }
  ],
  "department_id": 808,
  "metadata": "My special metadata",
  "leave_request_id": 333,
  "record_id": 532432,
  "approved_by": 123455,
  "approved_at": "1456988518",
  "notes": [
    {
      "body": "Goals were kicked this shift 💪",
      "author": "Mike Richards"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift"
    },
    "timesheet_id": {
      "type": "number",
      "description": "The id of the timesheet that the shift belongs on"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "date": {
      "type": "string",
      "description": "The date the shift was worked"
    },
    "start": {
      "type": "number",
      "description": "The start of the shift"
    },
    "break_start": {
      "type": "number",
      "description": "The start of the break"
    },
    "break_finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "break_length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_start - break_finish) / 60`, see Shifts section)"
    },
    "breaks": {
      "type": "array",
      "description": "The shift's breaks"
    },
    "finish": {
      "type": "number",
      "description": "The end of the shift"
    },
    "status": {
      "type": "string",
      "description": "One of `PENDING`, `APPROVED`"
    },
    "allowances": {
      "type": "array",
      "description": "The allowances that apply to the shift"
    },
    "tag": {
      "type": "string",
      "description": "The name of the tag on the shift (can use `tag_id` instead)"
    },
    "tag_id": {
      "type": "number",
      "description": "The id of the tag on the shift (can use `tag` instead)"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the shift, if `show_costs=true` parameter is set"
    },
    "award_interpretation": {
      "type": "array",
      "description": "Award interpretation output, if `show_award_interpretation=true` parameter is set"
    },
    "department_id": {
      "type": "number",
      "description": "The ID for the team this shift was worked in"
    },
    "metadata": {
      "type": "string",
      "description": "Custom string field that holds up to 500 characters"
    },
    "leave_request_id": {
      "type": "number",
      "description": "The ID for the leave request, if leave was taken, otherwise null."
    },
    "record_id": {
      "type": "number",
      "description": "The record ID, for use with Platform endpoints"
    },
    "approved_by": {
      "type": "number",
      "description": "The ID of the user that approved the shift"
    },
    "approved_at": {
      "type": "string",
      "description": "The time the shift was approved"
    },
    "notes": {
      "type": "array",
      "description": "Notes on the shift"
    }
  },
  "required": [
    "id",
    "timesheet_id",
    "user_id",
    "date",
    "status",
    "allowances"
  ]
}

Get Shift
GET/api/v2/shifts/{id}{?show_costs,show_award_interpretation,platform}

Get a shift by id.

This method requires the timesheet scope (see Scopes for more information).

If you are using show_costs=true or show_award_interpretation=true, the cost scope is also required.

URI Parameters
HideShow
id
number (required) Example: 1337

The id of the shift

show_costs
boolean (optional) Example: true

Whether to show the costs for the shift (defaults to false)

show_award_interpretation
boolean (optional) Example: true

Whether to show award interpretation for the shift (defaults to false)

show_associated_tag
boolean (optional) Example: true

Whether to show the associated tag for the shifts (defaults to false)

show_notes
boolean (optional) Example: true

Whether to show notes for the shift (defaults to false)

show_export_name
boolean (optional) Example: true

Whether to show the department’s export code that the employee worked on the shift (defaults to false)

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false).


PUT https://my.tanda.co/api/v2/shifts/1337
RequestsApprove ShiftUpdate Shift timesUpdate Shift times on new dateUpdate Shift allowances
Headers
Content-Type: application/json
Body
{
  "status": "APPROVED"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1337,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-02",
  "start": 1456902118,
  "break_start": 1456908143,
  "break_finish": 1456909812,
  "break_length": 27,
  "breaks": [
    {
      "id": 42,
      "shift_id": 1337,
      "start": 1456908143,
      "finish": 1456909812,
      "length": 27,
      "paid": false,
      "selected_automatic_break_id": 73647
    }
  ],
  "finish": 1456916286,
  "status": "APPROVED",
  "allowances": [
    {
      "id": 456789,
      "name": "Hazardous Environment Allowance",
      "value": 0.5,
      "cost": 1.75
    }
  ],
  "tag": "Head Technician",
  "tag_id": 65421,
  "cost": 20.1,
  "award_interpretation": [
    {
      "units": 6.45,
      "date": "2016-02-29",
      "export_name": "ORD 1x",
      "secondary_export_name": "LOAD",
      "pay_class": "P1",
      "ordinary_hours": true,
      "cost": 16.125,
      "from": 1456902000,
      "to": 1456916400
    }
  ],
  "department_id": 808,
  "metadata": "My special metadata",
  "leave_request_id": 333,
  "record_id": 532432,
  "approved_by": 123455,
  "approved_at": "1456988518",
  "notes": [
    {
      "body": "Goals were kicked this shift 💪",
      "author": "Mike Richards"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift"
    },
    "timesheet_id": {
      "type": "number",
      "description": "The id of the timesheet that the shift belongs on"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "date": {
      "type": "string",
      "description": "The date the shift was worked"
    },
    "start": {
      "type": "number",
      "description": "The start of the shift"
    },
    "break_start": {
      "type": "number",
      "description": "The start of the break"
    },
    "break_finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "break_length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_start - break_finish) / 60`, see Shifts section)"
    },
    "breaks": {
      "type": "array",
      "description": "The shift's breaks"
    },
    "finish": {
      "type": "number",
      "description": "The end of the shift"
    },
    "status": {
      "type": "string",
      "description": "One of `PENDING`, `APPROVED`"
    },
    "allowances": {
      "type": "array",
      "description": "The allowances that apply to the shift"
    },
    "tag": {
      "type": "string",
      "description": "The name of the tag on the shift (can use `tag_id` instead)"
    },
    "tag_id": {
      "type": "number",
      "description": "The id of the tag on the shift (can use `tag` instead)"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the shift, if `show_costs=true` parameter is set"
    },
    "award_interpretation": {
      "type": "array",
      "description": "Award interpretation output, if `show_award_interpretation=true` parameter is set"
    },
    "department_id": {
      "type": "number",
      "description": "The ID for the team this shift was worked in"
    },
    "metadata": {
      "type": "string",
      "description": "Custom string field that holds up to 500 characters"
    },
    "leave_request_id": {
      "type": "number",
      "description": "The ID for the leave request, if leave was taken, otherwise null."
    },
    "record_id": {
      "type": "number",
      "description": "The record ID, for use with Platform endpoints"
    },
    "approved_by": {
      "type": "number",
      "description": "The ID of the user that approved the shift"
    },
    "approved_at": {
      "type": "string",
      "description": "The time the shift was approved"
    },
    "notes": {
      "type": "array",
      "description": "Notes on the shift"
    }
  },
  "required": [
    "id",
    "timesheet_id",
    "user_id",
    "date",
    "status",
    "allowances"
  ]
}
Headers
Content-Type: application/json
Body
{
  "start": 1456901518,
  "finish": 1456916886
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1337,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-02",
  "start": 1456901518,
  "break_start": 1456908143,
  "break_finish": 1456909812,
  "break_length": 27,
  "breaks": [
    {
      "id": 42,
      "shift_id": 1337,
      "start": 1456908143,
      "finish": 1456909812,
      "length": 27,
      "paid": false,
      "selected_automatic_break_id": 73647
    }
  ],
  "finish": 1456916886,
  "status": "PENDING",
  "allowances": [
    {
      "id": 456789,
      "name": "Hazardous Environment Allowance",
      "value": 0.5,
      "cost": 1.75
    }
  ],
  "tag": "Head Technician",
  "tag_id": 65421,
  "cost": 20.1,
  "award_interpretation": [
    {
      "units": 6.45,
      "date": "2016-02-29",
      "export_name": "ORD 1x",
      "secondary_export_name": "LOAD",
      "pay_class": "P1",
      "ordinary_hours": true,
      "cost": 16.125,
      "from": 1456902000,
      "to": 1456916400
    }
  ],
  "department_id": 808,
  "metadata": "My special metadata",
  "leave_request_id": 333,
  "record_id": 532432,
  "approved_by": 123455,
  "approved_at": "1456988518",
  "notes": [
    {
      "body": "Goals were kicked this shift 💪",
      "author": "Mike Richards"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift"
    },
    "timesheet_id": {
      "type": "number",
      "description": "The id of the timesheet that the shift belongs on"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "date": {
      "type": "string",
      "description": "The date the shift was worked"
    },
    "start": {
      "type": "number",
      "description": "The start of the shift"
    },
    "break_start": {
      "type": "number",
      "description": "The start of the break"
    },
    "break_finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "break_length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_start - break_finish) / 60`, see Shifts section)"
    },
    "breaks": {
      "type": "array",
      "description": "The shift's breaks"
    },
    "finish": {
      "type": "number",
      "description": "The end of the shift"
    },
    "status": {
      "type": "string",
      "description": "One of `PENDING`, `APPROVED`"
    },
    "allowances": {
      "type": "array",
      "description": "The allowances that apply to the shift"
    },
    "tag": {
      "type": "string",
      "description": "The name of the tag on the shift (can use `tag_id` instead)"
    },
    "tag_id": {
      "type": "number",
      "description": "The id of the tag on the shift (can use `tag` instead)"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the shift, if `show_costs=true` parameter is set"
    },
    "award_interpretation": {
      "type": "array",
      "description": "Award interpretation output, if `show_award_interpretation=true` parameter is set"
    },
    "department_id": {
      "type": "number",
      "description": "The ID for the team this shift was worked in"
    },
    "metadata": {
      "type": "string",
      "description": "Custom string field that holds up to 500 characters"
    },
    "leave_request_id": {
      "type": "number",
      "description": "The ID for the leave request, if leave was taken, otherwise null."
    },
    "record_id": {
      "type": "number",
      "description": "The record ID, for use with Platform endpoints"
    },
    "approved_by": {
      "type": "number",
      "description": "The ID of the user that approved the shift"
    },
    "approved_at": {
      "type": "string",
      "description": "The time the shift was approved"
    },
    "notes": {
      "type": "array",
      "description": "Notes on the shift"
    }
  },
  "required": [
    "id",
    "timesheet_id",
    "user_id",
    "date",
    "status",
    "allowances"
  ]
}
Headers
Content-Type: application/json
Body
{
  "date": "2016-03-03",
  "start": 1456987918,
  "finish": 1457003286,
  "break_start": 1456994543,
  "break_finish": 1456996212
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1337,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-03",
  "start": 1456987918,
  "break_start": 1456994543,
  "break_finish": 1456996212,
  "break_length": 27,
  "breaks": [
    {
      "id": 42,
      "shift_id": 1337,
      "start": 1456908143,
      "finish": 1456909812,
      "length": 27,
      "paid": false,
      "selected_automatic_break_id": 73647
    }
  ],
  "finish": 1457003286,
  "status": "PENDING",
  "allowances": [
    {
      "id": 456789,
      "name": "Hazardous Environment Allowance",
      "value": 0.5,
      "cost": 1.75
    }
  ],
  "tag": "Head Technician",
  "tag_id": 65421,
  "cost": 20.1,
  "award_interpretation": [
    {
      "units": 6.45,
      "date": "2016-02-29",
      "export_name": "ORD 1x",
      "secondary_export_name": "LOAD",
      "pay_class": "P1",
      "ordinary_hours": true,
      "cost": 16.125,
      "from": 1456902000,
      "to": 1456916400
    }
  ],
  "department_id": 808,
  "metadata": "My special metadata",
  "leave_request_id": 333,
  "record_id": 532432,
  "approved_by": 123455,
  "approved_at": "1456988518",
  "notes": [
    {
      "body": "Goals were kicked this shift 💪",
      "author": "Mike Richards"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift"
    },
    "timesheet_id": {
      "type": "number",
      "description": "The id of the timesheet that the shift belongs on"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "date": {
      "type": "string",
      "description": "The date the shift was worked"
    },
    "start": {
      "type": "number",
      "description": "The start of the shift"
    },
    "break_start": {
      "type": "number",
      "description": "The start of the break"
    },
    "break_finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "break_length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_start - break_finish) / 60`, see Shifts section)"
    },
    "breaks": {
      "type": "array",
      "description": "The shift's breaks"
    },
    "finish": {
      "type": "number",
      "description": "The end of the shift"
    },
    "status": {
      "type": "string",
      "description": "One of `PENDING`, `APPROVED`"
    },
    "allowances": {
      "type": "array",
      "description": "The allowances that apply to the shift"
    },
    "tag": {
      "type": "string",
      "description": "The name of the tag on the shift (can use `tag_id` instead)"
    },
    "tag_id": {
      "type": "number",
      "description": "The id of the tag on the shift (can use `tag` instead)"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the shift, if `show_costs=true` parameter is set"
    },
    "award_interpretation": {
      "type": "array",
      "description": "Award interpretation output, if `show_award_interpretation=true` parameter is set"
    },
    "department_id": {
      "type": "number",
      "description": "The ID for the team this shift was worked in"
    },
    "metadata": {
      "type": "string",
      "description": "Custom string field that holds up to 500 characters"
    },
    "leave_request_id": {
      "type": "number",
      "description": "The ID for the leave request, if leave was taken, otherwise null."
    },
    "record_id": {
      "type": "number",
      "description": "The record ID, for use with Platform endpoints"
    },
    "approved_by": {
      "type": "number",
      "description": "The ID of the user that approved the shift"
    },
    "approved_at": {
      "type": "string",
      "description": "The time the shift was approved"
    },
    "notes": {
      "type": "array",
      "description": "Notes on the shift"
    }
  },
  "required": [
    "id",
    "timesheet_id",
    "user_id",
    "date",
    "status",
    "allowances"
  ]
}
Headers
Content-Type: application/json
Body
{
  "allowances": [
    {
      "id": 987654,
      "value": 1
    }
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1337,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-02",
  "start": 1456902118,
  "break_start": 1456908143,
  "break_finish": 1456909812,
  "break_length": 27,
  "breaks": [
    {
      "id": 42,
      "shift_id": 1337,
      "start": 1456908143,
      "finish": 1456909812,
      "length": 27,
      "paid": false,
      "selected_automatic_break_id": 73647
    }
  ],
  "finish": 1456916286,
  "status": "PENDING",
  "allowances": [
    {
      "id": 987654,
      "value": 1
    },
    {
      "id": 456789,
      "value": 0.5,
      "cost": 1.75
    }
  ],
  "tag": "Head Technician",
  "tag_id": 65421,
  "cost": 20.1,
  "award_interpretation": [
    {
      "units": 6.45,
      "date": "2016-02-29",
      "export_name": "ORD 1x",
      "secondary_export_name": "LOAD",
      "pay_class": "P1",
      "ordinary_hours": true,
      "cost": 16.125,
      "from": 1456902000,
      "to": 1456916400
    }
  ],
  "department_id": 808,
  "metadata": "My special metadata",
  "leave_request_id": 333,
  "record_id": 532432,
  "approved_by": 123455,
  "approved_at": "1456988518",
  "notes": [
    {
      "body": "Goals were kicked this shift 💪",
      "author": "Mike Richards"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift"
    },
    "timesheet_id": {
      "type": "number",
      "description": "The id of the timesheet that the shift belongs on"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who worked the shift"
    },
    "date": {
      "type": "string",
      "description": "The date the shift was worked"
    },
    "start": {
      "type": "number",
      "description": "The start of the shift"
    },
    "break_start": {
      "type": "number",
      "description": "The start of the break"
    },
    "break_finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "break_length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_start - break_finish) / 60`, see Shifts section)"
    },
    "breaks": {
      "type": "array",
      "description": "The shift's breaks"
    },
    "finish": {
      "type": "number",
      "description": "The end of the shift"
    },
    "status": {
      "type": "string",
      "description": "One of `PENDING`, `APPROVED`"
    },
    "allowances": {
      "type": "array",
      "description": "The allowances that apply to the shift"
    },
    "tag": {
      "type": "string",
      "description": "The name of the tag on the shift (can use `tag_id` instead)"
    },
    "tag_id": {
      "type": "number",
      "description": "The id of the tag on the shift (can use `tag` instead)"
    },
    "cost": {
      "type": "number",
      "description": "The cost of the shift, if `show_costs=true` parameter is set"
    },
    "award_interpretation": {
      "type": "array",
      "description": "Award interpretation output, if `show_award_interpretation=true` parameter is set"
    },
    "department_id": {
      "type": "number",
      "description": "The ID for the team this shift was worked in"
    },
    "metadata": {
      "type": "string",
      "description": "Custom string field that holds up to 500 characters"
    },
    "leave_request_id": {
      "type": "number",
      "description": "The ID for the leave request, if leave was taken, otherwise null."
    },
    "record_id": {
      "type": "number",
      "description": "The record ID, for use with Platform endpoints"
    },
    "approved_by": {
      "type": "number",
      "description": "The ID of the user that approved the shift"
    },
    "approved_at": {
      "type": "string",
      "description": "The time the shift was approved"
    },
    "notes": {
      "type": "array",
      "description": "Notes on the shift"
    }
  },
  "required": [
    "id",
    "timesheet_id",
    "user_id",
    "date",
    "status",
    "allowances"
  ]
}

Update Shift
PUT/api/v2/shifts/{id}

When a shift is updated, the times provided for the start and finish keys will be rounded to the nearest minute. To avoid potentially confusing, you can round them before passing them to the API.

After the parent timesheet to which a shift is attached has been exported, you can no longer update the shift.

This method requires the timesheet scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 1337

The id of the shift


DELETE https://my.tanda.co/api/v2/shifts/1337
Responses200
Headers
Content-Type: application/json

Delete Shift
DELETE/api/v2/shifts/{id}

This method requires the timesheet scope (see Scopes for more information).

Shifts can’t be deleted if their timesheet has already been exported.

URI Parameters
HideShow
id
number (required) Example: 1337

The id of the shift


Active Status

GET https://my.tanda.co/api/v2/shifts/active
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "user_id": 123456,
    "shift_id": 1337,
    "status": "clocked_in"
  },
  {
    "user_id": 123457,
    "shift_id": 1338,
    "status": "on_break"
  }
]

Get Active Shifts
GET/api/v2/shifts/active

Gets a list of shifts that are taking place now. For each shift, returns the user ID, the shift ID, and the shift’s current status, which could be either clocked_in or on_break. Shifts are returned if they have a start time and no finish time.

This method requires the timesheet scopes (see Scopes for more information).


Shift's Applicable Allowances

GET https://my.tanda.co/api/v2/shifts/1337/applicable_allowances
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 456789,
    "name": "Hazardous Environment Allowance",
    "export_name": "HE Allowance",
    "current_value": 0.5
  },
  {
    "id": 987654,
    "name": "Meal Allowance"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Shift's Applicable Allowances
GET/api/v2/shifts/{id}/applicable_allowances

Our user guide has more information on working with allowances through the API.

Get list of manually applied allowances that can apply to a shift, along with the current amount currently applied to the given shift.

The allowance IDs returned will be the same for all shifts within the organisation, but the values may differ from shift to shift.

Allowances that are configured to apply automatically will not be returned by this endpoint. They will update automatically every time a shift is saved.

This method requires the timesheet scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 1337

The id of the shift


Shift Versions

GET https://my.tanda.co/api/v2/shifts/1337/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"Shift\"",
    "changes": [
      {
        "field": "finish",
        "previous": 1456916286,
        "updated": 1456916300
      },
      {
        "field": "status",
        "previous": "PENDING",
        "updated": "APPROVED"
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Shift Versions
GET/api/v2/shifts/{id}/versions

This method requires the timesheet scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 1337

The id of the shift

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified shift versions


Shift Breaks

Shift breaks represent a break in a Shift. A shift can have many breaks.

Shift breaks inherit access permissions from their parent shift.

All shift break actions require the timesheet scope (see Scopes for more information).

GET https://my.tanda.co/api/v2/shifts/1337/breaks
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 42,
    "shift_id": 1337,
    "start": 1456908143,
    "finish": 1456909812,
    "length": 27,
    "paid": false,
    "selected_automatic_break_id": 73647
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Shift's Breaks
GET/api/v2/shifts/{shift_id}/breaks

URI Parameters
HideShow
shift_id
number (required) Example: 1337

The id of the shift


POST https://my.tanda.co/api/v2/shifts/1337/breaks
RequestsCreate with timesCreate with lengthCreate with paid
Headers
Content-Type: application/json
Body
{
  "start": 1456908143,
  "finish": 1456909812,
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 42,
  "shift_id": 1337,
  "start": 1456908143,
  "finish": 1456909812,
  "length": 27,
  "paid": false,
  "selected_automatic_break_id": 73647
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the break"
    },
    "shift_id": {
      "type": "number",
      "description": "The id of the break's shift"
    },
    "start": {
      "type": "number",
      "description": "The start of the break"
    },
    "finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_start - break_finish) / 60`, see Shifts section)"
    },
    "paid": {
      "type": "boolean",
      "description": "Whether the break is a paid break"
    },
    "selected_automatic_break_id": {
      "type": "number",
      "description": "The id of the automatic break rule chosen to correspond to this shift break by the employee when they clocked in"
    }
  },
  "required": [
    "id",
    "shift_id"
  ]
}
Headers
Content-Type: application/json
Body
{
  "length": 45,
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 42,
  "shift_id": 1337,
  "start": null,
  "finish": null,
  "length": 45,
  "paid": false,
}
Headers
Content-Type: application/json
Body
{
  "paid": true,
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 42,
  "shift_id": 1337,
  "start": null,
  "finish": null,
  "length": 45,
  "paid": true,
}

Create Shift Break
POST/api/v2/shifts/{shift_id}/breaks

URI Parameters
HideShow
shift_id
number (required) Example: 1337

The id of the shift


Shift Break

Shift breaks represent a break in a Shift. A shift can have many breaks.

Shift breaks inherit access permissions from their parent shift.

All shift break actions require the timesheet scope (see Scopes for more information).

GET https://my.tanda.co/api/v2/shifts/1337/breaks/42
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 42,
  "shift_id": 1337,
  "start": 1456908143,
  "finish": 1456909812,
  "length": 27,
  "paid": false,
  "selected_automatic_break_id": 73647
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the break"
    },
    "shift_id": {
      "type": "number",
      "description": "The id of the break's shift"
    },
    "start": {
      "type": "number",
      "description": "The start of the break"
    },
    "finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_start - break_finish) / 60`, see Shifts section)"
    },
    "paid": {
      "type": "boolean",
      "description": "Whether the break is a paid break"
    },
    "selected_automatic_break_id": {
      "type": "number",
      "description": "The id of the automatic break rule chosen to correspond to this shift break by the employee when they clocked in"
    }
  },
  "required": [
    "id",
    "shift_id"
  ]
}

Get Shift Break
GET/api/v2/shifts/{shift_id}/breaks/{break_id}

URI Parameters
HideShow
shift_id
number (required) Example: 1337

The id of the shift

break_id
number (required) Example: 42

The id of the break


PUT https://my.tanda.co/api/v2/shifts/1337/breaks/42
Requestsupdate shift break
Headers
Content-Type: application/json
Body
{
  "start": 1456908143
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 42,
  "shift_id": 1337,
  "start": 1456908143,
  "finish": 1456909812,
  "length": 27,
  "paid": false,
  "selected_automatic_break_id": 73647
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the break"
    },
    "shift_id": {
      "type": "number",
      "description": "The id of the break's shift"
    },
    "start": {
      "type": "number",
      "description": "The start of the break"
    },
    "finish": {
      "type": "number",
      "description": "The end of the break"
    },
    "length": {
      "type": "number",
      "description": "The length of the break in minutes (NOTE: this can be different to `(break_start - break_finish) / 60`, see Shifts section)"
    },
    "paid": {
      "type": "boolean",
      "description": "Whether the break is a paid break"
    },
    "selected_automatic_break_id": {
      "type": "number",
      "description": "The id of the automatic break rule chosen to correspond to this shift break by the employee when they clocked in"
    }
  },
  "required": [
    "id",
    "shift_id"
  ]
}

Update Shift Break
PUT/api/v2/shifts/{shift_id}/breaks/{break_id}

When a break is updated, the times provided for the start and finish keys will be rounded to the nearest minute. To avoid potentially confusing, you can round them before passing them to the API.

URI Parameters
HideShow
shift_id
number (required) Example: 1337

The id of the shift

break_id
number (required) Example: 42

The id of the break


Shift Break Versions

GET https://my.tanda.co/api/v2/shifts/breaks/42/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"ShiftBreak\"",
    "changes": [
      {
        "field": "break_finish",
        "previous": 1456916286,
        "updated": 1456916300
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Shift Break Versions
GET/api/v2/shifts/breaks/{break_id}/versions

This method requires the timesheet scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 1337

The id of the shift

break_id
number (required) Example: 42

The id of the break

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified shift break versions


Shift Limits

GET https://my.tanda.co/api/v2/shifts/limits?user_ids=123456,987654
Responses200
Body
[
  {
    "id": 1337,
    "timesheet_id": 7007,
    "user_id": 123456,
    "date": "2016-03-02",
    "start": 1456902118,
    "break_start": 1456908143,
    "break_finish": 1456909812,
    "break_length": 27,
    "breaks": [
      {
        "id": 42,
        "shift_id": 1337,
        "start": 1456908143,
        "finish": 1456909812,
        "length": 27
      }
    ],
    "finish": 1456916286,
    "status": "PENDING",
    "allowances": [
      {
        "id": 456789,
        "name": "Hazardous Environment Allowance",
        "value": 0.5,
        "cost": 1.75
      }
    ],
    "tag": "Head Technician",
    "tag_id": 65421,
    "cost": 20.1,
    "award_interpretation": [
      {
        "units": 6.45,
        "date": "2016-02-29",
        "export_name": "ORD 1x",
        "secondary_export_name": "PEN10",
        "ordinary_hours": true,
        "cost": 16.125,
        "from": 1456902000,
        "to": 1456916400
      }
    ],
    "department_id": 808,
    "department_export_name": "abc123",
    "metadata": "My special metadata",
    "leave_request_id": 333
  },
  {
    "id": 9956,
    "timesheet_id": 14090,
    "user_id": 123456,
    "date": "2019-01-17",
    "start": 1547685971,
    "break_start": 1547695971,
    "break_finish": 1547697971,
    "break_length": 27,
    "breaks": [
      {
        "id": 42,
        "shift_id": 1337,
        "start": 1547695971,
        "finish": 1547697971,
        "length": 27
      }
    ],
    "finish": 1547697971,
    "status": "PENDING",
    "allowances": [
      {
        "id": 456789,
        "name": "Hazardous Environment Allowance",
        "value": 0.5,
        "cost": 1.75
      }
    ],
    "tag": "Head Technician",
    "tag_id": 65421,
    "cost": 20.1,
    "award_interpretation": [
      {
        "units": 6.45,
        "date": "2019-01-17",
        "export_name": "ORD 1x",
        "ordinary_hours": true,
        "cost": 16.125,
        "from": 1456902000,
        "to": 1456916400
      }
    ],
    "department_id": 808,
    "department_export_name": "abc123"
    "metadata": "My special metadata",
    "leave_request_id": 7889,
  }
]

Get Shift Limits
GET/api/v2/shifts/limits?user_ids=123456,987654

This method requires the timesheet scope (see Scopes for more information).

Gets the first and last shifts (based on start date/time) out of all shifts owned by the given users.

URI Parameters
HideShow
user_ids
string (required) Example: 123456,987654

Comma separated list of user IDs


Staff (Users)

There are no special system permissions to see information about the current user /users/me. However, to CRUD users in the organisation, the user will need to be a payroll officer, department manager, roster manager, or admin.

User List

GET https://my.tanda.co/api/v2/users?show_wages=true
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 123456,
    "name": "Lenny Leonard",
    "date_of_birth": "1955-05-12",
    "employment_start_date": "1989-12-17",
    "employee_id": "LL1",
    "passcode": "0456",
    "platform_role_ids": [
      18,
      19,
      22
    ],
    "department_ids": [
      111
    ],
    "preferred_hours": 20,
    "award": {
      "name": "Fast Food Industry",
      "identifier": "MA000003",
      "note": "This field is deprecated, and may be removed in the future. Please rely on the `award_template_organisation_id` field instead."
    },
    "award_template_id": 990,
    "award_template_organisation_id": 5624432,
    "award_tag_ids": [
      3816
    ],
    "report_department_id": 111,
    "managed_department_ids": [
      222
    ],
    "active": true,
    "email": "lenny.leonard@springfieldpowerplant.com",
    "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
    "phone": "0404 123 123",
    "normalised_phone": "+61404123123",
    "salary": 1234.12,
    "hourly_rate": 32.47,
    "time_zone": "Australia/Brisbane",
    "utc_offset": 36000,
    "part_time_fixed_hours": 20,
    "expected_hours_in_pay_period": 38,
    "days_overtime_averaged_over": 7,
    "overtime_calculated_over_period_start": "2016-09-12",
    "super_fund": {
      "id": 1234,
      "fund_name": "FUND NAME",
      "product_name": "FUND PRODUCT",
      "smsf": false,
      "abn": 123456789
    },
    "super_fund_membership": {
      "super_contribution_type": "arpa",
      "trustee_director": false,
      "member_number": "123ACB",
      "employer_action_date": "2000-01-01T09:30:00+10:00",
      "occupational_rating": "A1",
      "super_fund_id": 1234,
      "employer_preferred": 0,
      "employer_default": 1,
      "employer_generic": 2
    },
    "bank_details": {
      "bsb": 60111,
      "account_number": 12345678,
      "account_name": 0
    },
    "address": {
      "street_line_one": "742 Evergreen Terrace",
      "street_line_two": "Hello, world!",
      "city": "Springfield",
      "state": "Oregon",
      "country": "United States of America",
      "postcode": "97475"
    },
    "tax_declaration": {
      "previous_family_name": "Smith",
      "australian_tax_resident": true,
      "australian_tax_residency_status": "resident",
      "tax_free_threshold": true,
      "senior_tax_offset": false,
      "zone_overseas_carer": false,
      "student_loan": true,
      "financial_supplement_debt": true,
      "tax_code": true,
      "employment_basis": "full_time",
      "tax_file_number": 123456782,
      "student_loan_plans": [
        "uk_loan_plan_1"
      ],
      "uk_tax_year_status": "first_job",
      "tax_scale_type": "regular",
      "income_type": "salary_and_wages",
      "home_country": "Hello, world!",
      "employment_type": "employee",
      "senior_marital_status": "member_of_couple"
    },
    "onboarding_status": "not_applicable, pending, invited, in_progress, completed, invitation_failed",
    "qualifications": [
      {
        "id": 12345,
        "qualification_id": 1234,
        "enabled": true,
        "license_number": "ABC123",
        "expires": "2012-10-20",
        "in_training": false,
        "platform_records": {
          "Proficiency Level": "Level 1 - Beginner"
        }
      }
    ],
    "regular_hours": {
      "start_date": "2021-01-01",
      "schedules": {
        "week": 1,
        "day": "Monday",
        "start": "09:00",
        "end": "17:00",
        "breaks": "12:00",
        "department_id": 1234
      }
    },
    "minimum_base_hours": 20,
    "created_at": 1430715548,
    "record_id": 532432,
    "next_pay_group_id": 53242,
    "last_synced_mobile_app": 1430715548,
    "automatic_break_rule_set_id": 1430715548,
    "temporary_employee_type": "no_agency",
    "position_title": "Bartender",
    "position_template": "Bartender Group",
    "ssn": "123456789"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Users
GET/api/v2/users{?show_wages}

Gets information about all visible users.

This method requires the user scope (see Scopes for more information).

If you are using show_wages=true, the cost scope is also required.

If you want to see financial data, you’ll need the financial scope.

If your account contains more than 50 Qualifications, per-user qualification data will not be returned by default. Include the show_qualifications=true option to include it in the response.

URI Parameters
HideShow
name
string (optional) Example: Homer Simpson

The user’s name. Note, you cannot pass both name and email params.

email
string (optional) Example: homer.simpson@springfieldpowerplant.com

The user’s email.

show_wages
boolean (optional) Example: true

Whether to show the user’s wage (defaults to false)

show_qualifications
boolean (optional) Example: true

Should the response include qualifications for each user

show_regular_hours
boolean (optional) Example: true

Should the response include regular hours for each user

show_inactive
boolean (optional) Example: false

Include inactive staff in your response

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified users

location_id
number (optional) Example: 111

The ID of a location for which to filter users to. If provided, only returns user’s that belong to a department assigned to that location.

report_location_id
number (optional) Example: 111

The ID of a location for which to filter users to. If provided, only returns users if the user’s default team (report_department_id) is set, and it is a department, within this location.

role_types
number (optional) Example: employee

The role type for which to filter users by. This can be a list of role types, separated by a comma (ie. "manager,employee").

platform_role_ids
string (optional) Example: 111

The ID of a role for which to filter users by. This can be a list of ids, separated by a comma (ie. "111,222,333").

employee_id
string (optional) Example: "CC123"

Employee ID to filter by.

normalised_phone
string (optional) Example: "%2B61408123654"

Normalised phone number to filter by.

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false).

page
number (optional) Example: 1

The page number for your user list

page_size
number (optional) Example: 50

The number of users retrieved per page. Maximum 100 per page.


POST https://my.tanda.co/api/v2/users
RequestsCreate UserMinimum fields requiredCreate Regular Hours
Headers
Content-Type: application/json
Body
{
  "name": "Homer Simpson",
  "date_of_birth": "1955-05-12",
  "employment_start_date": "1989-12-17",
  "employee_id": "HS98",
  "passcode": "1230",
  "department_ids": [
    1
  ],
  "preferred_hours": 20,
  "part_time_fixed_hours": 20,
  "award_template_id": 990,
  "award_template_organisation_id": 12345,
  "award_tag_ids": [
    1
  ],
  "report_department_id": 111,
  "managed_department_ids": [
    1
  ],
  "email": "homer.simpson@springfieldpowerplant.com",
  "phone": "0404 123 123",
  "days_overtime_averaged_over": 7,
  "overtime_calculated_over_period_start": "2016-09-12",
  "can_see_costs": true,
  "user_levels": [
    "billing_partner"
  ],
  "hourly_rate": 24.8,
  "yearly_salary": 87450,
  "next_pay_group_id": 53242,
  "address": {
    "street_line_one": "742 Evergreen Terrace",
    "street_line_two": "Hello, world!",
    "city": "Springfield",
    "state": "Oregon",
    "country": "United States of America",
    "postcode": "97475"
  },
  "tax_declaration": {
    "previous_family_name": "Smith",
    "australian_tax_resident": true,
    "australian_tax_residency_status": "resident",
    "tax_free_threshold": true,
    "senior_tax_offset": false,
    "zone_overseas_carer": false,
    "student_loan": true,
    "financial_supplement_debt": true,
    "tax_code": true,
    "employment_basis": "full_time",
    "tax_file_number": 123456782,
    "student_loan_plans": [
      "uk_loan_plan_1"
    ],
    "uk_tax_year_status": "first_job",
    "tax_scale_type": "regular",
    "income_type": "salary_and_wages",
    "home_country": "Hello, world!",
    "employment_type": "employee",
    "senior_marital_status": "member_of_couple"
  },
  "bank_details": {
    "bsb": 60111,
    "account_number": 12345678,
    "account_name": 0
  },
  "super_fund_membership": {
    "request": {
      "employer_default": true,
      "ioof": true,
      "own_choice": true,
      "elevate": true
    },
    "config": {
      "super_contribution_type": "arpa",
      "trustee_director": false,
      "member_number": "123ACB",
      "occupational_rating": "A1",
      "super_fund_id": 1234
    }
  },
  "regular_hours": {
    "start_date": "2021-01-01",
    "schedules": {
      "week": 1,
      "day": "Monday",
      "start": "09:00",
      "end": "17:00",
      "breaks": "12:00",
      "department_id": 1234
    }
  },
  "temporary_employee_type": "no_agency"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "The user's name"
    },
    "date_of_birth": {
      "type": "string",
      "description": "The user's date of birth"
    },
    "employment_start_date": {
      "type": "string",
      "description": "The user's employment start date"
    },
    "employee_id": {
      "type": "string",
      "description": "The user's employee id, used for external systems"
    },
    "passcode": {
      "type": "string",
      "description": "The user's system passcode (used for clocking in and out)"
    },
    "department_ids": {
      "type": "array",
      "description": "The department (team) ids that the user is a member of"
    },
    "preferred_hours": {
      "type": "number",
      "description": "The preferred number of hours to be rostered each week"
    },
    "part_time_fixed_hours": {
      "type": "number",
      "description": "readonly: for part time staff, can be used to configure when overtime starts to apply"
    },
    "award_template_id": {
      "type": "number",
      "description": "The ID of the award template thte user is on"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The ID of the award template organisation"
    },
    "award_tag_ids": {
      "type": "array",
      "description": "The award tag ids that apply to the user"
    },
    "report_department_id": {
      "type": "number",
      "description": "The user's default team"
    },
    "managed_department_ids": {
      "type": "array",
      "description": "The department ids that this user manages"
    },
    "email": {
      "type": "string",
      "description": "The user's email"
    },
    "phone": {
      "type": "string",
      "description": "Phone number for the user"
    },
    "days_overtime_averaged_over": {
      "type": "number",
      "description": "readonly: date range (weekly, fortnightly, or 4-weekly) over which overtime calculations should run"
    },
    "overtime_calculated_over_period_start": {
      "type": "string",
      "description": "readonly: date from which overtime averaging periods should commence"
    },
    "can_see_costs": {
      "type": "boolean",
      "description": "can the user see the costs data"
    },
    "hourly_rate": {
      "type": "number",
      "description": "The users hourly rate"
    },
    "yearly_salary": {
      "type": "number",
      "description": "The users annual salary"
    },
    "next_pay_group_id": {
      "type": "number",
      "description": "the ID for the pay group of the user's next timesheet"
    },
    "address": {
      "type": "object",
      "properties": {
        "street_line_one": {
          "type": "string"
        },
        "street_line_two": {
          "type": [
            "string",
            "null"
          ],
          "description": "Apartment, Suite, etc"
        },
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "state": {
          "type": [
            "string",
            "null"
          ]
        },
        "country": {
          "type": "string"
        },
        "postcode": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "tax_declaration": {
      "type": "object",
      "properties": {
        "previous_family_name": {
          "type": "string",
          "description": "the previous family name of the employee"
        },
        "australian_tax_resident": {
          "type": "boolean",
          "description": "is the user an Australia resident for tax purposes"
        },
        "australian_tax_residency_status": {
          "type": "string"
        },
        "tax_free_threshold": {
          "type": "boolean",
          "description": "is the employee under the tax free threshold?"
        },
        "senior_tax_offset": {
          "type": "boolean",
          "description": "can the employee claim a senior tax offset?"
        },
        "zone_overseas_carer": {
          "type": "boolean",
          "description": "can the employee claim a zone or overseas tax offset?"
        },
        "student_loan": {
          "type": "boolean",
          "description": "does the employee have a student loan?"
        },
        "financial_supplement_debt": {
          "type": "boolean",
          "description": "does the employee have a financial supplement debt?"
        },
        "tax_code": {
          "type": "boolean",
          "description": "the employees code for tax services"
        },
        "employment_basis": {
          "type": "string",
          "enum": [
            "full_time",
            "part_time",
            "casual",
            "labour_hire"
          ],
          "description": "the employment type the employee has specified on their TFN declaration"
        },
        "student_loan_plans": {
          "type": "array",
          "description": "Loan plan type for uk organisations"
        },
        "uk_tax_year_status": {
          "type": "string",
          "enum": [
            "first_job",
            "had_previous_job",
            "second_job"
          ],
          "description": "For uk residents, the stage of the employees career"
        },
        "tax_file_number": {
          "type": "number"
        },
        "tax_scale_type": {
          "type": "string",
          "enum": [
            "regular",
            "horticulturist_or_shearer",
            "senior_or_pensioner",
            "working_holiday_maker"
          ]
        },
        "income_type": {
          "type": "string",
          "enum": [
            "salary_and_wages",
            "working_holiday_maker",
            "non_employee",
            "closely_held_payee",
            "labour_hire"
          ]
        },
        "home_country": {
          "type": "string"
        },
        "employment_type": {
          "type": "string",
          "enum": [
            "employee",
            "contractor"
          ]
        },
        "senior_marital_status": {
          "type": "string",
          "enum": [
            "member_of_couple",
            "member_of_illness_separated_couple",
            "single"
          ]
        }
      },
      "description": "the tax declaration information of the employee"
    },
    "bank_details": {
      "type": "object",
      "properties": {
        "bsb": {
          "type": "number",
          "description": "the bsb number of the employees bank account"
        },
        "account_number": {
          "type": "number",
          "description": "the account number of the employees bank account"
        },
        "account_name": {
          "type": "number",
          "description": "the account name of the employees bank account"
        }
      },
      "required": [
        "bsb",
        "account_number",
        "account_name"
      ],
      "description": "the bank details of the employee"
    },
    "super_fund_membership": {
      "type": "object",
      "properties": {
        "request": {
          "type": "object",
          "properties": {
            "employer_default": {
              "type": "boolean"
            },
            "ioof": {
              "type": "boolean"
            },
            "own_choice": {
              "type": "boolean"
            },
            "elevate": {
              "type": "boolean"
            }
          },
          "required": [
            "employer_default",
            "ioof",
            "own_choice",
            "elevate"
          ]
        },
        "config": {
          "type": "object",
          "properties": {
            "super_contribution_type": {
              "type": "string",
              "description": "the type of the employees super contribution"
            },
            "trustee_director": {
              "type": "boolean",
              "description": "is the employees super fund directed by a trustee?"
            },
            "member_number": {
              "type": "string",
              "description": "the membership number of the employees super fund"
            },
            "occupational_rating": {
              "type": "string",
              "description": "the occupational rating of the employees super fund"
            }
          },
          "oneOf": [
            {
              "properties": {
                "super_fund_id": {
                  "type": "number",
                  "description": "the record ID of the employees super fund"
                }
              }
            },
            {
              "properties": {
                "usi": {
                  "type": "string",
                  "description": "the number that is used to identify an individual super fund and individual superannuation products"
                }
              }
            },
            {
              "properties": {
                "super_fund": {
                  "type": "object",
                  "properties": {
                    "fund_name": {
                      "type": "string"
                    },
                    "abn": {
                      "type": "string"
                    },
                    "electronic_service_address": {
                      "type": "string",
                      "description": "the uniform resource locator (URL) or internet protocol (IP) address of a messaging provider."
                    },
                    "bank_details": {
                      "type": "object",
                      "properties": {
                        "bsb": {
                          "type": "number",
                          "description": "the bsb number of the employees bank account"
                        },
                        "account_number": {
                          "type": "number",
                          "description": "the account number of the employees bank account"
                        },
                        "account_name": {
                          "type": "number",
                          "description": "the account name of the employees bank account"
                        }
                      },
                      "required": [
                        "bsb",
                        "account_number",
                        "account_name"
                      ],
                      "description": "the super funds bank account details"
                    }
                  },
                  "required": [
                    "fund_name",
                    "abn",
                    "electronic_service_address",
                    "bank_details"
                  ],
                  "description": "the super fund name, abn, bank details and ESA"
                }
              }
            }
          ]
        }
      },
      "required": [
        "request",
        "config"
      ],
      "description": "information about the employees super fund membership"
    },
    "regular_hours": {
      "type": "object",
      "properties": {
        "start_date": {
          "type": "string",
          "description": "the anchor date of the regular hours"
        },
        "schedules": {
          "type": "object",
          "properties": {
            "week": {
              "type": "number",
              "description": "which week does the schedule fall in"
            },
            "day": {
              "type": "string",
              "description": "what day is the schedule for"
            },
            "start": {
              "type": "string",
              "description": "what time does the schedule start"
            },
            "end": {
              "type": "string",
              "description": "what time does the schedule finish"
            },
            "breaks": {
              "type": "string",
              "description": "13:00 (string) - what breaks apply to this schedule"
            },
            "department_id": {
              "type": "number",
              "description": "the id of the department the schedule is for"
            }
          },
          "required": [
            "week",
            "day",
            "start",
            "end"
          ],
          "description": "information about the schedules that make up the regular hours of work"
        }
      },
      "required": [
        "start_date"
      ],
      "description": "information about the employees regular hours of work"
    },
    "temporary_employee_type": {
      "type": "string",
      "enum": [
        "no_agency",
        "limber"
      ],
      "description": "Type of a temporary employee user. This field only exists if Enable Temporary Staff setting is turned on."
    }
  },
  "required": [
    "name"
  ],
  "oneOf": [
    {
      "properties": {
        "user_levels": {
          "type": "array"
        }
      }
    },
    {
      "properties": {
        "platform_role_ids": {
          "type": "array",
          "description": "IDs of the user's roles (see Access & Roles)"
        }
      }
    }
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1234567,
  "name": "Homer Simpson",
  "date_of_birth": "1955-05-12",
  "employment_start_date": "1989-12-17",
  "employment_end_date": "1995-07-12",
  "employee_id": "HS98",
  "passcode": "1230",
  "user_levels": [
    "billing_partner"
  ],
  "platform_role_ids": [
    3816,
    3817
  ],
  "department_ids": [
    111
  ],
  "preferred_hours": 20,
  "award_template_id": 990,
  "award_template_organisation_id": 12087,
  "award_tag_ids": [
    1
  ],
  "report_department_id": 111,
  "managed_department_ids": [
    1
  ],
  "active": false,
  "enable_login": true,
  "can_see_costs": false,
  "email": "homer.simpson@springfieldpowerplant.com",
  "photo": "http://vignette2.wikia.nocookie.net/simpsons/images/b/bd/Homer_Simpson.png",
  "phone": "0404 123 123",
  "normalised_phone": "+61404123123",
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "created_at": 1430715549,
  "part_time_fixed_hours": 20,
  "next_pay_group_id": 53242,
  "last_synced_mobile_app": 1430715548,
  "automatic_break_rule_set_id": 1430715548
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the user"
    },
    "name": {
      "type": "string",
      "description": "The user's name"
    },
    "date_of_birth": {
      "type": "string",
      "description": "The user's date of birth"
    },
    "employment_start_date": {
      "type": "string",
      "description": "The user's employment start date"
    },
    "employment_end_date": {
      "type": "string",
      "description": "The users employment end date"
    },
    "employee_id": {
      "type": "string",
      "description": "The user's employee id, used for external systems"
    },
    "passcode": {
      "type": "string",
      "description": "The user's system passcode (used for clocking in and out)"
    },
    "user_levels": {
      "type": "array"
    },
    "platform_role_ids": {
      "type": "array",
      "description": "IDs of the user's roles (see Access & Roles)"
    },
    "department_ids": {
      "type": "array",
      "description": "The department (team) ids that the user is a member of"
    },
    "preferred_hours": {
      "type": "number",
      "description": "The preferred number of hours to be rostered each week"
    },
    "award_template_id": {
      "type": "number",
      "description": "The ID of the award template thte user is on"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The ID of the organisation"
    },
    "award_tag_ids": {
      "type": "array",
      "description": "The award tag ids that apply to the user"
    },
    "report_department_id": {
      "type": "number",
      "description": "The user's default team"
    },
    "managed_department_ids": {
      "type": "array",
      "description": "The department ids that this user manages"
    },
    "active": {
      "type": "boolean",
      "description": "Whether the user is active in the system"
    },
    "enable_login": {
      "type": "boolean",
      "description": "Can the user login"
    },
    "can_see_costs": {
      "type": "boolean",
      "description": "Can the user see costing data"
    },
    "email": {
      "type": "string",
      "description": "The user's email"
    },
    "photo": {
      "type": "string",
      "description": "An avatar for the user"
    },
    "phone": {
      "type": "string",
      "description": "Phone number for the user"
    },
    "normalised_phone": {
      "type": "string",
      "description": "Phone number for user with international dialing code"
    },
    "time_zone": {
      "type": "string",
      "description": "The user's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The user's time zone's UTC offset"
    },
    "created_at": {
      "type": "number",
      "description": "When the user's Tanda profile was created"
    },
    "part_time_fixed_hours": {
      "type": "number",
      "description": "readonly: for part time staff, can be used to configure when overtime starts to apply"
    },
    "next_pay_group_id": {
      "type": "number",
      "description": "the ID for the pay group of the user's next timesheet"
    },
    "last_synced_mobile_app": {
      "type": "number",
      "description": "Read only: when the user last opened the mobile app."
    },
    "automatic_break_rule_set_id": {
      "type": "number",
      "description": "Read only: the ID for the user's automatic break rule set."
    }
  },
  "required": [
    "id",
    "name",
    "passcode",
    "platform_role_ids",
    "department_ids",
    "preferred_hours",
    "award_tag_ids",
    "active",
    "utc_offset",
    "created_at"
  ]
}
Headers
Content-Type: application/json
Body
{
  "name": "Carlton Carlson Jr."
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1234567,
  "name": "Homer Simpson",
  "date_of_birth": "1955-05-12",
  "employment_start_date": "1989-12-17",
  "employment_end_date": "1995-07-12",
  "employee_id": "HS98",
  "passcode": "1230",
  "user_levels": [
    "billing_partner"
  ],
  "platform_role_ids": [
    3816,
    3817
  ],
  "department_ids": [
    111
  ],
  "preferred_hours": 20,
  "award_template_id": 990,
  "award_template_organisation_id": 12087,
  "award_tag_ids": [
    1
  ],
  "report_department_id": 111,
  "managed_department_ids": [
    1
  ],
  "active": false,
  "enable_login": true,
  "can_see_costs": false,
  "email": "homer.simpson@springfieldpowerplant.com",
  "photo": "http://vignette2.wikia.nocookie.net/simpsons/images/b/bd/Homer_Simpson.png",
  "phone": "0404 123 123",
  "normalised_phone": "+61404123123",
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "created_at": 1430715549,
  "part_time_fixed_hours": 20,
  "next_pay_group_id": 53242,
  "last_synced_mobile_app": 1430715548,
  "automatic_break_rule_set_id": 1430715548
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the user"
    },
    "name": {
      "type": "string",
      "description": "The user's name"
    },
    "date_of_birth": {
      "type": "string",
      "description": "The user's date of birth"
    },
    "employment_start_date": {
      "type": "string",
      "description": "The user's employment start date"
    },
    "employment_end_date": {
      "type": "string",
      "description": "The users employment end date"
    },
    "employee_id": {
      "type": "string",
      "description": "The user's employee id, used for external systems"
    },
    "passcode": {
      "type": "string",
      "description": "The user's system passcode (used for clocking in and out)"
    },
    "user_levels": {
      "type": "array"
    },
    "platform_role_ids": {
      "type": "array",
      "description": "IDs of the user's roles (see Access & Roles)"
    },
    "department_ids": {
      "type": "array",
      "description": "The department (team) ids that the user is a member of"
    },
    "preferred_hours": {
      "type": "number",
      "description": "The preferred number of hours to be rostered each week"
    },
    "award_template_id": {
      "type": "number",
      "description": "The ID of the award template thte user is on"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The ID of the organisation"
    },
    "award_tag_ids": {
      "type": "array",
      "description": "The award tag ids that apply to the user"
    },
    "report_department_id": {
      "type": "number",
      "description": "The user's default team"
    },
    "managed_department_ids": {
      "type": "array",
      "description": "The department ids that this user manages"
    },
    "active": {
      "type": "boolean",
      "description": "Whether the user is active in the system"
    },
    "enable_login": {
      "type": "boolean",
      "description": "Can the user login"
    },
    "can_see_costs": {
      "type": "boolean",
      "description": "Can the user see costing data"
    },
    "email": {
      "type": "string",
      "description": "The user's email"
    },
    "photo": {
      "type": "string",
      "description": "An avatar for the user"
    },
    "phone": {
      "type": "string",
      "description": "Phone number for the user"
    },
    "normalised_phone": {
      "type": "string",
      "description": "Phone number for user with international dialing code"
    },
    "time_zone": {
      "type": "string",
      "description": "The user's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The user's time zone's UTC offset"
    },
    "created_at": {
      "type": "number",
      "description": "When the user's Tanda profile was created"
    },
    "part_time_fixed_hours": {
      "type": "number",
      "description": "readonly: for part time staff, can be used to configure when overtime starts to apply"
    },
    "next_pay_group_id": {
      "type": "number",
      "description": "the ID for the pay group of the user's next timesheet"
    },
    "last_synced_mobile_app": {
      "type": "number",
      "description": "Read only: when the user last opened the mobile app."
    },
    "automatic_break_rule_set_id": {
      "type": "number",
      "description": "Read only: the ID for the user's automatic break rule set."
    }
  },
  "required": [
    "id",
    "name",
    "passcode",
    "platform_role_ids",
    "department_ids",
    "preferred_hours",
    "award_tag_ids",
    "active",
    "utc_offset",
    "created_at"
  ]
}
Headers
Content-Type: application/json
Body
{
  "name": "Steve Barnett",
  "regular_hours": {
    "start_date": "2021-01-01",
    "schedules": [
      {
        "week": 1,
        "day": "Monday",
        "start": "09:00",
        "end": "17:00",
        "department_id": 1234,
        "breaks": "12:00-13:00"
      },
      {
        "week": 2,
        "day": "Tuesday",
        "start": "10:00",
        "end": "20:00",
        "department_id": 4321,
        "breaks": "12:00-13:00"
      }
    ]
  }
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 12345678,
  "name": "Steve Barnett",
  "date_of_birth": null,
  "employment_start_date": null,
  "employment_end_date": null,
  "employee_id": null,
  "passcode": null,
  "platform_role_ids": [
    3816
  ],
  "department_ids": [],
  "preferred_hours": 22,
  "award_template_id": null,
  "award_tag_ids": [],
  "report_department_id": null,
  "managed_department_ids": [],
  "active": true,
  "enable_login": true,
  "can_see_costs": true,
  "email": null,
  "photo": null,
  "phone": null,
  "normalised_phone": null,
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "created_at": 1459476813,
  "part_time_fixed_hours": 0,
  "expected_hours_in_pay_period": null,
  "days_overtime_averaged_over": 7,
  "overtime_calculated_over_period_start": "2016-11-14",
  "super_fund_membership": null,
  "super_fund": null,
  "bank_details": null,
  "temporary_employee_type": null,
  "tax_declaration": null,
  "onboarding_status": "not_applicable",
  "qualifications": [],
  "regular_hours": {
    "start_date": "2021-01-01",
    "schedules": [
      {
        "week": 1,
        "day": "Monday",
        "start": "09:00",
        "end": "17:00",
        "department_id": 1234,
        "breaks": "12:00-13:00"
      },
      {
        "week": 2,
        "day": "Tuesday",
        "start": "10:00",
        "end": "20:00",
        "department_id": 4321,
        "breaks": "12:00-13:00"
      }
    ]
  },
  "updated_at": 1562272900
}

Create User
POST/api/v2/users

Only the name field is required to create a user.

To create a manager, you should provide the IDs of Teams they manage in the managed_department_ids field.

The Tanda API currently requires email addresses to be unique within an organisation when creating a user. However, there is no guarantee that this restriction will exist in the future. If you are creating users via the API you should first GET a list of users and validate that the user you’re creating doesn’t already exist - do not depend on the API to validate this for you.

To skip email validation when creating a user, use skip_validation=true.

This method requires the user scope (see Scopes for more information).

If you plan to assign wage information you will need the cost scope. This includes the employee_id field.

To set financial information, you will need the financial scope.

URI Parameters
HideShow
skip_validation
boolean (optional) Example: true

Skip’s checking if an employee already exists with this email address (defaults to false)


Inactive User List

GET https://my.tanda.co/api/v2/users/inactive
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 1234567,
    "name": "Homer Simpson",
    "date_of_birth": null,
    "employment_start_date": null,
    "employment_end_date": "2019-06-01",
    "employee_id": "HS98",
    "passcode": "1230",
    "department_ids": [
      111
    ],
    "preferred_hours": 22,
    "award_template_id": 58,
    "award_tag_ids": [],
    "report_department_id": 111,
    "managed_department_ids": [],
    "active": false,
    "enable_login": true,
    "can_see_costs": true,
    "email": "homer.simpson@springfieldpowerplant.com",
    "photo": "http://vignette2.wikia.nocookie.net/simpsons/images/b/bd/Homer_Simpson.png",
    "phone": "+61404123456",
    "normalised_phone": "+61404123456",
    "time_zone": "Australia/Brisbane",
    "utc_offset": 36000,
    "created_at": 1430715549,
    "part_time_fixed_hours": 0,
    "expected_hours_in_pay_period": null,
    "days_overtime_averaged_over": 7,
    "overtime_calculated_over_period_start": "2016-11-14",
    "super_fund_membership": null,
    "super_fund": null,
    "bank_details": null,
    "temporary_employee_type": null,
    "tax_declaration": null,
    "onboarding_status": "not_applicable",
    "qualifications": [],
    "updated_at": 1562272900
  }
]

Get Inactive Users
GET/api/v2/users/inactive

This method requires the user scope (see Scopes for more information).

URI Parameters
HideShow
name
string (optional) Example: Homer Simpson

The user’s name. Note, you cannot pass both name and email params.

email
string (optional) Example: homer.simpson@springfieldpowerplant.com

The user’s email.

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified users

report_location_id
number (optional) Example: 111

The ID of a location for which to filter users to. If provided, only returns users if the user’s default team (report_department_id) is set, and it is a team within this location.

page
number (optional) Example: 1

The page number for your user list

page_size
number (optional) Example: 50

The number of users retrieved per page. Maximum 100 per page.


User

GET https://my.tanda.co/api/v2/users/123456?show_wages=true
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "name": "Lenny Leonard",
  "date_of_birth": "1955-05-12",
  "employment_start_date": "1989-12-17",
  "employee_id": "LL1",
  "passcode": "0456",
  "platform_role_ids": [
    18,
    19,
    22
  ],
  "department_ids": [
    111
  ],
  "preferred_hours": 20,
  "award": {
    "name": "Fast Food Industry",
    "identifier": "MA000003",
    "note": "This field is deprecated, and may be removed in the future. Please rely on the `award_template_organisation_id` field instead."
  },
  "award_template_id": 990,
  "award_template_organisation_id": 5624432,
  "award_tag_ids": [
    3816
  ],
  "report_department_id": 111,
  "managed_department_ids": [
    222
  ],
  "active": true,
  "email": "lenny.leonard@springfieldpowerplant.com",
  "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
  "phone": "0404 123 123",
  "normalised_phone": "+61404123123",
  "salary": 1234.12,
  "hourly_rate": 32.47,
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "part_time_fixed_hours": 20,
  "expected_hours_in_pay_period": 38,
  "days_overtime_averaged_over": 7,
  "overtime_calculated_over_period_start": "2016-09-12",
  "super_fund": {
    "id": 1234,
    "fund_name": "FUND NAME",
    "product_name": "FUND PRODUCT",
    "smsf": false,
    "abn": 123456789
  },
  "super_fund_membership": {
    "super_contribution_type": "arpa",
    "trustee_director": false,
    "member_number": "123ACB",
    "employer_action_date": "2000-01-01T09:30:00+10:00",
    "occupational_rating": "A1",
    "super_fund_id": 1234,
    "employer_preferred": 0,
    "employer_default": 1,
    "employer_generic": 2
  },
  "bank_details": {
    "bsb": 60111,
    "account_number": 12345678,
    "account_name": 0
  },
  "address": {
    "street_line_one": "742 Evergreen Terrace",
    "street_line_two": "Hello, world!",
    "city": "Springfield",
    "state": "Oregon",
    "country": "United States of America",
    "postcode": "97475"
  },
  "tax_declaration": {
    "previous_family_name": "Smith",
    "australian_tax_resident": true,
    "australian_tax_residency_status": "resident",
    "tax_free_threshold": true,
    "senior_tax_offset": false,
    "zone_overseas_carer": false,
    "student_loan": true,
    "financial_supplement_debt": true,
    "tax_code": true,
    "employment_basis": "full_time",
    "tax_file_number": 123456782,
    "student_loan_plans": [
      "uk_loan_plan_1"
    ],
    "uk_tax_year_status": "first_job",
    "tax_scale_type": "regular",
    "income_type": "salary_and_wages",
    "home_country": "Hello, world!",
    "employment_type": "employee",
    "senior_marital_status": "member_of_couple"
  },
  "onboarding_status": "not_applicable, pending, invited, in_progress, completed, invitation_failed",
  "qualifications": [
    {
      "id": 12345,
      "qualification_id": 1234,
      "enabled": true,
      "license_number": "ABC123",
      "expires": "2012-10-20",
      "in_training": false,
      "platform_records": {
        "Proficiency Level": "Level 1 - Beginner"
      }
    }
  ],
  "regular_hours": {
    "start_date": "2021-01-01",
    "schedules": {
      "week": 1,
      "day": "Monday",
      "start": "09:00",
      "end": "17:00",
      "breaks": "12:00",
      "department_id": 1234
    }
  },
  "minimum_base_hours": 20,
  "created_at": 1430715548,
  "record_id": 532432,
  "next_pay_group_id": 53242,
  "last_synced_mobile_app": 1430715548,
  "automatic_break_rule_set_id": 1430715548,
  "temporary_employee_type": "no_agency",
  "position_title": "Bartender",
  "position_template": "Bartender Group",
  "ssn": "123456789"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the user"
    },
    "name": {
      "type": "string",
      "description": "The user's name"
    },
    "date_of_birth": {
      "type": "string",
      "description": "The user's date of birth"
    },
    "employment_start_date": {
      "type": "string",
      "description": "The user's employment start date"
    },
    "employee_id": {
      "type": "string",
      "description": "The user's employee id, used for external systems"
    },
    "passcode": {
      "type": "string",
      "description": "The user's system passcode (used for clocking in and out)"
    },
    "platform_role_ids": {
      "type": "array",
      "description": "IDs of the user's roles (see Access & Roles)"
    },
    "department_ids": {
      "type": "array",
      "description": "The department (team) ids that the user is a member of"
    },
    "preferred_hours": {
      "type": "number",
      "description": "The preferred number of hours to be rostered each week"
    },
    "award": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of the award"
        },
        "identifier": {
          "type": "string",
          "description": "The award's identifier (will be the award code for all modern awards)"
        },
        "note": {
          "type": "string",
          "description": "This field is deprecated, and may be removed in the future. Please rely on the `award_template_organisation_id` field instead."
        }
      },
      "required": [
        "name"
      ],
      "description": "Information about the user's award, null if user isn't on award"
    },
    "award_template_id": {
      "type": "number",
      "description": "The ID of the award template the user is on"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The internal ID of the award template the user is on"
    },
    "award_tag_ids": {
      "type": "array",
      "description": "The award tag ids that apply to the user"
    },
    "report_department_id": {
      "type": "number",
      "description": "The user's default team"
    },
    "managed_department_ids": {
      "type": "array",
      "description": "The department ids that this user manages"
    },
    "active": {
      "type": "boolean",
      "description": "Whether the user is active in the system"
    },
    "email": {
      "type": "string",
      "description": "The user's email"
    },
    "photo": {
      "type": "string",
      "description": "An avatar for the user"
    },
    "phone": {
      "type": "string",
      "description": "Phone number for the user"
    },
    "normalised_phone": {
      "type": "string",
      "description": "Phone number for user with international dialing code"
    },
    "salary": {
      "type": "number",
      "description": "The weekly salary of the user, if `show_wages=true` parameter is set"
    },
    "hourly_rate": {
      "type": "number",
      "description": "The hourly rate of the user, if `show_wages=true` parameter is set, will not show if the salary exists"
    },
    "time_zone": {
      "type": "string",
      "description": "The user's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The user's time zone's UTC offset"
    },
    "part_time_fixed_hours": {
      "type": "number",
      "description": "For part time staff, can be used to configure when overtime starts to apply"
    },
    "expected_hours_in_pay_period": {
      "type": "number",
      "description": "readonly: for salaried staff, defines expected number of hours worked per pay period"
    },
    "days_overtime_averaged_over": {
      "type": "number",
      "description": "date range (weekly, fortnightly, or 4-weekly) over which overtime calculations should run"
    },
    "overtime_calculated_over_period_start": {
      "type": "string",
      "description": "date from which overtime averaging periods should commence"
    },
    "super_fund": {
      "type": "object",
      "properties": {
        "id": {
          "type": "number",
          "description": "the unique ID of the employees fund"
        },
        "fund_name": {
          "type": "string",
          "description": "the name of the fund"
        },
        "product_name": {
          "type": "string",
          "description": "the name of the fund product"
        },
        "smsf": {
          "type": "boolean",
          "description": "is the fund a self managed fund"
        },
        "abn": {
          "type": "number",
          "description": "the number of the fund"
        }
      },
      "description": "information about the employees super fund"
    },
    "super_fund_membership": {
      "type": "object",
      "properties": {
        "super_contribution_type": {
          "type": "string",
          "description": "the type of the employees super contribution"
        },
        "trustee_director": {
          "type": "boolean",
          "description": "is the employees super fund directed by a trustee?"
        },
        "member_number": {
          "type": "string",
          "description": "the membership number of the employees super fund"
        },
        "employer_action_date": {
          "type": "string",
          "description": "the action date of the super fund by the employer"
        },
        "occupational_rating": {
          "type": "string",
          "description": "the occupational rating of the employees super fund"
        },
        "super_fund_id": {
          "type": "number",
          "description": "the record ID of the employees super fund"
        },
        "employer_preferred": {
          "type": "number",
          "description": "indication of an employers preferred super fund"
        },
        "employer_default": {
          "type": "number",
          "description": "indication of an employers default super fund"
        },
        "employer_generic": {
          "type": "number",
          "description": "indication of an employers generic super fund"
        }
      },
      "required": [
        "super_fund_id",
        "employer_preferred",
        "employer_default",
        "employer_generic"
      ],
      "description": "information about the employees super fund membership"
    },
    "bank_details": {
      "type": "object",
      "properties": {
        "bsb": {
          "type": "number",
          "description": "the bsb number of the employees bank account"
        },
        "account_number": {
          "type": "number",
          "description": "the account number of the employees bank account"
        },
        "account_name": {
          "type": "number",
          "description": "the account name of the employees bank account"
        }
      },
      "required": [
        "bsb",
        "account_number",
        "account_name"
      ],
      "description": "the bank details of the employee"
    },
    "address": {
      "type": "object",
      "properties": {
        "street_line_one": {
          "type": "string"
        },
        "street_line_two": {
          "type": [
            "string",
            "null"
          ],
          "description": "Apartment, Suite, etc"
        },
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "state": {
          "type": [
            "string",
            "null"
          ]
        },
        "country": {
          "type": "string"
        },
        "postcode": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "tax_declaration": {
      "type": "object",
      "properties": {
        "previous_family_name": {
          "type": "string",
          "description": "the previous family name of the employee"
        },
        "australian_tax_resident": {
          "type": "boolean",
          "description": "is the user an Australia resident for tax purposes"
        },
        "australian_tax_residency_status": {
          "type": "string"
        },
        "tax_free_threshold": {
          "type": "boolean",
          "description": "is the employee under the tax free threshold?"
        },
        "senior_tax_offset": {
          "type": "boolean",
          "description": "can the employee claim a senior tax offset?"
        },
        "zone_overseas_carer": {
          "type": "boolean",
          "description": "can the employee claim a zone or overseas tax offset?"
        },
        "student_loan": {
          "type": "boolean",
          "description": "does the employee have a student loan?"
        },
        "financial_supplement_debt": {
          "type": "boolean",
          "description": "does the employee have a financial supplement debt?"
        },
        "tax_code": {
          "type": "boolean",
          "description": "the employees code for tax services"
        },
        "employment_basis": {
          "type": "string",
          "enum": [
            "full_time",
            "part_time",
            "casual",
            "labour_hire"
          ],
          "description": "the employment type the employee has specified on their TFN declaration"
        },
        "student_loan_plans": {
          "type": "array",
          "description": "Loan plan type for uk organisations"
        },
        "uk_tax_year_status": {
          "type": "string",
          "enum": [
            "first_job",
            "had_previous_job",
            "second_job"
          ],
          "description": "For uk residents, the stage of the employees career"
        },
        "tax_file_number": {
          "type": "number"
        },
        "tax_scale_type": {
          "type": "string",
          "enum": [
            "regular",
            "horticulturist_or_shearer",
            "senior_or_pensioner",
            "working_holiday_maker"
          ]
        },
        "income_type": {
          "type": "string",
          "enum": [
            "salary_and_wages",
            "working_holiday_maker",
            "non_employee",
            "closely_held_payee",
            "labour_hire"
          ]
        },
        "home_country": {
          "type": "string"
        },
        "employment_type": {
          "type": "string",
          "enum": [
            "employee",
            "contractor"
          ]
        },
        "senior_marital_status": {
          "type": "string",
          "enum": [
            "member_of_couple",
            "member_of_illness_separated_couple",
            "single"
          ]
        }
      },
      "description": "the tax declaration information of the employee"
    },
    "onboarding_status": {
      "type": "string",
      "description": "the status of the employee onboarding progress"
    },
    "qualifications": {
      "type": "array",
      "description": "Information about qualifications the user holds, if Qualifications are enabled"
    },
    "regular_hours": {
      "type": "object",
      "properties": {
        "start_date": {
          "type": "string",
          "description": "the anchor date of the regular hours"
        },
        "schedules": {
          "type": "object",
          "properties": {
            "week": {
              "type": "number",
              "description": "which week does the schedule fall in"
            },
            "day": {
              "type": "string",
              "description": "what day is the schedule for"
            },
            "start": {
              "type": "string",
              "description": "what time does the schedule start"
            },
            "end": {
              "type": "string",
              "description": "what time does the schedule finish"
            },
            "breaks": {
              "type": "string",
              "description": "13:00 (string) - what breaks apply to this schedule"
            },
            "department_id": {
              "type": "number",
              "description": "the id of the department the schedule is for"
            }
          },
          "required": [
            "week",
            "day",
            "start",
            "end"
          ],
          "description": "information about the schedules that make up the regular hours of work"
        }
      },
      "required": [
        "start_date"
      ],
      "description": "information about the employees regular hours of work"
    },
    "minimum_base_hours": {
      "type": "number",
      "description": "minimum required hours for this employee"
    },
    "created_at": {
      "type": "number",
      "description": "When the user's Tanda profile was created"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "next_pay_group_id": {
      "type": "number",
      "description": "the ID for the pay group of the user's next timesheet"
    },
    "last_synced_mobile_app": {
      "type": "number",
      "description": "Read only: when the user last opened the mobile app."
    },
    "automatic_break_rule_set_id": {
      "type": "number",
      "description": "Read only: the ID for the user's automatic break rule set."
    },
    "temporary_employee_type": {
      "type": "string",
      "enum": [
        "no_agency",
        "limber"
      ],
      "description": "Type of a temporary employee user. This field only exists if Enable Temporary Staff setting is turned on."
    },
    "position_title": {
      "type": "string",
      "description": "Read only"
    },
    "position_template": {
      "type": "string",
      "description": "Read only"
    },
    "ssn": {
      "type": "string",
      "description": "Read only"
    }
  },
  "required": [
    "id",
    "name",
    "passcode",
    "platform_role_ids",
    "department_ids",
    "preferred_hours",
    "award_tag_ids",
    "active",
    "utc_offset",
    "created_at"
  ]
}

Get User
GET/api/v2/users/{id}{?show_wages}

Gets information about a user.

This method requires the user scope (see Scopes for more information).

If you are using show_wages=true, the cost scope is also required.

URI Parameters
HideShow
id
number (required) Example: 123456

The id of the user

show_wages
boolean (optional) Example: true

Whether to show the user’s wage (defaults to false)

show_regular_hours
boolean (optional) Example: true

Whether to show the user’s regular hours (defaults to false)

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false)


PUT https://my.tanda.co/api/v2/users/123456
RequestsUpdate UserDeactivate UserRemove DepartmentsUpdate Regular Hours
Headers
Content-Type: application/json
Body
{
  "name": "Lenford Leonard",
  "employee_id": "Lenford",
  "passcode": "0123",
  "phone": "0404123122",
  "date_of_birth": "1990-12-12",
  "employment_start_date": "2016-03-01",
  "email": "some_email@test.com",
  "hourly_rate": 12.34,
  "enable_login": true,
  "qualifications": [
    {
      "qualification_id": 2345,
      "enabled": true,
      "license_number": "BCD234",
      "expires": "2012-11-21",
      "in_training": false,
      "file_id": "2d4ab757-637c-4be2-b2d6-5f89ae211ba4"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "The user's name"
    },
    "date_of_birth": {
      "type": "string",
      "description": "The user's date of birth"
    },
    "employment_start_date": {
      "type": "string",
      "description": "The user's employment start date"
    },
    "employee_id": {
      "type": "string",
      "description": "The user's employee id, used for external systems"
    },
    "passcode": {
      "type": "string",
      "description": "The user's system passcode (used for clocking in and out)"
    },
    "department_ids": {
      "type": "array",
      "description": "The department (team) ids that the user is a member of"
    },
    "preferred_hours": {
      "type": "number",
      "description": "The preferred number of hours to be rostered each week"
    },
    "part_time_fixed_hours": {
      "type": "number",
      "description": "readonly: for part time staff, can be used to configure when overtime starts to apply"
    },
    "award_template_id": {
      "type": "number",
      "description": "The ID of the award template thte user is on"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The ID of the award template organisation"
    },
    "award_tag_ids": {
      "type": "array",
      "description": "The award tag ids that apply to the user"
    },
    "report_department_id": {
      "type": "number",
      "description": "The user's default team"
    },
    "managed_department_ids": {
      "type": "array",
      "description": "The department ids that this user manages"
    },
    "email": {
      "type": "string",
      "description": "The user's email"
    },
    "phone": {
      "type": "string",
      "description": "Phone number for the user"
    },
    "days_overtime_averaged_over": {
      "type": "number",
      "description": "readonly: date range (weekly, fortnightly, or 4-weekly) over which overtime calculations should run"
    },
    "overtime_calculated_over_period_start": {
      "type": "string",
      "description": "readonly: date from which overtime averaging periods should commence"
    },
    "can_see_costs": {
      "type": "boolean",
      "description": "can the user see the costs data"
    },
    "hourly_rate": {
      "type": "number",
      "description": "The users hourly rate"
    },
    "yearly_salary": {
      "type": "number",
      "description": "The users annual salary"
    },
    "next_pay_group_id": {
      "type": "number",
      "description": "the ID for the pay group of the user's next timesheet"
    },
    "address": {
      "type": "object",
      "properties": {
        "street_line_one": {
          "type": "string"
        },
        "street_line_two": {
          "type": [
            "string",
            "null"
          ],
          "description": "Apartment, Suite, etc"
        },
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "state": {
          "type": [
            "string",
            "null"
          ]
        },
        "country": {
          "type": "string"
        },
        "postcode": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "tax_declaration": {
      "type": "object",
      "properties": {
        "previous_family_name": {
          "type": "string",
          "description": "the previous family name of the employee"
        },
        "australian_tax_resident": {
          "type": "boolean",
          "description": "is the user an Australia resident for tax purposes"
        },
        "australian_tax_residency_status": {
          "type": "string"
        },
        "tax_free_threshold": {
          "type": "boolean",
          "description": "is the employee under the tax free threshold?"
        },
        "senior_tax_offset": {
          "type": "boolean",
          "description": "can the employee claim a senior tax offset?"
        },
        "zone_overseas_carer": {
          "type": "boolean",
          "description": "can the employee claim a zone or overseas tax offset?"
        },
        "student_loan": {
          "type": "boolean",
          "description": "does the employee have a student loan?"
        },
        "financial_supplement_debt": {
          "type": "boolean",
          "description": "does the employee have a financial supplement debt?"
        },
        "tax_code": {
          "type": "boolean",
          "description": "the employees code for tax services"
        },
        "employment_basis": {
          "type": "string",
          "enum": [
            "full_time",
            "part_time",
            "casual",
            "labour_hire"
          ],
          "description": "the employment type the employee has specified on their TFN declaration"
        },
        "student_loan_plans": {
          "type": "array",
          "description": "Loan plan type for uk organisations"
        },
        "uk_tax_year_status": {
          "type": "string",
          "enum": [
            "first_job",
            "had_previous_job",
            "second_job"
          ],
          "description": "For uk residents, the stage of the employees career"
        },
        "tax_file_number": {
          "type": "number"
        },
        "tax_scale_type": {
          "type": "string",
          "enum": [
            "regular",
            "horticulturist_or_shearer",
            "senior_or_pensioner",
            "working_holiday_maker"
          ]
        },
        "income_type": {
          "type": "string",
          "enum": [
            "salary_and_wages",
            "working_holiday_maker",
            "non_employee",
            "closely_held_payee",
            "labour_hire"
          ]
        },
        "home_country": {
          "type": "string"
        },
        "employment_type": {
          "type": "string",
          "enum": [
            "employee",
            "contractor"
          ]
        },
        "senior_marital_status": {
          "type": "string",
          "enum": [
            "member_of_couple",
            "member_of_illness_separated_couple",
            "single"
          ]
        }
      },
      "description": "the tax declaration information of the employee"
    },
    "bank_details": {
      "type": "object",
      "properties": {
        "bsb": {
          "type": "number",
          "description": "the bsb number of the employees bank account"
        },
        "account_number": {
          "type": "number",
          "description": "the account number of the employees bank account"
        },
        "account_name": {
          "type": "number",
          "description": "the account name of the employees bank account"
        }
      },
      "required": [
        "bsb",
        "account_number",
        "account_name"
      ],
      "description": "the bank details of the employee"
    },
    "super_fund_membership": {
      "type": "object",
      "properties": {
        "request": {
          "type": "object",
          "properties": {
            "employer_default": {
              "type": "boolean"
            },
            "ioof": {
              "type": "boolean"
            },
            "own_choice": {
              "type": "boolean"
            },
            "elevate": {
              "type": "boolean"
            }
          },
          "required": [
            "employer_default",
            "ioof",
            "own_choice",
            "elevate"
          ]
        },
        "config": {
          "type": "object",
          "properties": {
            "super_contribution_type": {
              "type": "string",
              "description": "the type of the employees super contribution"
            },
            "trustee_director": {
              "type": "boolean",
              "description": "is the employees super fund directed by a trustee?"
            },
            "member_number": {
              "type": "string",
              "description": "the membership number of the employees super fund"
            },
            "occupational_rating": {
              "type": "string",
              "description": "the occupational rating of the employees super fund"
            }
          },
          "oneOf": [
            {
              "properties": {
                "super_fund_id": {
                  "type": "number",
                  "description": "the record ID of the employees super fund"
                }
              }
            },
            {
              "properties": {
                "usi": {
                  "type": "string",
                  "description": "the number that is used to identify an individual super fund and individual superannuation products"
                }
              }
            },
            {
              "properties": {
                "super_fund": {
                  "type": "object",
                  "properties": {
                    "fund_name": {
                      "type": "string"
                    },
                    "abn": {
                      "type": "string"
                    },
                    "electronic_service_address": {
                      "type": "string",
                      "description": "the uniform resource locator (URL) or internet protocol (IP) address of a messaging provider."
                    },
                    "bank_details": {
                      "type": "object",
                      "properties": {
                        "bsb": {
                          "type": "number",
                          "description": "the bsb number of the employees bank account"
                        },
                        "account_number": {
                          "type": "number",
                          "description": "the account number of the employees bank account"
                        },
                        "account_name": {
                          "type": "number",
                          "description": "the account name of the employees bank account"
                        }
                      },
                      "required": [
                        "bsb",
                        "account_number",
                        "account_name"
                      ],
                      "description": "the super funds bank account details"
                    }
                  },
                  "required": [
                    "fund_name",
                    "abn",
                    "electronic_service_address",
                    "bank_details"
                  ],
                  "description": "the super fund name, abn, bank details and ESA"
                }
              }
            }
          ]
        }
      },
      "required": [
        "request",
        "config"
      ],
      "description": "information about the employees super fund membership"
    },
    "regular_hours": {
      "type": "object",
      "properties": {
        "start_date": {
          "type": "string",
          "description": "the anchor date of the regular hours"
        },
        "schedules": {
          "type": "object",
          "properties": {
            "week": {
              "type": "number",
              "description": "which week does the schedule fall in"
            },
            "day": {
              "type": "string",
              "description": "what day is the schedule for"
            },
            "start": {
              "type": "string",
              "description": "what time does the schedule start"
            },
            "end": {
              "type": "string",
              "description": "what time does the schedule finish"
            },
            "breaks": {
              "type": "string",
              "description": "13:00 (string) - what breaks apply to this schedule"
            },
            "department_id": {
              "type": "number",
              "description": "the id of the department the schedule is for"
            }
          },
          "required": [
            "week",
            "day",
            "start",
            "end"
          ],
          "description": "information about the schedules that make up the regular hours of work"
        }
      },
      "required": [
        "start_date"
      ],
      "description": "information about the employees regular hours of work"
    },
    "temporary_employee_type": {
      "type": "string",
      "enum": [
        "no_agency",
        "limber"
      ],
      "description": "Type of a temporary employee user. This field only exists if Enable Temporary Staff setting is turned on."
    },
    "employment_end_date": {
      "type": "string",
      "description": "The user's employment end date"
    },
    "active": {
      "type": "boolean"
    },
    "qualifications": {
      "type": "object",
      "properties": {
        "id": {
          "type": "number"
        },
        "qualification_id": {
          "type": "number"
        },
        "enabled": {
          "type": "boolean"
        },
        "license_number": {
          "type": "string"
        },
        "expires": {
          "type": "string"
        },
        "in_training": {
          "type": "boolean"
        },
        "date_ranges": {
          "type": "object",
          "properties": {}
        },
        "file_id": {
          "type": "string"
        }
      }
    },
    "answered_questions": {
      "type": "array"
    },
    "minimum_base_hours": {
      "type": "number"
    }
  },
  "oneOf": [
    {
      "properties": {
        "user_levels": {
          "type": "array"
        }
      }
    },
    {
      "properties": {
        "platform_role_ids": {
          "type": "array",
          "description": "IDs of the user's roles (see Access & Roles)"
        }
      }
    }
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "name": "Lenford Leonard",
  "date_of_birth": "1990-12-12",
  "employment_start_date": "2016-03-01",
  "employee_id": "Lenford",
  "passcode": "0123",
  "platform_role_ids": [
    18,
    19,
    22
  ],
  "department_ids": [
    111
  ],
  "preferred_hours": 20,
  "award": {
    "name": "Fast Food Industry",
    "identifier": "MA000003",
    "note": "This field is deprecated, and may be removed in the future. Please rely on the `award_template_organisation_id` field instead."
  },
  "award_template_id": 990,
  "award_template_organisation_id": 5624432,
  "award_tag_ids": [
    3816
  ],
  "report_department_id": 111,
  "managed_department_ids": [
    222
  ],
  "active": true,
  "email": "some_email@test.com",
  "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
  "phone": "0404123122",
  "normalised_phone": "+61404123122",
  "salary": 1234.12,
  "hourly_rate": 12.34,
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "part_time_fixed_hours": 20,
  "expected_hours_in_pay_period": 38,
  "days_overtime_averaged_over": 7,
  "overtime_calculated_over_period_start": "2016-09-12",
  "super_fund": {
    "id": 1234,
    "fund_name": "FUND NAME",
    "product_name": "FUND PRODUCT",
    "smsf": false,
    "abn": 123456789
  },
  "super_fund_membership": {
    "super_contribution_type": "arpa",
    "trustee_director": false,
    "member_number": "123ACB",
    "employer_action_date": "2000-01-01T09:30:00+10:00",
    "occupational_rating": "A1",
    "super_fund_id": 1234,
    "employer_preferred": 0,
    "employer_default": 1,
    "employer_generic": 2
  },
  "bank_details": {
    "bsb": 60111,
    "account_number": 12345678,
    "account_name": 0
  },
  "address": {
    "street_line_one": "742 Evergreen Terrace",
    "street_line_two": null,
    "city": "Springfield",
    "state": "Oregon",
    "country": "United States of America",
    "postcode": "97475"
  },
  "tax_declaration": {
    "previous_family_name": "Smith",
    "australian_tax_resident": true,
    "australian_tax_residency_status": "resident",
    "tax_free_threshold": true,
    "senior_tax_offset": false,
    "zone_overseas_carer": false,
    "student_loan": true,
    "financial_supplement_debt": true,
    "tax_code": true,
    "employment_basis": "full_time",
    "student_loan_plans": [
      "uk_loan_plan_1"
    ],
    "uk_tax_year_status": "first_job",
    "tax_file_number": 123456782,
    "tax_scale_type": "regular",
    "income_type": "salary_and_wages",
    "home_country": "",
    "employment_type": "employee",
    "senior_marital_status": "member_of_couple"
  },
  "onboarding_status": "not_applicable, pending, invited, in_progress, completed, invitation_failed",
  "qualifications": "[{}]",
  "regular_hours": {
    "start_date": "2021-01-01",
    "schedules": {
      "week": 1,
      "day": "Monday",
      "start": "09:00",
      "end": "17:00",
      "breaks": "12:00",
      "department_id": 1234
    }
  },
  "minimum_base_hours": 20,
  "created_at": 1430715548,
  "record_id": 532432,
  "next_pay_group_id": 53242,
  "last_synced_mobile_app": 1430715548,
  "automatic_break_rule_set_id": 1430715548,
  "temporary_employee_type": "no_agency",
  "position_title": "Bartender",
  "position_template": "Bartender Group",
  "ssn": "123456789",
  "enable_login": true
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the user"
    },
    "name": {
      "type": "string",
      "description": "The user's name"
    },
    "date_of_birth": {
      "type": "string",
      "description": "The user's date of birth"
    },
    "employment_start_date": {
      "type": "string",
      "description": "The user's employment start date"
    },
    "employee_id": {
      "type": "string",
      "description": "The user's employee id, used for external systems"
    },
    "passcode": {
      "type": "string",
      "description": "The user's system passcode (used for clocking in and out)"
    },
    "platform_role_ids": {
      "type": "array",
      "description": "IDs of the user's roles (see Access & Roles)"
    },
    "department_ids": {
      "type": "array",
      "description": "The department (team) ids that the user is a member of"
    },
    "preferred_hours": {
      "type": "number",
      "description": "The preferred number of hours to be rostered each week"
    },
    "award": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of the award"
        },
        "identifier": {
          "type": "string",
          "description": "The award's identifier (will be the award code for all modern awards)"
        },
        "note": {
          "type": "string",
          "description": "This field is deprecated, and may be removed in the future. Please rely on the `award_template_organisation_id` field instead."
        }
      },
      "required": [
        "name"
      ],
      "description": "Information about the user's award, null if user isn't on award"
    },
    "award_template_id": {
      "type": "number",
      "description": "The ID of the award template the user is on"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The internal ID of the award template the user is on"
    },
    "award_tag_ids": {
      "type": "array",
      "description": "The award tag ids that apply to the user"
    },
    "report_department_id": {
      "type": "number",
      "description": "The user's default team"
    },
    "managed_department_ids": {
      "type": "array",
      "description": "The department ids that this user manages"
    },
    "active": {
      "type": "boolean",
      "description": "Whether the user is active in the system"
    },
    "email": {
      "type": "string",
      "description": "The user's email"
    },
    "photo": {
      "type": "string",
      "description": "An avatar for the user"
    },
    "phone": {
      "type": "string",
      "description": "Phone number for the user"
    },
    "normalised_phone": {
      "type": "string",
      "description": "Phone number for user with international dialing code"
    },
    "salary": {
      "type": "number",
      "description": "The weekly salary of the user, if `show_wages=true` parameter is set"
    },
    "hourly_rate": {
      "type": "number",
      "description": "The hourly rate of the user, if `show_wages=true` parameter is set, will not show if the salary exists"
    },
    "time_zone": {
      "type": "string",
      "description": "The user's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The user's time zone's UTC offset"
    },
    "part_time_fixed_hours": {
      "type": "number",
      "description": "For part time staff, can be used to configure when overtime starts to apply"
    },
    "expected_hours_in_pay_period": {
      "type": "number",
      "description": "readonly: for salaried staff, defines expected number of hours worked per pay period"
    },
    "days_overtime_averaged_over": {
      "type": "number",
      "description": "date range (weekly, fortnightly, or 4-weekly) over which overtime calculations should run"
    },
    "overtime_calculated_over_period_start": {
      "type": "string",
      "description": "date from which overtime averaging periods should commence"
    },
    "super_fund": {
      "type": "object",
      "properties": {
        "id": {
          "type": "number",
          "description": "the unique ID of the employees fund"
        },
        "fund_name": {
          "type": "string",
          "description": "the name of the fund"
        },
        "product_name": {
          "type": "string",
          "description": "the name of the fund product"
        },
        "smsf": {
          "type": "boolean",
          "description": "is the fund a self managed fund"
        },
        "abn": {
          "type": "number",
          "description": "the number of the fund"
        }
      },
      "description": "information about the employees super fund"
    },
    "super_fund_membership": {
      "type": "object",
      "properties": {
        "super_contribution_type": {
          "type": "string",
          "description": "the type of the employees super contribution"
        },
        "trustee_director": {
          "type": "boolean",
          "description": "is the employees super fund directed by a trustee?"
        },
        "member_number": {
          "type": "string",
          "description": "the membership number of the employees super fund"
        },
        "employer_action_date": {
          "type": "string",
          "description": "the action date of the super fund by the employer"
        },
        "occupational_rating": {
          "type": "string",
          "description": "the occupational rating of the employees super fund"
        },
        "super_fund_id": {
          "type": "number",
          "description": "the record ID of the employees super fund"
        },
        "employer_preferred": {
          "type": "number",
          "description": "indication of an employers preferred super fund"
        },
        "employer_default": {
          "type": "number",
          "description": "indication of an employers default super fund"
        },
        "employer_generic": {
          "type": "number",
          "description": "indication of an employers generic super fund"
        }
      },
      "required": [
        "super_fund_id",
        "employer_preferred",
        "employer_default",
        "employer_generic"
      ],
      "description": "information about the employees super fund membership"
    },
    "bank_details": {
      "type": "object",
      "properties": {
        "bsb": {
          "type": "number",
          "description": "the bsb number of the employees bank account"
        },
        "account_number": {
          "type": "number",
          "description": "the account number of the employees bank account"
        },
        "account_name": {
          "type": "number",
          "description": "the account name of the employees bank account"
        }
      },
      "required": [
        "bsb",
        "account_number",
        "account_name"
      ],
      "description": "the bank details of the employee"
    },
    "address": {
      "type": "object",
      "properties": {
        "street_line_one": {
          "type": "string"
        },
        "street_line_two": {
          "type": [
            "string",
            "null"
          ],
          "description": "Apartment, Suite, etc"
        },
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "state": {
          "type": [
            "string",
            "null"
          ]
        },
        "country": {
          "type": "string"
        },
        "postcode": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "tax_declaration": {
      "type": "object",
      "properties": {
        "previous_family_name": {
          "type": "string",
          "description": "the previous family name of the employee"
        },
        "australian_tax_resident": {
          "type": "boolean",
          "description": "is the user an Australia resident for tax purposes"
        },
        "australian_tax_residency_status": {
          "type": "string"
        },
        "tax_free_threshold": {
          "type": "boolean",
          "description": "is the employee under the tax free threshold?"
        },
        "senior_tax_offset": {
          "type": "boolean",
          "description": "can the employee claim a senior tax offset?"
        },
        "zone_overseas_carer": {
          "type": "boolean",
          "description": "can the employee claim a zone or overseas tax offset?"
        },
        "student_loan": {
          "type": "boolean",
          "description": "does the employee have a student loan?"
        },
        "financial_supplement_debt": {
          "type": "boolean",
          "description": "does the employee have a financial supplement debt?"
        },
        "tax_code": {
          "type": "boolean",
          "description": "the employees code for tax services"
        },
        "employment_basis": {
          "type": "string",
          "enum": [
            "full_time",
            "part_time",
            "casual",
            "labour_hire"
          ],
          "description": "the employment type the employee has specified on their TFN declaration"
        },
        "student_loan_plans": {
          "type": "array",
          "description": "Loan plan type for uk organisations"
        },
        "uk_tax_year_status": {
          "type": "string",
          "enum": [
            "first_job",
            "had_previous_job",
            "second_job"
          ],
          "description": "For uk residents, the stage of the employees career"
        },
        "tax_file_number": {
          "type": "number"
        },
        "tax_scale_type": {
          "type": "string",
          "enum": [
            "regular",
            "horticulturist_or_shearer",
            "senior_or_pensioner",
            "working_holiday_maker"
          ]
        },
        "income_type": {
          "type": "string",
          "enum": [
            "salary_and_wages",
            "working_holiday_maker",
            "non_employee",
            "closely_held_payee",
            "labour_hire"
          ]
        },
        "home_country": {
          "type": "string"
        },
        "employment_type": {
          "type": "string",
          "enum": [
            "employee",
            "contractor"
          ]
        },
        "senior_marital_status": {
          "type": "string",
          "enum": [
            "member_of_couple",
            "member_of_illness_separated_couple",
            "single"
          ]
        }
      },
      "description": "the tax declaration information of the employee"
    },
    "onboarding_status": {
      "type": "string",
      "description": "the status of the employee onboarding progress"
    },
    "qualifications": {
      "type": "string",
      "description": "Information about qualifications the user holds, if Qualifications are enabled"
    },
    "regular_hours": {
      "type": "object",
      "properties": {
        "start_date": {
          "type": "string",
          "description": "the anchor date of the regular hours"
        },
        "schedules": {
          "type": "object",
          "properties": {
            "week": {
              "type": "number",
              "description": "which week does the schedule fall in"
            },
            "day": {
              "type": "string",
              "description": "what day is the schedule for"
            },
            "start": {
              "type": "string",
              "description": "what time does the schedule start"
            },
            "end": {
              "type": "string",
              "description": "what time does the schedule finish"
            },
            "breaks": {
              "type": "string",
              "description": "13:00 (string) - what breaks apply to this schedule"
            },
            "department_id": {
              "type": "number",
              "description": "the id of the department the schedule is for"
            }
          },
          "required": [
            "week",
            "day",
            "start",
            "end"
          ],
          "description": "information about the schedules that make up the regular hours of work"
        }
      },
      "required": [
        "start_date"
      ],
      "description": "information about the employees regular hours of work"
    },
    "minimum_base_hours": {
      "type": "number",
      "description": "minimum required hours for this employee"
    },
    "created_at": {
      "type": "number",
      "description": "When the user's Tanda profile was created"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "next_pay_group_id": {
      "type": "number",
      "description": "the ID for the pay group of the user's next timesheet"
    },
    "last_synced_mobile_app": {
      "type": "number",
      "description": "Read only: when the user last opened the mobile app."
    },
    "automatic_break_rule_set_id": {
      "type": "number",
      "description": "Read only: the ID for the user's automatic break rule set."
    },
    "temporary_employee_type": {
      "type": "string",
      "enum": [
        "no_agency",
        "limber"
      ],
      "description": "Type of a temporary employee user. This field only exists if Enable Temporary Staff setting is turned on."
    },
    "position_title": {
      "type": "string",
      "description": "Read only"
    },
    "position_template": {
      "type": "string",
      "description": "Read only"
    },
    "ssn": {
      "type": "string",
      "description": "Read only"
    },
    "enable_login": {
      "type": "boolean"
    }
  },
  "required": [
    "id",
    "name",
    "passcode",
    "platform_role_ids",
    "department_ids",
    "preferred_hours",
    "award_tag_ids",
    "active",
    "utc_offset",
    "created_at"
  ]
}
Headers
Content-Type: application/json
Body
{
  "active": false
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "name": "Lenny Leonard",
  "date_of_birth": "1955-05-12",
  "employment_start_date": "1989-12-17",
  "employee_id": "LL1",
  "passcode": "01234568975461",
  "platform_role_ids": [
    18,
    19,
    22
  ],
  "department_ids": [
    111
  ],
  "preferred_hours": 20,
  "award": {
    "name": "Fast Food Industry",
    "identifier": "MA000003",
    "note": "This field is deprecated, and may be removed in the future. Please rely on the `award_template_organisation_id` field instead."
  },
  "award_template_id": 990,
  "award_template_organisation_id": 5624432,
  "award_tag_ids": [
    3816
  ],
  "report_department_id": 111,
  "managed_department_ids": [
    222
  ],
  "active": false,
  "email": "lenny.leonard@springfieldpowerplant.com",
  "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
  "phone": "0404 123 123",
  "normalised_phone": "+61404123123",
  "salary": 1234.12,
  "hourly_rate": 32.47,
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "part_time_fixed_hours": 20,
  "expected_hours_in_pay_period": 38,
  "days_overtime_averaged_over": 7,
  "overtime_calculated_over_period_start": "2016-09-12",
  "super_fund": {
    "id": 1234,
    "fund_name": "FUND NAME",
    "product_name": "FUND PRODUCT",
    "smsf": false,
    "abn": 123456789
  },
  "super_fund_membership": {
    "super_contribution_type": "arpa",
    "trustee_director": false,
    "member_number": "123ACB",
    "employer_action_date": "2000-01-01T09:30:00+10:00",
    "occupational_rating": "A1",
    "super_fund_id": 1234,
    "employer_preferred": 0,
    "employer_default": 1,
    "employer_generic": 2
  },
  "bank_details": {
    "bsb": 60111,
    "account_number": 12345678,
    "account_name": 0
  },
  "address": {
    "street_line_one": "742 Evergreen Terrace",
    "street_line_two": null,
    "city": "Springfield",
    "state": "Oregon",
    "country": "United States of America",
    "postcode": "97475"
  },
  "tax_declaration": {
    "previous_family_name": "Smith",
    "australian_tax_resident": true,
    "australian_tax_residency_status": "resident",
    "tax_free_threshold": true,
    "senior_tax_offset": false,
    "zone_overseas_carer": false,
    "student_loan": true,
    "financial_supplement_debt": true,
    "tax_code": true,
    "employment_basis": "full_time",
    "student_loan_plans": [
      "uk_loan_plan_1"
    ],
    "uk_tax_year_status": "first_job",
    "tax_file_number": 123456782,
    "tax_scale_type": "regular",
    "income_type": "salary_and_wages",
    "home_country": "",
    "employment_type": "employee",
    "senior_marital_status": "member_of_couple"
  },
  "onboarding_status": "not_applicable, pending, invited, in_progress, completed, invitation_failed",
  "qualifications": [
    {
      "id": 12345,
      "qualification_id": 1234,
      "enabled": true,
      "license_number": "ABC123",
      "expires": "2012-10-20",
      "in_training": false,
      "platform_records": {
        "Proficiency Level": "Level 1 - Beginner"
      }
    }
  ],
  "regular_hours": {
    "start_date": "2021-01-01",
    "schedules": {
      "week": 1,
      "day": "Monday",
      "start": "09:00",
      "end": "17:00",
      "breaks": "12:00",
      "department_id": 1234
    }
  },
  "minimum_base_hours": 20,
  "created_at": 1430715548,
  "record_id": 532432,
  "next_pay_group_id": 53242,
  "last_synced_mobile_app": 1430715548,
  "automatic_break_rule_set_id": 1430715548,
  "temporary_employee_type": "no_agency",
  "position_title": "Bartender",
  "position_template": "Bartender Group",
  "ssn": "123456789"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the user"
    },
    "name": {
      "type": "string",
      "description": "The user's name"
    },
    "date_of_birth": {
      "type": "string",
      "description": "The user's date of birth"
    },
    "employment_start_date": {
      "type": "string",
      "description": "The user's employment start date"
    },
    "employee_id": {
      "type": "string",
      "description": "The user's employee id, used for external systems"
    },
    "passcode": {
      "type": "string",
      "description": "The user's system passcode (used for clocking in and out)"
    },
    "platform_role_ids": {
      "type": "array",
      "description": "IDs of the user's roles (see Access & Roles)"
    },
    "department_ids": {
      "type": "array",
      "description": "The department (team) ids that the user is a member of"
    },
    "preferred_hours": {
      "type": "number",
      "description": "The preferred number of hours to be rostered each week"
    },
    "award": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of the award"
        },
        "identifier": {
          "type": "string",
          "description": "The award's identifier (will be the award code for all modern awards)"
        },
        "note": {
          "type": "string",
          "description": "This field is deprecated, and may be removed in the future. Please rely on the `award_template_organisation_id` field instead."
        }
      },
      "required": [
        "name"
      ],
      "description": "Information about the user's award, null if user isn't on award"
    },
    "award_template_id": {
      "type": "number",
      "description": "The ID of the award template the user is on"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The internal ID of the award template the user is on"
    },
    "award_tag_ids": {
      "type": "array",
      "description": "The award tag ids that apply to the user"
    },
    "report_department_id": {
      "type": "number",
      "description": "The user's default team"
    },
    "managed_department_ids": {
      "type": "array",
      "description": "The department ids that this user manages"
    },
    "active": {
      "type": "boolean",
      "description": "Whether the user is active in the system"
    },
    "email": {
      "type": "string",
      "description": "The user's email"
    },
    "photo": {
      "type": "string",
      "description": "An avatar for the user"
    },
    "phone": {
      "type": "string",
      "description": "Phone number for the user"
    },
    "normalised_phone": {
      "type": "string",
      "description": "Phone number for user with international dialing code"
    },
    "salary": {
      "type": "number",
      "description": "The weekly salary of the user, if `show_wages=true` parameter is set"
    },
    "hourly_rate": {
      "type": "number",
      "description": "The hourly rate of the user, if `show_wages=true` parameter is set, will not show if the salary exists"
    },
    "time_zone": {
      "type": "string",
      "description": "The user's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The user's time zone's UTC offset"
    },
    "part_time_fixed_hours": {
      "type": "number",
      "description": "For part time staff, can be used to configure when overtime starts to apply"
    },
    "expected_hours_in_pay_period": {
      "type": "number",
      "description": "readonly: for salaried staff, defines expected number of hours worked per pay period"
    },
    "days_overtime_averaged_over": {
      "type": "number",
      "description": "date range (weekly, fortnightly, or 4-weekly) over which overtime calculations should run"
    },
    "overtime_calculated_over_period_start": {
      "type": "string",
      "description": "date from which overtime averaging periods should commence"
    },
    "super_fund": {
      "type": "object",
      "properties": {
        "id": {
          "type": "number",
          "description": "the unique ID of the employees fund"
        },
        "fund_name": {
          "type": "string",
          "description": "the name of the fund"
        },
        "product_name": {
          "type": "string",
          "description": "the name of the fund product"
        },
        "smsf": {
          "type": "boolean",
          "description": "is the fund a self managed fund"
        },
        "abn": {
          "type": "number",
          "description": "the number of the fund"
        }
      },
      "description": "information about the employees super fund"
    },
    "super_fund_membership": {
      "type": "object",
      "properties": {
        "super_contribution_type": {
          "type": "string",
          "description": "the type of the employees super contribution"
        },
        "trustee_director": {
          "type": "boolean",
          "description": "is the employees super fund directed by a trustee?"
        },
        "member_number": {
          "type": "string",
          "description": "the membership number of the employees super fund"
        },
        "employer_action_date": {
          "type": "string",
          "description": "the action date of the super fund by the employer"
        },
        "occupational_rating": {
          "type": "string",
          "description": "the occupational rating of the employees super fund"
        },
        "super_fund_id": {
          "type": "number",
          "description": "the record ID of the employees super fund"
        },
        "employer_preferred": {
          "type": "number",
          "description": "indication of an employers preferred super fund"
        },
        "employer_default": {
          "type": "number",
          "description": "indication of an employers default super fund"
        },
        "employer_generic": {
          "type": "number",
          "description": "indication of an employers generic super fund"
        }
      },
      "required": [
        "super_fund_id",
        "employer_preferred",
        "employer_default",
        "employer_generic"
      ],
      "description": "information about the employees super fund membership"
    },
    "bank_details": {
      "type": "object",
      "properties": {
        "bsb": {
          "type": "number",
          "description": "the bsb number of the employees bank account"
        },
        "account_number": {
          "type": "number",
          "description": "the account number of the employees bank account"
        },
        "account_name": {
          "type": "number",
          "description": "the account name of the employees bank account"
        }
      },
      "required": [
        "bsb",
        "account_number",
        "account_name"
      ],
      "description": "the bank details of the employee"
    },
    "address": {
      "type": "object",
      "properties": {
        "street_line_one": {
          "type": "string"
        },
        "street_line_two": {
          "type": [
            "string",
            "null"
          ],
          "description": "Apartment, Suite, etc"
        },
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "state": {
          "type": [
            "string",
            "null"
          ]
        },
        "country": {
          "type": "string"
        },
        "postcode": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "tax_declaration": {
      "type": "object",
      "properties": {
        "previous_family_name": {
          "type": "string",
          "description": "the previous family name of the employee"
        },
        "australian_tax_resident": {
          "type": "boolean",
          "description": "is the user an Australia resident for tax purposes"
        },
        "australian_tax_residency_status": {
          "type": "string"
        },
        "tax_free_threshold": {
          "type": "boolean",
          "description": "is the employee under the tax free threshold?"
        },
        "senior_tax_offset": {
          "type": "boolean",
          "description": "can the employee claim a senior tax offset?"
        },
        "zone_overseas_carer": {
          "type": "boolean",
          "description": "can the employee claim a zone or overseas tax offset?"
        },
        "student_loan": {
          "type": "boolean",
          "description": "does the employee have a student loan?"
        },
        "financial_supplement_debt": {
          "type": "boolean",
          "description": "does the employee have a financial supplement debt?"
        },
        "tax_code": {
          "type": "boolean",
          "description": "the employees code for tax services"
        },
        "employment_basis": {
          "type": "string",
          "enum": [
            "full_time",
            "part_time",
            "casual",
            "labour_hire"
          ],
          "description": "the employment type the employee has specified on their TFN declaration"
        },
        "student_loan_plans": {
          "type": "array",
          "description": "Loan plan type for uk organisations"
        },
        "uk_tax_year_status": {
          "type": "string",
          "enum": [
            "first_job",
            "had_previous_job",
            "second_job"
          ],
          "description": "For uk residents, the stage of the employees career"
        },
        "tax_file_number": {
          "type": "number"
        },
        "tax_scale_type": {
          "type": "string",
          "enum": [
            "regular",
            "horticulturist_or_shearer",
            "senior_or_pensioner",
            "working_holiday_maker"
          ]
        },
        "income_type": {
          "type": "string",
          "enum": [
            "salary_and_wages",
            "working_holiday_maker",
            "non_employee",
            "closely_held_payee",
            "labour_hire"
          ]
        },
        "home_country": {
          "type": "string"
        },
        "employment_type": {
          "type": "string",
          "enum": [
            "employee",
            "contractor"
          ]
        },
        "senior_marital_status": {
          "type": "string",
          "enum": [
            "member_of_couple",
            "member_of_illness_separated_couple",
            "single"
          ]
        }
      },
      "description": "the tax declaration information of the employee"
    },
    "onboarding_status": {
      "type": "string",
      "description": "the status of the employee onboarding progress"
    },
    "qualifications": {
      "type": "array",
      "description": "Information about qualifications the user holds, if Qualifications are enabled"
    },
    "regular_hours": {
      "type": "object",
      "properties": {
        "start_date": {
          "type": "string",
          "description": "the anchor date of the regular hours"
        },
        "schedules": {
          "type": "object",
          "properties": {
            "week": {
              "type": "number",
              "description": "which week does the schedule fall in"
            },
            "day": {
              "type": "string",
              "description": "what day is the schedule for"
            },
            "start": {
              "type": "string",
              "description": "what time does the schedule start"
            },
            "end": {
              "type": "string",
              "description": "what time does the schedule finish"
            },
            "breaks": {
              "type": "string",
              "description": "13:00 (string) - what breaks apply to this schedule"
            },
            "department_id": {
              "type": "number",
              "description": "the id of the department the schedule is for"
            }
          },
          "required": [
            "week",
            "day",
            "start",
            "end"
          ],
          "description": "information about the schedules that make up the regular hours of work"
        }
      },
      "required": [
        "start_date"
      ],
      "description": "information about the employees regular hours of work"
    },
    "minimum_base_hours": {
      "type": "number",
      "description": "minimum required hours for this employee"
    },
    "created_at": {
      "type": "number",
      "description": "When the user's Tanda profile was created"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "next_pay_group_id": {
      "type": "number",
      "description": "the ID for the pay group of the user's next timesheet"
    },
    "last_synced_mobile_app": {
      "type": "number",
      "description": "Read only: when the user last opened the mobile app."
    },
    "automatic_break_rule_set_id": {
      "type": "number",
      "description": "Read only: the ID for the user's automatic break rule set."
    },
    "temporary_employee_type": {
      "type": "string",
      "enum": [
        "no_agency",
        "limber"
      ],
      "description": "Type of a temporary employee user. This field only exists if Enable Temporary Staff setting is turned on."
    },
    "position_title": {
      "type": "string",
      "description": "Read only"
    },
    "position_template": {
      "type": "string",
      "description": "Read only"
    },
    "ssn": {
      "type": "string",
      "description": "Read only"
    }
  },
  "required": [
    "id",
    "name",
    "passcode",
    "platform_role_ids",
    "department_ids",
    "preferred_hours",
    "award_tag_ids",
    "active",
    "utc_offset",
    "created_at"
  ]
}
Headers
Content-Type: application/json
Body
{
  "department_ids": null
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "name": "Lenny Leonard",
  "date_of_birth": "1955-05-12",
  "employment_start_date": "1989-12-17",
  "employment_end_date": "2019-06-01",
  "employee_id": "LL1",
  "passcode": "0456",
  "department_ids": [],
  "preferred_hours": 20,
  "award_template_id": 990,
  "award_tag_ids": [
    3816
  ],
  "report_department_id": 111,
  "managed_department_ids": [
    222
  ],
  "active": true,
  "enable_login": true,
  "can_see_costs": true,
  "email": "lenny.leonard@springfieldpowerplant.com",
  "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
  "phone": "0404 123 123",
  "normalised_phone": "+61404123123",
  "salary": 1234.12,
  "hourly_rate": 32.47,
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "created_at": 1430715548
  "part_time_fixed_hours": 20,
  "expected_hours_in_pay_period": 38,
  "days_overtime_averaged_over": 7,
  "overtime_calculated_over_period_start": "2016-09-12",
  "super_fund_membership": null,
  "super_fund": null,
  "bank_details": null,
  "tax_declaration": null,
  "qualifications": [],
  "updated_at": 1562272900
}
Headers
Content-Type: application/json
Body
{
  "regular_hours": {
    "start_date": "2021-01-01",
    "schedules": [
      {
        "week": 1,
        "day": "Monday",
        "start": "09:00",
        "end": "17:00",
        "department_id": 1234,
        "breaks": "12:00-13:00"
      }
    ]
  }
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "name": "Lenny Leonard",
  "date_of_birth": "1955-05-12",
  "employment_start_date": "1989-12-17",
  "employment_end_date": "2019-06-01",
  "employee_id": "LL1",
  "passcode": "0456",
  "department_ids": [],
  "preferred_hours": 20,
  "award_template_id": 990,
  "award_tag_ids": [
    3816
  ],
  "report_department_id": 111,
  "managed_department_ids": [
    222
  ],
  "active": true,
  "enable_login": true,
  "can_see_costs": true,
  "email": "lenny.leonard@springfieldpowerplant.com",
  "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
  "phone": "0404 123 123",
  "normalised_phone": "+61404123123",
  "salary": 1234.12,
  "hourly_rate": 32.47,
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "created_at": 1430715548
  "part_time_fixed_hours": 20,
  "expected_hours_in_pay_period": 38,
  "days_overtime_averaged_over": 7,
  "overtime_calculated_over_period_start": "2016-09-12",
  "super_fund_membership": null,
  "super_fund": null,
  "bank_details": null,
  "temporary_employee_type": null,
  "tax_declaration": null,
  "qualifications": [],
  "regular_hours": {
    "start_date": "2021-01-01",
    "schedules": [
      {
        "week": 1,
        "day": "Monday",
        "start": "09:00",
        "end": "17:00",
        "department_id": 1234,
        "breaks": "12:00-13:00"
      }
    ]
  },
  "updated_at": 1562272900
}

Update User
PUT/api/v2/users/{id}

This method requires the user scope (see Scopes for more information).

If you plan to update wage information you will need the cost scope. This includes the employee_id field.

To set financial information, you will need the financial scope.

Notes

  • To skip email validation when creating a user, use skip_validation=true.

  • The UUID for uploading a file_id to a qualification can be found at the create temporary file endpoint.

  • If you are attempting to remove a user’s department_ids or managed_department_ids, you should pass null as part of your API call. There is an example in the sidebar.

  • The API currently requires email addresses to be unique within an organisation. However, there is no guarantee that this restriction will exist in the future. If you are updating a user’s email via the API you should first GET a list of users and validate that the email you’re setting isn’t already in use - do not depend on the API to validate this for you.

  • It’s not possible to remove a user’s passcode. If you pass null as a value for it, the user’s passcode will be regenerated.

  • Updating a Tax File Number requires the financial scope. Valid values for a Tax File Number are 8 or 9 numeric characters, or an exemption: exempt_underage | exempt_applied | exempt_allowance | exempt_blank (TFN intentionally withheld). Only the current user can view their TFN via the API; that is, you can POST/PUT a TFN but cannot read it except for your own user record. If you POST/PUT an invalid TFN you’ll get a validation error.

URI Parameters
HideShow
id
number (required) Example: 123456

The id of the user

skip_validation
boolean (optional) Example: true

Skip’s checking if an employee already exists with this email address


DELETE https://my.tanda.co/api/v2/users/654321
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "name": "Lenny Leonard",
  "date_of_birth": "1955-05-12",
  "employment_start_date": "1989-12-17",
  "employee_id": "LL1",
  "passcode": "01234568975461",
  "platform_role_ids": [
    18,
    19,
    22
  ],
  "department_ids": [
    111
  ],
  "preferred_hours": 20,
  "award": {
    "name": "Fast Food Industry",
    "identifier": "MA000003",
    "note": "This field is deprecated, and may be removed in the future. Please rely on the `award_template_organisation_id` field instead."
  },
  "award_template_id": 990,
  "award_template_organisation_id": 5624432,
  "award_tag_ids": [
    3816
  ],
  "report_department_id": 111,
  "managed_department_ids": [
    222
  ],
  "active": false,
  "email": "lenny.leonard@springfieldpowerplant.com",
  "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
  "phone": "0404 123 123",
  "normalised_phone": "+61404123123",
  "salary": 1234.12,
  "hourly_rate": 32.47,
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "part_time_fixed_hours": 20,
  "expected_hours_in_pay_period": 38,
  "days_overtime_averaged_over": 7,
  "overtime_calculated_over_period_start": "2016-09-12",
  "super_fund": {
    "id": 1234,
    "fund_name": "FUND NAME",
    "product_name": "FUND PRODUCT",
    "smsf": false,
    "abn": 123456789
  },
  "super_fund_membership": {
    "super_contribution_type": "arpa",
    "trustee_director": false,
    "member_number": "123ACB",
    "employer_action_date": "2000-01-01T09:30:00+10:00",
    "occupational_rating": "A1",
    "super_fund_id": 1234,
    "employer_preferred": 0,
    "employer_default": 1,
    "employer_generic": 2
  },
  "bank_details": {
    "bsb": 60111,
    "account_number": 12345678,
    "account_name": 0
  },
  "address": {
    "street_line_one": "742 Evergreen Terrace",
    "street_line_two": null,
    "city": "Springfield",
    "state": "Oregon",
    "country": "United States of America",
    "postcode": "97475"
  },
  "tax_declaration": {
    "previous_family_name": "Smith",
    "australian_tax_resident": true,
    "australian_tax_residency_status": "resident",
    "tax_free_threshold": true,
    "senior_tax_offset": false,
    "zone_overseas_carer": false,
    "student_loan": true,
    "financial_supplement_debt": true,
    "tax_code": true,
    "employment_basis": "full_time",
    "student_loan_plans": [
      "uk_loan_plan_1"
    ],
    "uk_tax_year_status": "first_job",
    "tax_file_number": 123456782,
    "tax_scale_type": "regular",
    "income_type": "salary_and_wages",
    "home_country": "",
    "employment_type": "employee",
    "senior_marital_status": "member_of_couple"
  },
  "onboarding_status": "not_applicable, pending, invited, in_progress, completed, invitation_failed",
  "qualifications": [
    {
      "id": 12345,
      "qualification_id": 1234,
      "enabled": true,
      "license_number": "ABC123",
      "expires": "2012-10-20",
      "in_training": false,
      "platform_records": {
        "Proficiency Level": "Level 1 - Beginner"
      }
    }
  ],
  "regular_hours": {
    "start_date": "2021-01-01",
    "schedules": {
      "week": 1,
      "day": "Monday",
      "start": "09:00",
      "end": "17:00",
      "breaks": "12:00",
      "department_id": 1234
    }
  },
  "minimum_base_hours": 20,
  "created_at": 1430715548,
  "record_id": 532432,
  "next_pay_group_id": 53242,
  "last_synced_mobile_app": 1430715548,
  "automatic_break_rule_set_id": 1430715548,
  "temporary_employee_type": "no_agency",
  "position_title": "Bartender",
  "position_template": "Bartender Group",
  "ssn": "123456789"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the user"
    },
    "name": {
      "type": "string",
      "description": "The user's name"
    },
    "date_of_birth": {
      "type": "string",
      "description": "The user's date of birth"
    },
    "employment_start_date": {
      "type": "string",
      "description": "The user's employment start date"
    },
    "employee_id": {
      "type": "string",
      "description": "The user's employee id, used for external systems"
    },
    "passcode": {
      "type": "string",
      "description": "The user's system passcode (used for clocking in and out)"
    },
    "platform_role_ids": {
      "type": "array",
      "description": "IDs of the user's roles (see Access & Roles)"
    },
    "department_ids": {
      "type": "array",
      "description": "The department (team) ids that the user is a member of"
    },
    "preferred_hours": {
      "type": "number",
      "description": "The preferred number of hours to be rostered each week"
    },
    "award": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of the award"
        },
        "identifier": {
          "type": "string",
          "description": "The award's identifier (will be the award code for all modern awards)"
        },
        "note": {
          "type": "string",
          "description": "This field is deprecated, and may be removed in the future. Please rely on the `award_template_organisation_id` field instead."
        }
      },
      "required": [
        "name"
      ],
      "description": "Information about the user's award, null if user isn't on award"
    },
    "award_template_id": {
      "type": "number",
      "description": "The ID of the award template the user is on"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The internal ID of the award template the user is on"
    },
    "award_tag_ids": {
      "type": "array",
      "description": "The award tag ids that apply to the user"
    },
    "report_department_id": {
      "type": "number",
      "description": "The user's default team"
    },
    "managed_department_ids": {
      "type": "array",
      "description": "The department ids that this user manages"
    },
    "active": {
      "type": "boolean",
      "description": "Whether the user is active in the system"
    },
    "email": {
      "type": "string",
      "description": "The user's email"
    },
    "photo": {
      "type": "string",
      "description": "An avatar for the user"
    },
    "phone": {
      "type": "string",
      "description": "Phone number for the user"
    },
    "normalised_phone": {
      "type": "string",
      "description": "Phone number for user with international dialing code"
    },
    "salary": {
      "type": "number",
      "description": "The weekly salary of the user, if `show_wages=true` parameter is set"
    },
    "hourly_rate": {
      "type": "number",
      "description": "The hourly rate of the user, if `show_wages=true` parameter is set, will not show if the salary exists"
    },
    "time_zone": {
      "type": "string",
      "description": "The user's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The user's time zone's UTC offset"
    },
    "part_time_fixed_hours": {
      "type": "number",
      "description": "For part time staff, can be used to configure when overtime starts to apply"
    },
    "expected_hours_in_pay_period": {
      "type": "number",
      "description": "readonly: for salaried staff, defines expected number of hours worked per pay period"
    },
    "days_overtime_averaged_over": {
      "type": "number",
      "description": "date range (weekly, fortnightly, or 4-weekly) over which overtime calculations should run"
    },
    "overtime_calculated_over_period_start": {
      "type": "string",
      "description": "date from which overtime averaging periods should commence"
    },
    "super_fund": {
      "type": "object",
      "properties": {
        "id": {
          "type": "number",
          "description": "the unique ID of the employees fund"
        },
        "fund_name": {
          "type": "string",
          "description": "the name of the fund"
        },
        "product_name": {
          "type": "string",
          "description": "the name of the fund product"
        },
        "smsf": {
          "type": "boolean",
          "description": "is the fund a self managed fund"
        },
        "abn": {
          "type": "number",
          "description": "the number of the fund"
        }
      },
      "description": "information about the employees super fund"
    },
    "super_fund_membership": {
      "type": "object",
      "properties": {
        "super_contribution_type": {
          "type": "string",
          "description": "the type of the employees super contribution"
        },
        "trustee_director": {
          "type": "boolean",
          "description": "is the employees super fund directed by a trustee?"
        },
        "member_number": {
          "type": "string",
          "description": "the membership number of the employees super fund"
        },
        "employer_action_date": {
          "type": "string",
          "description": "the action date of the super fund by the employer"
        },
        "occupational_rating": {
          "type": "string",
          "description": "the occupational rating of the employees super fund"
        },
        "super_fund_id": {
          "type": "number",
          "description": "the record ID of the employees super fund"
        },
        "employer_preferred": {
          "type": "number",
          "description": "indication of an employers preferred super fund"
        },
        "employer_default": {
          "type": "number",
          "description": "indication of an employers default super fund"
        },
        "employer_generic": {
          "type": "number",
          "description": "indication of an employers generic super fund"
        }
      },
      "required": [
        "super_fund_id",
        "employer_preferred",
        "employer_default",
        "employer_generic"
      ],
      "description": "information about the employees super fund membership"
    },
    "bank_details": {
      "type": "object",
      "properties": {
        "bsb": {
          "type": "number",
          "description": "the bsb number of the employees bank account"
        },
        "account_number": {
          "type": "number",
          "description": "the account number of the employees bank account"
        },
        "account_name": {
          "type": "number",
          "description": "the account name of the employees bank account"
        }
      },
      "required": [
        "bsb",
        "account_number",
        "account_name"
      ],
      "description": "the bank details of the employee"
    },
    "address": {
      "type": "object",
      "properties": {
        "street_line_one": {
          "type": "string"
        },
        "street_line_two": {
          "type": [
            "string",
            "null"
          ],
          "description": "Apartment, Suite, etc"
        },
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "state": {
          "type": [
            "string",
            "null"
          ]
        },
        "country": {
          "type": "string"
        },
        "postcode": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "tax_declaration": {
      "type": "object",
      "properties": {
        "previous_family_name": {
          "type": "string",
          "description": "the previous family name of the employee"
        },
        "australian_tax_resident": {
          "type": "boolean",
          "description": "is the user an Australia resident for tax purposes"
        },
        "australian_tax_residency_status": {
          "type": "string"
        },
        "tax_free_threshold": {
          "type": "boolean",
          "description": "is the employee under the tax free threshold?"
        },
        "senior_tax_offset": {
          "type": "boolean",
          "description": "can the employee claim a senior tax offset?"
        },
        "zone_overseas_carer": {
          "type": "boolean",
          "description": "can the employee claim a zone or overseas tax offset?"
        },
        "student_loan": {
          "type": "boolean",
          "description": "does the employee have a student loan?"
        },
        "financial_supplement_debt": {
          "type": "boolean",
          "description": "does the employee have a financial supplement debt?"
        },
        "tax_code": {
          "type": "boolean",
          "description": "the employees code for tax services"
        },
        "employment_basis": {
          "type": "string",
          "enum": [
            "full_time",
            "part_time",
            "casual",
            "labour_hire"
          ],
          "description": "the employment type the employee has specified on their TFN declaration"
        },
        "student_loan_plans": {
          "type": "array",
          "description": "Loan plan type for uk organisations"
        },
        "uk_tax_year_status": {
          "type": "string",
          "enum": [
            "first_job",
            "had_previous_job",
            "second_job"
          ],
          "description": "For uk residents, the stage of the employees career"
        },
        "tax_file_number": {
          "type": "number"
        },
        "tax_scale_type": {
          "type": "string",
          "enum": [
            "regular",
            "horticulturist_or_shearer",
            "senior_or_pensioner",
            "working_holiday_maker"
          ]
        },
        "income_type": {
          "type": "string",
          "enum": [
            "salary_and_wages",
            "working_holiday_maker",
            "non_employee",
            "closely_held_payee",
            "labour_hire"
          ]
        },
        "home_country": {
          "type": "string"
        },
        "employment_type": {
          "type": "string",
          "enum": [
            "employee",
            "contractor"
          ]
        },
        "senior_marital_status": {
          "type": "string",
          "enum": [
            "member_of_couple",
            "member_of_illness_separated_couple",
            "single"
          ]
        }
      },
      "description": "the tax declaration information of the employee"
    },
    "onboarding_status": {
      "type": "string",
      "description": "the status of the employee onboarding progress"
    },
    "qualifications": {
      "type": "array",
      "description": "Information about qualifications the user holds, if Qualifications are enabled"
    },
    "regular_hours": {
      "type": "object",
      "properties": {
        "start_date": {
          "type": "string",
          "description": "the anchor date of the regular hours"
        },
        "schedules": {
          "type": "object",
          "properties": {
            "week": {
              "type": "number",
              "description": "which week does the schedule fall in"
            },
            "day": {
              "type": "string",
              "description": "what day is the schedule for"
            },
            "start": {
              "type": "string",
              "description": "what time does the schedule start"
            },
            "end": {
              "type": "string",
              "description": "what time does the schedule finish"
            },
            "breaks": {
              "type": "string",
              "description": "13:00 (string) - what breaks apply to this schedule"
            },
            "department_id": {
              "type": "number",
              "description": "the id of the department the schedule is for"
            }
          },
          "required": [
            "week",
            "day",
            "start",
            "end"
          ],
          "description": "information about the schedules that make up the regular hours of work"
        }
      },
      "required": [
        "start_date"
      ],
      "description": "information about the employees regular hours of work"
    },
    "minimum_base_hours": {
      "type": "number",
      "description": "minimum required hours for this employee"
    },
    "created_at": {
      "type": "number",
      "description": "When the user's Tanda profile was created"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "next_pay_group_id": {
      "type": "number",
      "description": "the ID for the pay group of the user's next timesheet"
    },
    "last_synced_mobile_app": {
      "type": "number",
      "description": "Read only: when the user last opened the mobile app."
    },
    "automatic_break_rule_set_id": {
      "type": "number",
      "description": "Read only: the ID for the user's automatic break rule set."
    },
    "temporary_employee_type": {
      "type": "string",
      "enum": [
        "no_agency",
        "limber"
      ],
      "description": "Type of a temporary employee user. This field only exists if Enable Temporary Staff setting is turned on."
    },
    "position_title": {
      "type": "string",
      "description": "Read only"
    },
    "position_template": {
      "type": "string",
      "description": "Read only"
    },
    "ssn": {
      "type": "string",
      "description": "Read only"
    }
  },
  "required": [
    "id",
    "name",
    "passcode",
    "platform_role_ids",
    "department_ids",
    "preferred_hours",
    "award_tag_ids",
    "active",
    "utc_offset",
    "created_at"
  ]
}

Delete User
DELETE/api/v2/users/{id}

This endpoint will just mark the user as inactive and return the user, this effectively does the same as the deactivate user request above.

This method requires the user scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 654321

The id of the user


Invite Users

POST https://my.tanda.co/api/v2/users/654321/invite
Responses201
Headers
Content-Type: application/json

Invite User
POST/api/v2/users/{id}/invite

This endpoint takes a user ID and sends that user an email invite to use Tanda.

This method requires the user scope (see Scopes for more information).

It also requires the following prerequisites to work

  • User must exist

  • You must be able to manage the User

  • The User must have an email and it must be valid

  • The User must not have already signed up

  • The User must not already have a valid invitation

Failure to meet these pre reqs will result in a returned 400, 403 or 404. Otherwise a 201 CREATED will be returned

URI Parameters
HideShow
id
number (required) Example: 654321

The id of the user


Invite New Users for Onboarding

POST https://my.tanda.co/api/v2/users/onboarding
RequestsCreate User for Onboarding
Headers
Content-Type: application/json
Body
{
  "name": "Eddard Sheppard",
  "email": "carl.carlson@springfieldpowerplant.com",
  "phone": "+61408123654",
  "custom_message": "Welcome to the company!"
}
Responses201
Headers
Content-Type: application/json

Invite User for Onboarding
POST/api/v2/users/onboarding

If you are using Tanda’s employee onboarding, you can use this endpoint to automatically invite new staff to be onboarded. It takes a name and email, and optionally a phone number and custom message, and sends the employee a link to a form where they can add their details.


Invite Existing User for Onboarding

POST https://my.tanda.co/api/v2/users/123456/onboard
Responses201
Headers
Content-Type: application/json

Invite Existing User for Onboarding
POST/api/v2/users/{id}/onboard

If you have created a new user with the Create User endpoint and are using Tanda’s employee onboarding, you can use this endpoint to trigger the onboarding process for the new user.

This endpoint is intended only for brand new users created from the Create User endpoint. If the user has already been invited to Tanda you cannot use this endpoint.

URI Parameters
HideShow
id
number (required) Example: 123456

The id of the user


Clocked In Users

GET https://my.tanda.co/api/v2/users/clocked_in
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "user_id": 123456,
    "shift_id": 1337
  }
]

Get Clocked In Users
GET/api/v2/users/clocked_in

This endpoint is deprecated. You should use /shifts/active instead.

Gets a list of staff who are currently at work. Essentially this looks for valid shifts that have a start time but no end time. The shift’s ID is also returned.

This method requires the user and timesheet scopes (see Scopes for more information).

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified users


User Versions

GET https://my.tanda.co/api/v2/users/123456/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"User\"",
    "changes": [
      {
        "field": "name",
        "previous": "Lenny L Leonard",
        "updated": "Lenny Leonard"
      },
      {
        "field": "preferred_hours",
        "previous": 28,
        "updated": 20
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get User Versions
GET/api/v2/users/{id}/versions

This method requires the user scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123456

The id of the user

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified user versions


Alternate Rates

Alternate Rates are user level assigned hourly rates based on team.

Note: employment_contract_id is an optional param for all Alternate Rate endpoints.

If no employment_contract_id is included, the endpoint will refrence the latest employment contract.

These endpoint actions require Allow Additional Rates to be enabled under your organisation’s feature management settings.

GET https://my.tanda.co/api/v2/users/162456/alternate_rates
Responses200
Headers
Content-Type: application/json
Body
{
  "alternate_rates": [
    {
      "department_id": "123456",
      "hourly_rate": "20.01"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "alternate_rates": {
      "type": "array"
    }
  }
}

Get Alternate Rates
GET/api/v2/users/{id}/alternate_rates

This method requires the user scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162456

The ID of an user

employment_contract_id
number (optional) Example: 162456

The ID of an user’s employment contract


PUT https://my.tanda.co/api/v2/users/123456/alternate_rates
RequestsAlternate Rates
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "employment_contract_id": 987654,
  "alternate_rates": [
    {"department_id": 987654, "hourly_rate": 20.01},
    {"department_id": 987653, "hourly_rate": 7.99},
    {"department_id": 987652, "hourly_rate": 8},
    ]
}
Responses201
Headers
Content-Type: application/json
Body
{
  "alternate_rates": [
    {
      "department_id": "123456",
      "hourly_rate": "20.01"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "alternate_rates": {
      "type": "array"
    }
  }
}

Update Alternate Rates
PUT/api/v2/users/{id}/alternate_rates

To Create and update a user’s alternate rate(s) data, include the user’s id and alternate_rates array.

Note: Alternate rates can only be assigned to teams that are scope to the user. Also only one alternate rate can be assigned per team and the rate must be different from the user’s base hourly rate.

This method requires the user scope (see Scopes for more information).

Successfully using this endpoint will overwrite all existing alternate rates for the user.

URI Parameters
HideShow
id
number (required) Example: 123456

The ID of an user

employment_contract_id
number (optional) Example: 162456

The ID of an user’s employment contract

alternate_rates
array (required) 
object
object (required) Example: {"department_id": 987654, "hourly_rate": 20.01}

department_id: (required, number) - The ID of a department/team the user works in hourly_rate: (required, number) - The hourly rate this user will be paid for working in this team


DELETE https://my.tanda.co/api/v2/users/162456/alternate_rates
Responses200
Headers
Content-Type: application/json
Body
{
  "message": "Successfully deleted all alternate rates"
}

Delete Alternate Rates
DELETE/api/v2/users/{id}/alternate_rates

This method requires the user scope (see Scopes for more information).

This method will delete ALL alternate rates for the user.

URI Parameters
HideShow
id
number (required) Example: 162456

The ID of an user

employment_contract_id
number (optional) Example: 162456

The ID of an user’s employment contract


Employee Pay Fields

There are no special system permissions required. To access most of these endpoints, you will need the cost scope for your api token. The user the token is generated for must also have custom permissions edit_wages on for the staff members they wish to edit pay fields for.

Employee Payfields

GET https://my.tanda.co/api/v2/user_pay_fields
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 12345,
    "reason_for_change": "Pay Fields Update Jan 2022",
    "from_date": "1970-1-1",
    "to_date": "1970-1-1",
    "hourly_rate": 0,
    "yearly_salary": 60000,
    "user_id": 12345,
    "award_template_organisation_id": 12345
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Payfields For All Users
GET/api/v2/user_pay_fields

Retrieves all pay field objects belonging to the users of the organisation. This endpoint can be paginated.

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
page
number (optional) Example: 1

The page number for your pay fields list

page_size
number (optional) Example: 50

The number of pay field objects retrieved per page. The maximum is 100 per page.


Get Payfields By Known ID

GET https://my.tanda.co/api/v2/user_pay_fields/54321
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 12345,
  "reason_for_change": "Pay Fields Update Jan 2022",
  "from_date": "1970-1-1",
  "to_date": "1970-1-1",
  "hourly_rate": 0,
  "yearly_salary": 60000,
  "user_id": 12345,
  "award_template_organisation_id": 12345
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the payfield"
    },
    "reason_for_change": {
      "type": "string",
      "description": "The name of a pay field change, usually specifying the reason."
    },
    "from_date": {
      "type": "string",
      "description": "The effective date that the grouping of payfields applies after"
    },
    "to_date": {
      "type": "string",
      "description": "The effective date that the grouping of payfields applies until"
    },
    "hourly_rate": {
      "type": "number",
      "description": "Hourly rate of the employee for the effective date"
    },
    "yearly_salary": {
      "type": "number",
      "description": "Yearly Salary of the employee for the effective date"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user these payfields apply to"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The id of the award template organisation that is attached to this user"
    }
  }
}

Get Payfields By Payfield ID
GET/api/v2/user_pay_fields/{id}

Retrieves one pay field object by it’s unique id.

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 54321

The id of the payfield


Employee Payfields By User

GET https://my.tanda.co/api/v2/user_pay_fields/user/654321
Responses201
Headers
Content-Type: application/json
Body
[
  {
    "id": 12345,
    "reason_for_change": "Pay Fields Update Jan 2022",
    "from_date": "1970-1-1",
    "to_date": "1970-1-1",
    "hourly_rate": 0,
    "yearly_salary": 60000,
    "user_id": 12345,
    "award_template_organisation_id": 12345
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Payfields By User
GET/api/v2/user_pay_fields/user/{user_id}

This endpoint takes a user ID and returns an array of all the users pay field objects.

This method requires the cost scope (see Scopes for more information).

It also requires the following prerequisites to work

  • User must exist

Failure to meet these pre reqs will result in a returned 400, 403 or 404. Otherwise an array of UserPayFieldData will be returned

URI Parameters
HideShow
user_id
number (required) Example: 654321

The id of the user


Verify Employee Payfields By User

GET https://my.tanda.co/api/v2/user_pay_fields/user/654321/verify
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 12345,
    "from": {
      "date": "2022-01-01",
      "valid": true
    },
    "to": {
      "date": "2023-01-01",
      "valid": true
    },
    "errors": [
      "Something is wrong",
      "Something else is wrong"
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Verify Payfields By User
GET/api/v2/user_pay_fields/user/{user_id}/verify

This endpoint conducts a check on a specific user’s pay field records. The check will ensure correct sequence of dates, and return any errors that might be evident.

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
user_id
number (required) Example: 654321

The id of the user


Updating Pay Fields

PUT https://my.tanda.co/api/v2/user_pay_fields/54321
RequestsUpdate Payfield
Headers
Content-Type: application/json
Body
{
  "id": 54321,
  "user_id": 654321,
  "from_date": "1970-1-1",
  "to_date": "2020-1-1",
  "hourly_rate": 0,
  "award_tags": "Casual,Level 1",
  "yearly_salary": 60000,
  "award_template_organisation_id": 12345
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 12345,
  "reason_for_change": "Pay Fields Update Jan 2022",
  "from_date": "1970-1-1",
  "to_date": "1970-1-1",
  "hourly_rate": 0,
  "yearly_salary": 60000,
  "user_id": 12345,
  "award_template_organisation_id": 12345
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the payfield"
    },
    "reason_for_change": {
      "type": "string",
      "description": "The name of a pay field change, usually specifying the reason."
    },
    "from_date": {
      "type": "string",
      "description": "The effective date that the grouping of payfields applies after"
    },
    "to_date": {
      "type": "string",
      "description": "The effective date that the grouping of payfields applies until"
    },
    "hourly_rate": {
      "type": "number",
      "description": "Hourly rate of the employee for the effective date"
    },
    "yearly_salary": {
      "type": "number",
      "description": "Yearly Salary of the employee for the effective date"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user these payfields apply to"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The id of the award template organisation that is attached to this user"
    }
  }
}

Update Payfield
PUT/api/v2/user_pay_fields/{id}

Update a specific param for a single payfield entry.

This method requires a id to be given.

This method requires the cost scope (see Scopes for more information).

You do not have to provide every pay field in the request body.

The ones you do provide will form the new value of the updated pay field object.

The only limitation to updating behaviour is - you cannot update a user’s first pay field object’s from_date.

You can identify which pay field object is the first by it’s from date. This should be represented as start.

URI Parameters
HideShow
id
number (required) Example: 54321

The ID of payfield entry.


Creating Pay Fields

POST https://my.tanda.co/api/v2/user_pay_fields
RequestsCreate Payfield
Headers
Content-Type: application/json
Body
{
  "user_id": 654321,
  "from_date": "1970-1-1",
  "to_date": "2020-1-1",
  "hourly_rate": 0,
  "award_tags": "Casual,Level 1",
  "yearly_salary": 60000,
  "award_template_organisation_id": 12345
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 12345,
  "reason_for_change": "Pay Fields Update Jan 2022",
  "from_date": "1970-1-1",
  "to_date": "1970-1-1",
  "hourly_rate": 0,
  "yearly_salary": 60000,
  "user_id": 12345,
  "award_template_organisation_id": 12345
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the payfield"
    },
    "reason_for_change": {
      "type": "string",
      "description": "The name of a pay field change, usually specifying the reason."
    },
    "from_date": {
      "type": "string",
      "description": "The effective date that the grouping of payfields applies after"
    },
    "to_date": {
      "type": "string",
      "description": "The effective date that the grouping of payfields applies until"
    },
    "hourly_rate": {
      "type": "number",
      "description": "Hourly rate of the employee for the effective date"
    },
    "yearly_salary": {
      "type": "number",
      "description": "Yearly Salary of the employee for the effective date"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user these payfields apply to"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The id of the award template organisation that is attached to this user"
    }
  }
}

Create Payfield
POST/api/v2/user_pay_fields

user_id and from_date are all that are required in the request body to create a new payfield entry.

If no to_date is provided as a parameter, this payfield record will apply forever.


Managing Multiple Pay Fields

POST https://my.tanda.co/api/v2/user_pay_fields/654321
RequestsCreate / Update Pay Fieds
Headers
Content-Type: application/json
Body
{
  "pay_fields": [
    {
      "id": 654321,
      "regular_hours": "Pay Increase Jan 2022",
      "from_date": "2020-1-1",
      "to_date": "2021-1-1",
      "hourly_rate": 0,
      "award_tags": "Casual,Level 1",
      "yearly_salary": 60000,
      "award_template_organisation_id": 12345
    }
  ]
}
Responses201
Headers
Content-Type: application/json
Body
[
  {
    "id": 12345,
    "reason_for_change": "Pay Fields Update Jan 2022",
    "from_date": "1970-1-1",
    "to_date": "1970-1-1",
    "hourly_rate": 0,
    "yearly_salary": 60000,
    "user_id": 12345,
    "award_template_organisation_id": 12345
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Create & Update Multiple Pay Fields For A User
POST/api/v2/user_pay_fields/{user_id}

This endpoint can be used through a POST request to manage a specific user’s pay field objects in bulk.

This method requires a user_id to be given.

This method requires the cost scope (see Scopes for more information).

You do not have to provide every pay field in the request body. The ones you do provide will form the new value of the updated pay field object.

The only limitation to updating behaviour is - you cannot update a user’s first pay field object’s from_date. You can identify which pay field object is the first by it’s from date. This should be represented as start.

If you provide an id to a pay field object in the array, the request will look for the existing record and update the corresponding fields. You must provide a valid id in doing so. The whole request will fail there is a non-existent pay field id.

If you do not provide an id to a pay field object in the array, the request will create a new pay field record for the user. It will create the record with the provided fields.

URI Parameters
HideShow
user_id
number (required) Example: 654321

The ID of the user


Deleting Pay Fields

DELETE https://my.tanda.co/api/v2/user_pay_fields/54321
RequestsDelete Payfield
Headers
Content-Type: application/json
Body
{
  "id": 54321
}
Responses201
Headers
Content-Type: application/json

Delete Payfield By Id
DELETE/api/v2/user_pay_fields/{id}

Delete a specific payfield entry.

This method requires a id to be given.

You cannot remove the earliest payfield record; There should ALWAYS be a single payfield record. If this isn’t the case, costing and award interpretation will not work as intended.

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 54321

The ID of payfield entry.


Locations

Admins and general managers can CRUD locations. Team managers can read locations which contain teams they manage.

Location List

GET https://my.tanda.co/api/v2/locations?updated_after=1451570400&platform=false&show_business_hours=false
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 111,
    "name": "Springfield",
    "short_name": "S",
    "latitude": -27.459687,
    "longitude": 153.032108,
    "address": "Springfield Powerplant Reactors",
    "time_zone": "Australia/Brisbane",
    "utc_offset": 36000,
    "public_holiday_regions": [
      "au",
      "au_qld"
    ],
    "specific_holiday_dates": [
      {
        "date": "2016-08-08",
        "from": 8,
        "to": 17
      }
    ],
    "business_day_cutoff": 5,
    "business_hours": [
      {
        "weekday": 0,
        "start": "8:30",
        "finish": "17:00"
      }
    ],
    "record_id": 532432
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Locations
GET/api/v2/locations{?updated_after,platform,show_business_hours}

This method requires the department scope (see Scopes for more information).

For business hours data, weekday ‘0’ is Sunday, ‘1’ is Monday, with the rest following that order till ‘6’ which ends on Saturday.

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified locations

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false).

show_business_hours
boolean (optional) Example: false

If true, business hours will be returned (defaults to false).


POST https://my.tanda.co/api/v2/locations
RequestsCreate LocationCreate basic Location
Headers
Content-Type: application/json
Body
{
  "name": "Springfield",
  "short_name": "S",
  "latitude": -27.467004,
  "longitude": 153.025453,
  "address": "Springfield Powerplant Logistics Centre",
  "public_holiday_regions": [
    "au"
  ],
  "specific_holiday_dates": [
    {
      "date": "2016-03-14"
    },
    {
      "date": "2016-08-08",
      "from": 12,
      "to": 17
    }
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 801,
  "name": "Springfield",
  "short_name": "S",
  "latitude": -27.467004,
  "longitude": 153.025453,
  "address": "Springfield Powerplant Logistics Centre",
  "time_zone": null,
  "organisation_id": 12,
  "public_holiday_regions": [
    "au"
  ],
  "specific_holiday_dates": [
    {
      "date": "2016-03-14"
    },
    {
      "date": "2016-08-08",
      "from": 12,
      "to": 17
    }
  ],
  "business_day_cutoff": 0
}
Headers
Content-Type: application/json
Body
{
  "name": "Springfield"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 801,
  "name": "Springfield",
  "short_name": null,
  "latitude": null,
  "longitude": null,
  "address": null,
  "time_zone": null,
  "organisation_id": 12,
  "public_holiday_regions": [],
  "specific_holiday_dates": [],
  "business_day_cutoff": 0
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the location"
    },
    "name": {
      "type": "string",
      "description": "The name of the location"
    },
    "short_name": {
      "type": "string",
      "description": "The abbreviated form of the location's name"
    },
    "latitude": {
      "type": "number",
      "description": "The latitude of the location"
    },
    "longitude": {
      "type": "number",
      "description": "The longitude of the location"
    },
    "address": {
      "type": "string",
      "description": "Address of the location"
    },
    "time_zone": {
      "type": "string",
      "description": "The location's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The location's time zone's UTC offset"
    },
    "public_holiday_regions": {
      "type": "array",
      "description": "Public holiday regions (see Locations section for list of options)"
    },
    "specific_holiday_dates": {
      "type": "array",
      "description": "The dates and times of specific holidays for the location"
    },
    "business_day_cutoff": {
      "type": "number",
      "description": "The hour of the day before which data should be treated as being part of the previous day. eg 5 indicates that data from before 5am is part of the previous business day."
    },
    "business_hours": {
      "type": "array",
      "description": "The business hours of the location"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "name",
    "time_zone",
    "utc_offset"
  ]
}

Create Location
POST/api/v2/locations

Use this endpoint to create a Location object. Location objects should have addresses, but the field is not mandatory - you can create a Location with just a name (though it will not be as useful).

If an address is provided, latitude and longitude are also required.

This method requires the department scope (see Scopes for more information).


Location

GET https://my.tanda.co/api/v2/locations/111
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 111,
  "name": "Springfield",
  "short_name": "S",
  "latitude": -27.459687,
  "longitude": 153.032108,
  "address": "Springfield Powerplant Reactors",
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "public_holiday_regions": [
    "au",
    "au_qld"
  ],
  "specific_holiday_dates": [
    {
      "date": "2016-08-08",
      "from": 8,
      "to": 17
    }
  ],
  "business_day_cutoff": 5,
  "business_hours": [
    {
      "weekday": 0,
      "start": "8:30",
      "finish": "17:00"
    }
  ],
  "record_id": 532432
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the location"
    },
    "name": {
      "type": "string",
      "description": "The name of the location"
    },
    "short_name": {
      "type": "string",
      "description": "The abbreviated form of the location's name"
    },
    "latitude": {
      "type": "number",
      "description": "The latitude of the location"
    },
    "longitude": {
      "type": "number",
      "description": "The longitude of the location"
    },
    "address": {
      "type": "string",
      "description": "Address of the location"
    },
    "time_zone": {
      "type": "string",
      "description": "The location's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The location's time zone's UTC offset"
    },
    "public_holiday_regions": {
      "type": "array",
      "description": "Public holiday regions (see Locations section for list of options)"
    },
    "specific_holiday_dates": {
      "type": "array",
      "description": "The dates and times of specific holidays for the location"
    },
    "business_day_cutoff": {
      "type": "number",
      "description": "The hour of the day before which data should be treated as being part of the previous day. eg 5 indicates that data from before 5am is part of the previous business day."
    },
    "business_hours": {
      "type": "array",
      "description": "The business hours of the location"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "name",
    "time_zone",
    "utc_offset"
  ]
}

Get Location
GET/api/v2/locations/{id}

This method requires the department scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 111

The id of the location

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false).


PUT https://my.tanda.co/api/v2/locations/111
RequestsUpdate LocationUpdate Business Hours
Headers
Content-Type: application/json
Body
{
  "name": "Shelbyville",
  "short_name": "S",
  "latitude": -27.467004,
  "longitude": 153.025453
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 111,
  "name": "Shelbyville",
  "short_name": "S",
  "latitude": -27.459687,
  "longitude": 153.032108,
  "address": "Springfield Powerplant Reactors",
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "public_holiday_regions": [
    "au",
    "au_qld"
  ],
  "specific_holiday_dates": [
    {
      "date": "2016-08-08",
      "from": 8,
      "to": 17
    }
  ],
  "business_day_cutoff": 5,
  "business_hours": [
    {
      "weekday": 0,
      "start": "8:30",
      "finish": "17:00"
    }
  ],
  "record_id": 532432
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the location"
    },
    "name": {
      "type": "string",
      "description": "The name of the location"
    },
    "short_name": {
      "type": "string",
      "description": "The abbreviated form of the location's name"
    },
    "latitude": {
      "type": "number",
      "description": "The latitude of the location"
    },
    "longitude": {
      "type": "number",
      "description": "The longitude of the location"
    },
    "address": {
      "type": "string",
      "description": "Address of the location"
    },
    "time_zone": {
      "type": "string",
      "description": "The location's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The location's time zone's UTC offset"
    },
    "public_holiday_regions": {
      "type": "array",
      "description": "Public holiday regions (see Locations section for list of options)"
    },
    "specific_holiday_dates": {
      "type": "array",
      "description": "The dates and times of specific holidays for the location"
    },
    "business_day_cutoff": {
      "type": "number",
      "description": "The hour of the day before which data should be treated as being part of the previous day. eg 5 indicates that data from before 5am is part of the previous business day."
    },
    "business_hours": {
      "type": "array",
      "description": "The business hours of the location"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "name",
    "time_zone",
    "utc_offset"
  ]
}
Headers
Content-Type: application/json
Body
{
  "business_hours": [
    { "weekday": 0, "start": "08:30", "finish": "17:00" },
    { "weekday": 1, "start": "6am", "finish": "2pm" },
    { "weekday": 1, "start": "3pm", "finish": "8pm" },
    { "weekday": 2, "start": "11:30", "finish": "11:45pm" },
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 111,
  "name": "Springfield",
  "short_name": "S",
  "latitude": -27.459687,
  "longitude": 153.032108,
  "address": "Springfield Powerplant Reactors",
  "time_zone": "Australia/Brisbane",
  "utc_offset": 36000,
  "public_holiday_regions": [
    "au",
    "au_qld"
  ],
  "specific_holiday_dates": [
    {
      "date": "2016-08-08",
      "from": 8,
      "to": 17
    }
  ],
  "business_day_cutoff": 5,
  "business_hours": [
    {
      "weekday": 0,
      "start": "08:30",
      "finish": "17:00"
    },
    {
      "weekday": 1,
      "start": "06:00",
      "finish": "14:00"
    },
    {
      "weekday": 1,
      "start": "15:00",
      "finish": "20:00"
    },
    {
      "weekday": 2,
      "start": "11:30",
      "finish": "23:45"
    }
  ],
  "record_id": 532432
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the location"
    },
    "name": {
      "type": "string",
      "description": "The name of the location"
    },
    "short_name": {
      "type": "string",
      "description": "The abbreviated form of the location's name"
    },
    "latitude": {
      "type": "number",
      "description": "The latitude of the location"
    },
    "longitude": {
      "type": "number",
      "description": "The longitude of the location"
    },
    "address": {
      "type": "string",
      "description": "Address of the location"
    },
    "time_zone": {
      "type": "string",
      "description": "The location's time zone"
    },
    "utc_offset": {
      "type": "number",
      "description": "The location's time zone's UTC offset"
    },
    "public_holiday_regions": {
      "type": "array",
      "description": "Public holiday regions (see Locations section for list of options)"
    },
    "specific_holiday_dates": {
      "type": "array",
      "description": "The dates and times of specific holidays for the location"
    },
    "business_day_cutoff": {
      "type": "number",
      "description": "The hour of the day before which data should be treated as being part of the previous day. eg 5 indicates that data from before 5am is part of the previous business day."
    },
    "business_hours": {
      "type": "array",
      "description": "The business hours of the location"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "name",
    "time_zone",
    "utc_offset"
  ]
}

Update Location
PUT/api/v2/locations/{id}

This method requires the department scope (see Scopes for more information).

Updating a location’s business hours

For business hours data, weekday ‘0’ is Sunday, ‘1’ is Monday, with the rest following that order till ‘6’ which ends on Saturday. Setting a config for a certain weekday through the API will override any existing business hours for that weekday, the rest of the week will stay the same. You can update multiple days at the same time with one request.

URI Parameters
HideShow
id
number (required) Example: 111

The id of the location


DELETE https://my.tanda.co/api/v2/locations/111
Responses200
Headers
Content-Type: application/json

Delete Location
DELETE/api/v2/locations/{id}

This method requires the department scope (see Scopes for more information).

Locations cannot be deleted if they have any teams.

URI Parameters
HideShow
id
number (required) Example: 111

The id of the location


Location Versions

GET https://my.tanda.co/api/v2/locations/111/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"Location\"",
    "changes": [
      {
        "field": "name",
        "previous": "Spring field",
        "updated": "Springfield"
      },
      {
        "field": "longitude",
        "previous": 153.032108,
        "updated": 100.500169
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Location Versions
GET/api/v2/locations/{id}/versions

This method requires the department scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 111

The id of the location

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified location versions


Teams (Departments)

Departments are often referred to as Teams inside Tanda. Teams belong to a Location.

Department managers can read and update information about the departments they manage. Admins can CRUD departments. Employees can read the departments that they belong to, with a subset of fields (see below)

The department group / team group Feature needs to be enabled before you can access this field. The assisting teams Feature needs to be enabled before you can access this field.

Team List

GET https://my.tanda.co/api/v2/departments
RequestsAs a managerAs an employee
This response has no content.
Responses200
Body
[
  {
    "id": 808,
    "location_id": 111,
    "name": "Waiters",
    "export_name": "WGB",
    "colour": "#FBB829",
    "staff": [
      1,
      2,
      123456
    ],
    "managers": [
      4,
      5
    ],
    "associated_tags": [
      "Level 2",
      "Level 3 HD"
    ],
    "qualification_ids": [
      1234,
      4321
    ],
    "assisting_team_ids": [
      1234,
      4321
    ],
    "team_group": "Front of House",
    "record_id": 532432
  }
]
Schema
{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id": {
        "type": "number",
        "description": "The id of the team"
      },
      "location_id": {
        "type": "number",
        "description": "The id of the team's location"
      },
      "name": {
        "type": "string",
        "description": "The name of the team"
      },
      "export_name": {
        "type": "string",
        "description": "30 (string) - The payroll export name of the team (if different to the name)"
      },
      "colour": {
        "type": "string",
        "description": "The team's colour"
      },
      "staff": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "description": "The user ids of the staff in the team"
      },
      "managers": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "description": "The user ids of the managers of the team"
      },
      "associated_tags": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "description": "Tags automatically assigned to shifts worked in this team"
      },
      "qualification_ids": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "description": "The required qualifications to work in this team"
      },
      "assisting_team_ids": {
        "type": "array",
        "items": {
          "type": "number"
        },
        "description": "The teams that will count toward this team's requirements on the roster"
      },
      "team_group": {
        "type": "string",
        "description": "A group of teams for rostering or reporting"
      },
      "record_id": {
        "type": "number",
        "description": "the record ID, for use with Platform endpoints"
      }
    },
    "required": [
      "id",
      "location_id",
      "name"
    ]
  },
  "$schema": "http://json-schema.org/draft-04/schema#"
}
This response has no content.
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 608,
    "name": "Waiters",
    "location_id": 111,
    "colour": "#FBB830"
  }
]

Get Teams
GET/api/v2/departments

This method requires the department scope (see Scopes for more information).

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified teams

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false).

page
number (optional) Example: 1

The page number for your teams list

page_size
number (optional) Example: 50

The number of teams retrieved per page. The maximum is 100 teams per page.


POST https://my.tanda.co/api/v2/departments
RequestsCreate TeamCreate Basic Team
Headers
Content-Type: application/json
Body
{
  "name": "Waiters",
  "location_id": 111,
  "export_name": "WGB-32",
  "colour": "#FBB830",
  "team_group": "Front of House",
  "qualification_ids" [123456],
  "manager_ids": [4444, 5555],
  "user_ids": [1111, 2222, 3333]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 809,
  "location_id": "111",
  "name": "Waiters",
  "export_name": "WGB",
  "colour": "#FBB830",
  "staff": [
    "[1111",
    "2222",
    "3333]"
  ],
  "managers": [
    "[4444",
    "5555]"
  ],
  "associated_tags": [
    "Level 2",
    "Level 3 HD"
  ],
  "qualification_ids": [
    1234,
    4321
  ],
  "assisting_team_ids": [],
  "team_group": "Front of House",
  "record_id": 532432
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the team"
    },
    "location_id": {
      "type": "string",
      "description": "The id of the team's location"
    },
    "name": {
      "type": "string",
      "description": "The name of the team"
    },
    "export_name": {
      "type": "string",
      "description": "32"
    },
    "colour": {
      "type": "string",
      "description": "The team's colour"
    },
    "staff": {
      "type": "array",
      "description": "The user ids of the staff in the team"
    },
    "managers": {
      "type": "array",
      "description": "The user ids of the managers of the team"
    },
    "associated_tags": {
      "type": "array",
      "description": "Tags automatically assigned to shifts worked in this team"
    },
    "qualification_ids": {
      "type": "array",
      "description": "The required qualifications to work in this team"
    },
    "assisting_team_ids": {
      "description": "The teams that will count toward this team's requirements on the roster"
    },
    "team_group": {
      "type": "string",
      "description": "A group of teams for rostering or reporting"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "location_id",
    "name"
  ]
}
Headers
Content-Type: application/json
Body
{
  "name": "Waiters",
  "location_id": "111",
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 809,
  "location_id": 111,
  "name": "Waiters",
  "export_name": null,
  "colour": null,
  "staff": [],
  "managers": []
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the team"
    },
    "location_id": {
      "type": "number",
      "description": "The id of the team's location"
    },
    "name": {
      "type": "string",
      "description": "The name of the team"
    },
    "export_name": {
      "type": "string",
      "description": "30 (string) - The payroll export name of the team (if different to the name)"
    },
    "colour": {
      "type": "string",
      "description": "The team's colour"
    },
    "staff": {
      "type": "array",
      "description": "The user ids of the staff in the team"
    },
    "managers": {
      "type": "array",
      "description": "The user ids of the managers of the team"
    },
    "associated_tags": {
      "type": "array",
      "description": "Tags automatically assigned to shifts worked in this team"
    },
    "qualification_ids": {
      "type": "array",
      "description": "The required qualifications to work in this team"
    },
    "assisting_team_ids": {
      "type": "array",
      "description": "The teams that will count toward this team's requirements on the roster"
    },
    "team_group": {
      "type": "string",
      "description": "A group of teams for rostering or reporting"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "location_id",
    "name"
  ]
}

Create Team
POST/api/v2/departments

This method requires the department scope (see Scopes for more information).


Team

GET https://my.tanda.co/api/v2/departments/111
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 808,
  "location_id": 111,
  "name": "Waiters",
  "export_name": "WGB",
  "colour": "#FBB829",
  "staff": [
    1,
    2,
    123456
  ],
  "managers": [
    4,
    5
  ],
  "associated_tags": [
    "Level 2",
    "Level 3 HD"
  ],
  "qualification_ids": [
    1234,
    4321
  ],
  "assisting_team_ids": [
    1234,
    4321
  ],
  "team_group": "Front of House",
  "record_id": 532432
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the team"
    },
    "location_id": {
      "type": "number",
      "description": "The id of the team's location"
    },
    "name": {
      "type": "string",
      "description": "The name of the team"
    },
    "export_name": {
      "type": "string",
      "description": "30 (string) - The payroll export name of the team (if different to the name)"
    },
    "colour": {
      "type": "string",
      "description": "The team's colour"
    },
    "staff": {
      "type": "array",
      "description": "The user ids of the staff in the team"
    },
    "managers": {
      "type": "array",
      "description": "The user ids of the managers of the team"
    },
    "associated_tags": {
      "type": "array",
      "description": "Tags automatically assigned to shifts worked in this team"
    },
    "qualification_ids": {
      "type": "array",
      "description": "The required qualifications to work in this team"
    },
    "assisting_team_ids": {
      "type": "array",
      "description": "The teams that will count toward this team's requirements on the roster"
    },
    "team_group": {
      "type": "string",
      "description": "A group of teams for rostering or reporting"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "location_id",
    "name"
  ]
}

Get Team
GET/api/v2/departments/{id}

This method requires the department scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 111

The id of the team

platform
boolean (optional) Example: false

If true, Platform data will be returned (defaults to false).


PUT https://my.tanda.co/api/v2/departments/111
RequestsUpdate Team NameUpdate Users & ManagersUpdate Required Qualifications
Headers
Content-Type: application/json
Body
{
  "name": "Kitchen Staff"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 808,
  "location_id": 111,
  "name": "Kitchen Staff",
  "export_name": "WGB",
  "colour": "#FBB829",
  "staff": [
    1,
    2,
    123456
  ],
  "managers": [
    4,
    5
  ],
  "associated_tags": [
    "Level 2",
    "Level 3 HD"
  ],
  "qualification_ids": [
    1234,
    4321
  ],
  "assisting_team_ids": [
    1234,
    4321
  ],
  "team_group": "Front of House",
  "record_id": 532432
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the team"
    },
    "location_id": {
      "type": "number",
      "description": "The id of the team's location"
    },
    "name": {
      "type": "string",
      "description": "The name of the team"
    },
    "export_name": {
      "type": "string",
      "description": "30 (string) - The payroll export name of the team (if different to the name)"
    },
    "colour": {
      "type": "string",
      "description": "The team's colour"
    },
    "staff": {
      "type": "array",
      "description": "The user ids of the staff in the team"
    },
    "managers": {
      "type": "array",
      "description": "The user ids of the managers of the team"
    },
    "associated_tags": {
      "type": "array",
      "description": "Tags automatically assigned to shifts worked in this team"
    },
    "qualification_ids": {
      "type": "array",
      "description": "The required qualifications to work in this team"
    },
    "assisting_team_ids": {
      "type": "array",
      "description": "The teams that will count toward this team's requirements on the roster"
    },
    "team_group": {
      "type": "string",
      "description": "A group of teams for rostering or reporting"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "location_id",
    "name"
  ]
}
Headers
Content-Type: application/json
Body
{
  "user_ids": [
    1111,
    2222,
    3333
  ],
  "manager_ids": [
    4444,
    5555
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 808,
  "location_id": 111,
  "name": "Waiters",
  "export_name": "WGB",
  "colour": "#FBB829",
  "staff": [
    "1111",
    "2222",
    "3333"
  ],
  "managers": [
    "4444",
    "5555"
  ],
  "associated_tags": [
    "Level 2",
    "Level 3 HD"
  ],
  "qualification_ids": [
    1234,
    4321
  ],
  "assisting_team_ids": [
    1234,
    4321
  ],
  "team_group": "Front of House",
  "record_id": 532432
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the team"
    },
    "location_id": {
      "type": "number",
      "description": "The id of the team's location"
    },
    "name": {
      "type": "string",
      "description": "The name of the team"
    },
    "export_name": {
      "type": "string",
      "description": "30 (string) - The payroll export name of the team (if different to the name)"
    },
    "colour": {
      "type": "string",
      "description": "The team's colour"
    },
    "staff": {
      "type": "array",
      "description": "The user ids of the staff in the team"
    },
    "managers": {
      "type": "array",
      "description": "The user ids of the managers of the team"
    },
    "associated_tags": {
      "type": "array",
      "description": "Tags automatically assigned to shifts worked in this team"
    },
    "qualification_ids": {
      "type": "array",
      "description": "The required qualifications to work in this team"
    },
    "assisting_team_ids": {
      "type": "array",
      "description": "The teams that will count toward this team's requirements on the roster"
    },
    "team_group": {
      "type": "string",
      "description": "A group of teams for rostering or reporting"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    }
  },
  "required": [
    "id",
    "location_id",
    "name"
  ]
}
Headers
Content-Type: application/json
Body
{
  "qualification_ids": [
    1001,
    1002
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 808,
  "location_id": 111,
  "name": "Waiters",
  "export_name": "WGB",
  "colour": "#FBB829",
  "staff": [
    1,
    2,
    123456
  ],
  "managers": [
    4,
    5
  ],
  "associated_tags": [
    "Level 2",
    "Level 3 HD"
  ],
  "qualification_ids": [
    1234,
    4321
  ],
  "assisting_team_ids": [
    1234,
    4321
  ],
  "team_group": "Front of House",
  "record_id": 532432,
  "qualifications": [
    "1001",
    "1002"
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the team"
    },
    "location_id": {
      "type": "number",
      "description": "The id of the team's location"
    },
    "name": {
      "type": "string",
      "description": "The name of the team"
    },
    "export_name": {
      "type": "string",
      "description": "30 (string) - The payroll export name of the team (if different to the name)"
    },
    "colour": {
      "type": "string",
      "description": "The team's colour"
    },
    "staff": {
      "type": "array",
      "description": "The user ids of the staff in the team"
    },
    "managers": {
      "type": "array",
      "description": "The user ids of the managers of the team"
    },
    "associated_tags": {
      "type": "array",
      "description": "Tags automatically assigned to shifts worked in this team"
    },
    "qualification_ids": {
      "type": "array",
      "description": "The required qualifications to work in this team"
    },
    "assisting_team_ids": {
      "type": "array",
      "description": "The teams that will count toward this team's requirements on the roster"
    },
    "team_group": {
      "type": "string",
      "description": "A group of teams for rostering or reporting"
    },
    "record_id": {
      "type": "number",
      "description": "the record ID, for use with Platform endpoints"
    },
    "qualifications": {
      "type": "array"
    }
  },
  "required": [
    "id",
    "location_id",
    "name"
  ]
}

Update Team
PUT/api/v2/departments/{id}

This method requires the department scope (see Scopes for more information).

Updating users & managers

Updating a department’s users or managers through a PUT request will completely replace existing users and managers with the ids provided. It is recommended to only update users and managers on setup of an account. Users provided must also be active or your request will fail.

Updating required team qualifications

When providing qualification ids you wish to assign as ‘required’ to join this team, users in the team must all have the qualification or else your request will fail. Your account must also have the enable_qualifications setting turned on.

URI Parameters
HideShow
id
number (required) Example: 111

The id of the team


DELETE https://my.tanda.co/api/v2/departments/111
Responses200
Headers
Content-Type: application/json

Delete Team
DELETE/api/v2/departments/{id}

This method requires the department scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 111

The id of the team


Team Versions

GET https://my.tanda.co/api/v2/departments/111/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"Department\"",
    "changes": [
      {
        "field": "name",
        "previous": "Wait staff",
        "updated": "Waiters"
      },
      {
        "field": "colour",
        "previous": "#3FAFD7",
        "updated": "#FBB829"
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Team Versions
GET/api/v2/departments/{id}/versions

This method requires the department scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 111

The id of the team

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified team versions


Shift Details

Shift details belong to a Team, and can be assigned on Schedules within that team.

Teams managers can read and update information about the shift details from the teams they manage. Admins can CRUD shift details.

Shift Detail List

GET https://my.tanda.co/api/v2/shift_details
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 36,
    "department_id": 808,
    "name": "Higher Duties"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Shift Details
GET/api/v2/shift_details

This method requires the department scope (see Scopes for more information).


POST https://my.tanda.co/api/v2/shift_details
RequestsCreate Shift Detail
Headers
Content-Type: application/json
Body
{
  "name": "Manager",
  "department_id": 808
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 532,
  "department_id": "808",
  "name": "Manager"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift detail"
    },
    "department_id": {
      "type": "string",
      "description": "The id of the shift detail's department"
    },
    "name": {
      "type": "string",
      "description": "The name of the shift detail"
    }
  },
  "required": [
    "id",
    "department_id",
    "name"
  ]
}

Create Shift Detail
POST/api/v2/shift_details

This method requires the department scope (see Scopes for more information).


Shift Detail

GET https://my.tanda.co/api/v2/shift_details/36
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 36,
  "department_id": 808,
  "name": "Higher Duties"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift detail"
    },
    "department_id": {
      "type": "number",
      "description": "The id of the shift detail's department"
    },
    "name": {
      "type": "string",
      "description": "The name of the shift detail"
    }
  },
  "required": [
    "id",
    "department_id",
    "name"
  ]
}

Get Shift Detail
GET/api/v2/shift_details/{id}

This method requires the department scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 36

The id of the shift detail


PUT https://my.tanda.co/api/v2/shift_details/36
RequestsUpdate Shift Detail
Headers
Content-Type: application/json
Body
{
  "name": "Shift Runner"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 36,
  "department_id": 808,
  "name": "Shift Runner"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the shift detail"
    },
    "department_id": {
      "type": "number",
      "description": "The id of the shift detail's department"
    },
    "name": {
      "type": "string",
      "description": "The name of the shift detail"
    }
  },
  "required": [
    "id",
    "department_id",
    "name"
  ]
}

Update Shift Detail
PUT/api/v2/shift_details/{id}

This method requires the department scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 36

The id of the shift detail


DELETE https://my.tanda.co/api/v2/shift_details/36
Responses200
Headers
Content-Type: application/json

Delete Shift Detail
DELETE/api/v2/shift_details/{id}

This method requires the department scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 36

The id of the shift detail


Access & Roles

By default only admin level users can access roles. But you can also define new roles that are able to access roles!

Platform Role List

GET https://my.tanda.co/api/v2/platform/roles
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 3816,
    "name": "Admin",
    "description": "access to all functions in Tanda",
    "type": "organisation_admin",
    "enabled": true,
    "native": true,
    "sort_order": 1
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Platform Roles
GET/api/v2/platform/roles

This method requires the platform scope (see Scopes for more information).


Award Tags

No special permissions are required to read award tags.

Award Tag List

GET https://my.tanda.co/api/v2/award_tags
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 3816,
    "name": "Casual"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Award Tags
GET/api/v2/award_tags

This method requires the user scope (see Scopes for more information).

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified award tags


Award Tag

GET https://my.tanda.co/api/v2/award_tags/3816
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 3816,
  "name": "Casual"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the award tag"
    },
    "name": {
      "type": "string",
      "description": "The name of the award tag"
    }
  },
  "required": [
    "id",
    "name"
  ]
}

Get Award Tag
GET/api/v2/award_tags/{id}

This method requires the user scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 3816

The id of the Award Tag


Leave Requests

Leave is time formally not worked by an employee, due to things like public holidays, sickness, or by accruing annual leave.

For specifying times when an employee requests not to be rostered, please see Unavailability.

Admins, payroll officers, and roster managers can create, read and update leave requests for all users, and department managers can create, read and update leave requests for users that they manage. Other users are able to create, read and update leave requests for themself. Note that the current user may not update status for their own leave requests unless they are an Admin, payroll officer or roster manager. Deletion of leave requests is not supported.

Leave List

GET https://my.tanda.co/api/v2/leave?ids=1,2,666&from=2016-03-15&to=2016-04-05&user_ids=1,2,123456
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 666,
    "department_id": 808,
    "user_id": 123456,
    "reason": "Terribly Sick",
    "leave_type": "Personal/Carer's Leave",
    "hours": 7.6,
    "start": "2016-04-01",
    "finish": "2016-04-01",
    "start_time": "2000-01-01T09:30:00+10:00",
    "finish_time": "2000-01-01T05:30:00+10:00",
    "status": "pending",
    "multitagging": "false",
    "all_day": true,
    "include_inactive": false,
    "daily_breakdown": {
      "2016-04-01": {},
      "hours": 7.6,
      "all_day": true,
      "start_time": "2016-04-01T09:30:00+1000",
      "finish_time": "2016-04-01T17:30:00+1000"
    }
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Leave List
GET/api/v2/leave{?ids,from,to,user_ids}

Lookup multiple leave requests in a single request.

Your URL parameters must include:

  • from and to, or

  • ids, or

  • all 3 of the above

You can also specify user_ids to further filter your request.

This method requires the leave scope (see Scopes for more information).

You will only be able to query up to 366 days when specifying from and to.

By default inactive users are excluded.

URI Parameters
HideShow
ids
string (optional) Example: 1,2,666

Comma separated list of leave ids to lookup

from
string (optional) Example: 2016-03-15

From date to lookup leave in

to
string (optional) Example: 2016-04-05

To date to lookup leave in

user_ids
string (optional) Example: 1,2,123456

Comma separated list of user ids to lookup leave for

page
number (optional) Example: 1

The page number for your leave request list

page_size
number (optional) Example: 50

The number of leave requests retrieved per page. Maximum 100 per page.

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified leave requests

include_inactive
boolean (optional) Example: true

Include inactive staff in your response.


POST https://my.tanda.co/api/v2/leave
RequestsCreate Leave
Headers
Content-Type: application/json
Body
{
  "reason": "Sick Day",
  "department_id": 2,
  "user_id": 123456,
  "hours": 114.0,
  "start": "2016-03-07",
  "start_time": "2000-01-01 09:30:00",
  "finish": "2016-03-07",
  "finish_time": "2000-01-01 17:30:00",
  "leave_type": "Sick Leave",
  "fallback_leave_type": "Unpaid Leave",
  "status": "pending",
  "all_day": false,
  "file_id": "73fe3430-4f5d-3a0a-84a7-cffbeb5efeb2",
  "daily_breakdown": [
    {
      "date": "2016-03-07"
      "hours": 114.0,
      "all_day": true,
      "start_time": "2016-03-07T09:30:00+1000",
      "finish_time": "2016-03-07T17:30:00+1000"
    }
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 7250,
  "department_id": 808,
  "user_id": 123456,
  "reason": "Holiday in France",
  "leave_type": "Annual Leave",
  "hours": 114,
  "start": "2016-03-07",
  "finish": "2016-03-08",
  "start_time": "2000-01-01T09:30:00",
  "finish_time": "2000-01-01T17:30:00",
  "status": "pending",
  "multitagging": "false",
  "all_day": "false",
  "include_inactive": false,
  "daily_breakdown": [],
  "fallback_leave_type": "Unpaid Leave",
  "verification": "http://springfieldfiles.com/albums/notes/0244.JPG"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the leave request"
    },
    "department_id": {
      "type": "number",
      "description": "The id of the team with which the leave request's shifts will be tagged"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who owns the leave request"
    },
    "reason": {
      "type": "string",
      "description": "The reason for the leave request - optional"
    },
    "leave_type": {
      "type": "string",
      "description": "The type of leave request"
    },
    "hours": {
      "type": "number",
      "description": "The number of workable hours the leave request spans"
    },
    "start": {
      "type": "string",
      "description": "The start date for the leave request"
    },
    "finish": {
      "type": "string",
      "description": "The end date for the leave request"
    },
    "start_time": {
      "type": "string",
      "description": "The start time for a leave request event"
    },
    "finish_time": {
      "type": "string",
      "description": "The end time for a leave request event"
    },
    "status": {
      "type": "string",
      "description": "The status for the leave request. One of ['pending', 'approved', 'rejected']"
    },
    "multitagging": {
      "type": "string",
      "description": "Determines whether shifts on the leave request can be tagged differently."
    },
    "all_day": {
      "type": "string",
      "description": "Useful for all day leave requests."
    },
    "include_inactive": {
      "type": "boolean",
      "description": "Useful for all leave requests that include inactive staff."
    },
    "daily_breakdown": {},
    "fallback_leave_type": {
      "type": "string"
    },
    "verification": {
      "type": "string"
    },
    "": {
      "type": "object",
      "properties": {
        "date": {
          "type": "string"
        },
        "hours": {
          "type": "number"
        },
        "all_day": {
          "type": "boolean"
        },
        "start_time": {
          "type": "string"
        },
        "finish_time": {
          "type": "string"
        }
      },
      "required": [
        "date",
        "all_day",
        "start_time",
        "finish_time"
      ]
    }
  },
  "required": [
    "id",
    "user_id",
    "leave_type",
    "hours",
    "start",
    "finish",
    "status"
  ]
}

Create Leave Request
POST/api/v2/leave

Note that a status for a new Leave Request is required. Managers can create approved leave requests for their staff, and themselves if permitted by the organisation settings. Admins can create approved leave requests for all staff. Employees may only create pending leave requests. The server will respond with a 400 when a user creates a leave request violating the above requirements.

Leave request status must be one of: “pending”, “approved”, “rejected”.

When a leave request is created with status “approved”, a Shift will be created for each day the leave request spans, and will be attached to the leave request. If a department_id is passed, these shifts will be categorised with the team corresponding to the department_id. Passing a department_id will have no consequence if the leave request status is “pending” or “rejected”. Note that the department_id will not be returned by the API, since technically it is a property of the shift, not of the leave request.

If you are building a user interface for the creation of leave requests, you might like to use the default hours endpoint to get recommendations for the hours field as the user chooses their dates.

You can attach a file when creating a leave request using the file_id parameter. See the temporary files endpoint for more information. The file should be a JPEG, PNG, GIF, or PDF.

This method requires the leave scope (see Scopes for more information).

New: time fields, and all_day boolean added to leave. Time fields allow leave to apply to a portion of a day, instead of a whole day. The date part of the time fields is not to be used and when returned from the API will always use the ruby default date of 2000-01-01.


Leave Request

GET https://my.tanda.co/api/v2/leave/666
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 666,
  "department_id": 808,
  "user_id": 123456,
  "reason": "Terribly Sick",
  "leave_type": "Personal/Carer's Leave",
  "hours": 7.6,
  "start": "2016-04-01",
  "finish": "2016-04-01",
  "start_time": "2000-01-01T09:30:00+10:00",
  "finish_time": "2000-01-01T05:30:00+10:00",
  "status": "pending",
  "multitagging": "false",
  "all_day": true,
  "include_inactive": false,
  "daily_breakdown": {
    "2016-04-01": {},
    "hours": 7.6,
    "all_day": true,
    "start_time": "2016-04-01T09:30:00+1000",
    "finish_time": "2016-04-01T17:30:00+1000"
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the leave request"
    },
    "department_id": {
      "type": "number",
      "description": "The id of the team with which the leave request's shifts will be tagged"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who owns the leave request"
    },
    "reason": {
      "type": "string",
      "description": "The reason for the leave request - optional"
    },
    "leave_type": {
      "type": "string",
      "description": "The type of leave request"
    },
    "hours": {
      "type": "number",
      "description": "The number of workable hours the leave request spans"
    },
    "start": {
      "type": "string",
      "description": "The start date for the leave request"
    },
    "finish": {
      "type": "string",
      "description": "The end date for the leave request"
    },
    "start_time": {
      "type": "string",
      "description": "The start time for a leave request event"
    },
    "finish_time": {
      "type": "string",
      "description": "The end time for a leave request event"
    },
    "status": {
      "type": "string",
      "description": "The status for the leave request. One of ['pending', 'approved', 'rejected']"
    },
    "multitagging": {
      "type": "string",
      "description": "Determines whether shifts on the leave request can be tagged differently."
    },
    "all_day": {
      "type": "boolean",
      "description": "Useful for all day leave requests."
    },
    "include_inactive": {
      "type": "boolean",
      "description": "Useful for all leave requests that include inactive staff."
    },
    "daily_breakdown": {
      "type": "object",
      "properties": {
        "2016-04-01": {
          "type": "object",
          "properties": {}
        },
        "hours": {
          "type": "number"
        },
        "all_day": {
          "type": "boolean"
        },
        "start_time": {
          "type": "string"
        },
        "finish_time": {
          "type": "string"
        }
      },
      "required": [
        "all_day",
        "start_time",
        "finish_time"
      ]
    }
  },
  "required": [
    "id",
    "user_id",
    "leave_type",
    "hours",
    "start",
    "finish",
    "status"
  ]
}

Get Leave Request
GET/api/v2/leave/{id}

This method requires the leave scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 666

The id of the leave to lookup


PUT https://my.tanda.co/api/v2/leave/666
RequestsUpdate Leave
Headers
Content-Type: application/json
Body
{
  "reason": "Really Really Sick",
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 666,
  "department_id": 808,
  "user_id": 123456,
  "reason": "Really Really Sick",
  "leave_type": "Personal/Carer's Leave",
  "hours": 7.6,
  "start": "2016-04-01",
  "finish": "2016-04-01",
  "start_time": "2000-01-01T09:30:00+10:00",
  "finish_time": "2000-01-01T05:30:00+10:00",
  "status": "pending",
  "multitagging": "false",
  "all_day": true,
  "include_inactive": false,
  "daily_breakdown": {
    "2016-04-01": {},
    "hours": 7.6,
    "all_day": true,
    "start_time": "2016-04-01T09:30:00+1000",
    "finish_time": "2016-04-01T17:30:00+1000"
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the leave request"
    },
    "department_id": {
      "type": "number",
      "description": "The id of the team with which the leave request's shifts will be tagged"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who owns the leave request"
    },
    "reason": {
      "type": "string",
      "description": "The reason for the leave request - optional"
    },
    "leave_type": {
      "type": "string",
      "description": "The type of leave request"
    },
    "hours": {
      "type": "number",
      "description": "The number of workable hours the leave request spans"
    },
    "start": {
      "type": "string",
      "description": "The start date for the leave request"
    },
    "finish": {
      "type": "string",
      "description": "The end date for the leave request"
    },
    "start_time": {
      "type": "string",
      "description": "The start time for a leave request event"
    },
    "finish_time": {
      "type": "string",
      "description": "The end time for a leave request event"
    },
    "status": {
      "type": "string",
      "description": "The status for the leave request. One of ['pending', 'approved', 'rejected']"
    },
    "multitagging": {
      "type": "string",
      "description": "Determines whether shifts on the leave request can be tagged differently."
    },
    "all_day": {
      "type": "boolean",
      "description": "Useful for all day leave requests."
    },
    "include_inactive": {
      "type": "boolean",
      "description": "Useful for all leave requests that include inactive staff."
    },
    "daily_breakdown": {
      "type": "object",
      "properties": {
        "2016-04-01": {
          "type": "object",
          "properties": {}
        },
        "hours": {
          "type": "number"
        },
        "all_day": {
          "type": "boolean"
        },
        "start_time": {
          "type": "string"
        },
        "finish_time": {
          "type": "string"
        }
      },
      "required": [
        "all_day",
        "start_time",
        "finish_time"
      ]
    }
  },
  "required": [
    "id",
    "user_id",
    "leave_type",
    "hours",
    "start",
    "finish",
    "status"
  ]
}

Update Leave Request
PUT/api/v2/leave/{id}

This method requires the leave scope (see Scopes for more information).

Employees cannot update a leave request, with the exception of rejecting their own pending leave request.

URI Parameters
HideShow
id
number (required) Example: 666

The id of the leave to update


Leave Types

GET https://my.tanda.co/api/v2/leave/types_for/123456
Responses200
Headers
Content-Type: application/json
Body
[
  "Annual Leave",
  "Personal/Carer's Leave",
  "Public Holiday (Paid/Not Worked)"
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Leave Types for User
GET/api/v2/leave/types_for/{user_id}

This method requires the leave scope (see Scopes for more information).

URI Parameters
HideShow
user_id
number (required) Example: 123456

The id of the user to lookup leave types for


Leave Types With Details

GET https://my.tanda.co/api/v2/leave/types_with_details_for/123456
Responses200
Headers
Content-Type: application/json
Body
[
{
name: "Annual Leave",
prevent_negative: true,
default_fallback_leave_type_name: "Unpaid Leave"
},
{
name: "Unpaid Leave",
prevent_negative: false,
default_fallback_leave_type_name: nil
}
]

Get Leave Types with details for User
GET/api/v2/leave/types_with_details_for/{user_id}

This method requires the leave scope (see Scopes for more information).

URI Parameters
HideShow
user_id
number (required) Example: 123456

The id of the user to lookup leave types for


Leave Request Versions

GET https://my.tanda.co/api/v2/leave/666/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"Leave\"",
    "changes": [
      {
        "field": "status",
        "previous": "pending",
        "updated": "approved"
      },
      {
        "field": "reason",
        "previous": "Holiday",
        "updated": "Terribly Sick"
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Leave Request Versions
GET/api/v2/leave/{id}/versions

This method requires the leave scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 666

The id of the leave request

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified leave request versions


Default Leave Hours

GET https://my.tanda.co/api/v2/leave/hours_between?user_id=123456&start=2016-03-15&finish=2016-03-17&leave_type=Annual Leave
Responses200
Headers
Content-Type: application/json
Body
{
  "hours": "22.8",
}

Get Default Hours for a Leave Request
GET/api/v2/leave/hours_between{?user_id,start,finish,leave_type}

Use this endpoint to get a recommendation for the number of hours of leave someone should take based on the given dates. This will take into account public holidays and weekends, and the default leave hours setting in an account. For example, if given a date range of 5 days, of which 1 is a weekend and 1 is a holiday, and with a default leave hours setting of 7.6, the endpoint will return 22.8 hours.

This method requires the leave scope (see Scopes for more information).

URI Parameters
HideShow
user_id
number (required) Example: 123456

The id of the user

start
string (required) Example: 2016-03-15

Start date of leave request

finish
string (required) Example: 2016-03-17

Finish date of leave request

leave_type
string (optional) Example: Annual Leave

The leave type


Leave Balances

Leave balances denote how much leave (of each type) someone has accrued.

Leave balance interactions require the same permissions as leave requests.

Leave Balance List

GET https://my.tanda.co/api/v2/leave_balances?user_ids=1,2,666
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 666,
    "user_id": 123456,
    "leave_type": "Annual Leave",
    "hours": 4,
    "should_accrue": false
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Leave Balances
GET/api/v2/leave_balances{?user_ids}

Lookup leave balances for one or more user_ids.

This method requires the leave scope (see Scopes for more information).

URI Parameters
HideShow
user_ids
string (optional) Example: 1,2,666

Comma separated list of user ids to lookup leave balances for

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified leave balances


POST https://my.tanda.co/api/v2/leave_balances
RequestsCreate Leave BalanceCreate multiple Leave Balances
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "leave_type": "Annual Leave",
  "hours": 18
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 666,
  "user_id": 123456,
  "leave_type": "Annual Leave",
  "hours": 18,
  "should_accrue": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the leave balance"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who owns the leave balance"
    },
    "leave_type": {
      "type": "string",
      "description": "The type of leave"
    },
    "hours": {
      "type": "number",
      "description": "The number of hours of leave accrued"
    },
    "should_accrue": {
      "type": "boolean",
      "description": "If true, this leave balance will accrue in Tanda automatically. If false, you should keep it up to date. Default is false."
    }
  },
  "required": [
    "id",
    "user_id",
    "leave_type",
    "hours"
  ]
}
Headers
Content-Type: application/json
Body
{
  "balances": [
    {
      "user_id": 123456,
      "leave_type": "Annual Leave",
      "hours": 18
    },
    {
      "user_id": 654321,
      "leave_type": "Sick Leave",
      "hours": 22
    }
  ]
}
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "user_id": 123456,
    "hours": 18,
    "leave_type": "Annual Leave"
  },
  {
    "user_id": 654321,
    "hours": 22,
    "leave_type": "Sick Leave"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Create Leave Balance
POST/api/v2/leave_balances

Use the Leave Types For User call to find accessible leave types for your user.

This method requires the leave scope (see Scopes for more information).


Leave Balance

GET https://my.tanda.co/api/v2/leave_balances/666
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 666,
  "user_id": 123456,
  "leave_type": "Annual Leave",
  "hours": 4,
  "should_accrue": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the leave balance"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who owns the leave balance"
    },
    "leave_type": {
      "type": "string",
      "description": "The type of leave"
    },
    "hours": {
      "type": "number",
      "description": "The number of hours of leave accrued"
    },
    "should_accrue": {
      "type": "boolean",
      "description": "If true, this leave balance will accrue in Tanda automatically. If false, you should keep it up to date. Default is false."
    }
  },
  "required": [
    "id",
    "user_id",
    "leave_type",
    "hours"
  ]
}

Get Leave Balance
GET/api/v2/leave_balances/{id}

This method requires the leave scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 666

The ID of the leave balance to lookup


PUT https://my.tanda.co/api/v2/leave_balances/666
RequestsUpdate Leave
Headers
Content-Type: application/json
Body
{
  "hours": 22.5
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 666,
  "user_id": 123456,
  "leave_type": "Annual Leave",
  "hours": 22.5,
  "should_accrue": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the leave balance"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who owns the leave balance"
    },
    "leave_type": {
      "type": "string",
      "description": "The type of leave"
    },
    "hours": {
      "type": "number",
      "description": "The number of hours of leave accrued"
    },
    "should_accrue": {
      "type": "boolean",
      "description": "If true, this leave balance will accrue in Tanda automatically. If false, you should keep it up to date. Default is false."
    }
  },
  "required": [
    "id",
    "user_id",
    "leave_type",
    "hours"
  ]
}

Update Leave Balance with ID
PUT/api/v2/leave_balances/{id}

This method requires the leave scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 666

The ID of the leave balance to update


Update Leave Balance with User ID

PUT https://my.tanda.co/api/v2/leave_balances/user/123456
RequestsUpdate Leave Balance with User IDCreate multiple Leave Balances with User ID
Headers
Content-Type: application/json
Body
{
  "leave_type": "Annual Leave",
  "hours": 18,
  "should_accrue": false
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 666,
  "user_id": 123456,
  "leave_type": "Annual Leave",
  "hours": 18,
  "should_accrue": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the leave balance"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user who owns the leave balance"
    },
    "leave_type": {
      "type": "string",
      "description": "The type of leave"
    },
    "hours": {
      "type": "number",
      "description": "The number of hours of leave accrued"
    },
    "should_accrue": {
      "type": "boolean",
      "description": "If true, this leave balance will accrue in Tanda automatically. If false, you should keep it up to date. Default is false."
    }
  },
  "required": [
    "id",
    "user_id",
    "leave_type",
    "hours"
  ]
}
Headers
Content-Type: application/json
Body
{
  "balances": [
    {
      "leave_type": "Annual Leave",
      "hours": 18
    },
    {
      "leave_type": "Sick Leave",
      "hours": 22
    }
  ]
}
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "hours": 18,
    "leave_type": "Annual Leave"
  },
  {
    "hours": 22,
    "leave_type": "Sick Leave"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Update Leave Balance with User ID
PUT/api/v2/leave_balances/user/{user_id}

This method requires the leave scope (see Scopes for more information).

URI Parameters
HideShow
user_id
number (required) Example: 123456

The ID of the user whose leave balance you want to update


Predict Leave Balances

POST https://my.tanda.co/api/v2/leave_balances/654321/predict
RequestsPredict Leave Balance
Headers
Content-Type: application/json
Body
{
  "date": "2019-12-24"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "prediction": 22.5
}

Predict Leave Balance
POST/api/v2/leave_balances/{id}/predict

This endpoint takes a leave balance ID and a date, and predicts what the leave balance will be on the given date. The date must be in the future.

This method requires the leave scope (see Scopes for more information).

You should make it clear when displaying the result that this is a prediction. There is no guarantee the user’s actual leave balance will match this when the date comes.

URI Parameters
HideShow
id
number (required) Example: 654321

The ID of the leave balance


Unavailability

Unavailability is an employee’s way to notify the person building the roster that they are not going to be available during a certain time period. Unavailability is most used by casual staff or employees with flexible hours.

For specifying times when an employee formally took time off, or to request time off (most often for part time and full time employees), please see Leave.

If the organisation has unavailability enabled, then all employees can CRUD unavailability about themselves. Roster managers, and admins can CRUD unavailability for everyone and department managers can CRUD unavailability for users they can manage.

Unavailability List

GET https://my.tanda.co/api/v2/unavailability?ids=1,2,42&from=2016-03-15&to=2016-04-05&user_ids=1,2,123456
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 42,
    "user_id": 123456,
    "title": "Doing errr... something",
    "start": 1459814400,
    "finish": 1459836000,
    "repeating": false,
    "repeating_info": null,
    "all_day": false
  }
]

Get Unavailabilities
GET/api/v2/unavailability{?ids,from,to,user_ids}

Lookup multiple leave requests in a single request.

You must specify either both from and to or ids (you can specify both if you want too). user_ids can be specified in any case.

This method requires the unavailability scope (see Scopes for more information).

You will only be able to query up to 366 days when specifying from and to.

URI Parameters
HideShow
ids
string (optional) Example: 1,2,42

Comma separated list of unavailability ids to lookup

from
string (optional) Example: 2016-03-15

From date to lookup unavailability in

to
string (optional) Example: 2016-04-05

To date to lookup unavailability in

user_ids
string (optional) Example: 1,2,123456

Comma separated list of user ids to lookup unavailability for

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified unavailability


POST https://my.tanda.co/api/v2/unavailability
RequestsCreate UnavailabilityCreate all day UnavailabilityCreate repeating Unavailability
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "title": "Buying a unicycle",
  "start": 1459375200,
  "finish": 1459382400,
  "repeating": false
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 106092,
  "user_id": 123456,
  "title": "Buying a unicycle",
  "start": 1459375200,
  "finish": 1459382400,
  "repeating": false,
  "repeating_info": null,
  "all_day": false
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "title": "Buying a unicycle",
  "date_from": "2017-05-15",
  "date_to": "2017-05-15",
  "repeating": false,
  "all_day": true
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 106092,
  "user_id": 123456,
  "title": "Buying a unicycle",
  "start": 1494770400,
  "finish": 1494856800,
  "repeating": false,
  "repeating_info": null,
  "all_day": true
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "title": "Learning to ride my unicycle",
  "start": 1459382400,
  "finish": 1459389600,
  "repeating": true,
  "repeating_info": {
    "interval": "day",
    "occurrences": 3
  }
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 106093,
  "user_id": 123456,
  "title": "Learning to ride my unicycle",
  "start": 1459382400,
  "finish": 1459389600,
  "repeating": true,
  "repeating_info": {
    "interval": "day",
    "occurrences": 3,
    "start": 1459382400,
    "ids": [
      106093,
      106094,
      106095
    ]
  },
  "all_day": false
}

Create Unavailability
POST/api/v2/unavailability

This method requires the unavailability scope (see Scopes for more information).

There’s two ways to create unavailabilities: using dates (for all_day events), or using times (for events that don’t go all day).

Regardless of which method you use, you should use the unavailability minimum date from the Settings endpoint to validate your dates or times locally. If you pass a time that is earlier than the minimum date (in the given user’s time zone), the request will fail. You can override the failure by setting the override_validations flag.

To create an event using dates, use these parameters. Note that date_from and date_to are inclusive. If you have an unavailability that only goes for one day, they should have the same value. If you have an unavailability that goes for two full days, they should be one day apart, etc.

  • all_day: true

  • user_id - integer

  • title - string

  • repeating - boolean

  • date_from - string, eg “2016-03-15”

  • date_to - string, eg “2016-03-16” - In this example, you will be unavailable on the 15th AND the 16th of March

To create an event using times, use these parameters:

  • all_day: false

  • user_id - integer

  • title - string

  • repeating - boolean

  • start - integer, eg 1459375200

  • finish - integer, eg 1459382400 - In this example, you will be unavailable from 2016-03-30 22:00:00 UTC to 2016-03-31 00:00:00 UTC

To bypass checking minimum date and published schedule checks, use override_validations:

  • all_day: true

  • override_validations: true

  • user_id - integer

  • title - string

  • repeating - boolean

  • start - integer, eg 1459375200

  • finish - integer, eg 1459382400 - In this example, you will be unavailable from 2016-03-30 22:00:00 UTC to 2016-03-31 00:00:00 UTC

You can also use the repeating param to tell an event to repeat. For example:

  • all_day: false

  • user_id - integer

  • title - string

  • repeating - true

  • repeating_info: {"interval": "week","occurrences": 4}

  • start - integer, eg 1494838800

  • finish - integer, eg 1494867600 - In this example, you will be unavailable from 2017-05-15 09:00:00 UTC to 2017-05-15 17:00:00 UTC, and at the same times for the next 3 weeks after (4 weeks total).

There’s more examples in the sidebar. The examples are based on a user in the AEST+10 time zone.


Repeating Unavailability List

GET https://my.tanda.co/api/v2/unavailability/repeating_for/43
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 43,
    "user_id": 123456,
    "title": "Doing errr... something else",
    "start": 1459994400,
    "finish": 1460001600,
    "repeating": true,
    "repeating_info": {
      "interval": "week",
      "occurrences": 2,
      "start": 1459994400,
      "ids": [
        43,
        44
      ]
    }
  },
  {
    "id": 44,
    "user_id": 123456,
    "title": "Doing errr... something else",
    "start": 1460599200,
    "finish": 1460606400,
    "repeating": true,
    "repeating_info": {
      "interval": "week",
      "occurrences": 2,
      "start": 1459994400,
      "ids": [
        43,
        44
      ]
    }
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Repeating Unavailabilities
GET/api/v2/unavailability/repeating_for/{id}

This method requires the unavailability scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 43

The id of the unavailability to get repeating information for


Unavailability

GET https://my.tanda.co/api/v2/unavailability/42
RequestsNon-repeating unavailabilityRepeating unavailability
This response has no content.
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 42,
  "user_id": 123456,
  "title": "Doing errr... something",
  "start": 1459814400,
  "finish": 1459836000,
  "repeating": false,
  "repeating_info": null,
  "all_day": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the unavailability"
    },
    "user_id": {
      "type": "number",
      "description": "The user that the unavailability applies for"
    },
    "title": {
      "type": "string",
      "description": "The reason for the unavailability"
    },
    "start": {
      "type": "number",
      "description": "The start time for the unavailability"
    },
    "finish": {
      "type": "number",
      "description": "The end time for the unavailability"
    },
    "repeating": {
      "type": "boolean",
      "description": "Whether this is part of a set of repeating unavailabilities"
    },
    "repeating_info": {
      "type": "object",
      "properties": {
        "interval": {
          "type": "string",
          "description": "The time between repeating events"
        },
        "occurrences": {
          "type": "number",
          "description": "The number of unavailabilities in the repeating set of unavailabilities"
        },
        "start": {
          "type": "number",
          "description": "The start of the first unavailability in the repeating set"
        },
        "ids": {
          "type": "array",
          "description": "The ids of the unavailabilities that are part of the this repeating set"
        }
      },
      "required": [
        "interval",
        "occurrences",
        "start",
        "ids"
      ],
      "description": "Info about the unavailabilities that are part of this repeating set of unavailabilities (if the unavailability is repeating)"
    }
  },
  "required": [
    "id",
    "user_id",
    "start",
    "finish",
    "repeating"
  ]
}
This response has no content.
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 43,
  "user_id": 123456,
  "title": "Doing errr... something else",
  "start": 1459994400,
  "finish": 1460001600,
  "repeating": true,
  "repeating_info": {
    "interval": "week",
    "occurrences": 2,
    "start": 1459994400,
    "ids": [
      43,
      44
    ]
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the unavailability"
    },
    "user_id": {
      "type": "number",
      "description": "The user that the unavailability applies for"
    },
    "title": {
      "type": "string",
      "description": "The reason for the unavailability"
    },
    "start": {
      "type": "number",
      "description": "The start time for the unavailability"
    },
    "finish": {
      "type": "number",
      "description": "The end time for the unavailability"
    },
    "repeating": {
      "type": "boolean",
      "description": "Whether this is part of a set of repeating unavailabilities"
    },
    "repeating_info": {
      "type": "object",
      "properties": {
        "interval": {
          "type": "string",
          "description": "The time between repeating events"
        },
        "occurrences": {
          "type": "number",
          "description": "The number of unavailabilities in the repeating set of unavailabilities"
        },
        "start": {
          "type": "number",
          "description": "The start of the first unavailability in the repeating set"
        },
        "ids": {
          "type": "array",
          "description": "The ids of the unavailabilities that are part of the this repeating set"
        }
      },
      "required": [
        "interval",
        "occurrences",
        "start",
        "ids"
      ],
      "description": "Info about the unavailabilities that are part of this repeating set of unavailabilities (if the unavailability is repeating)"
    }
  },
  "required": [
    "id",
    "user_id",
    "start",
    "finish",
    "repeating"
  ]
}

Get Unavailability
GET/api/v2/unavailability/{id}

This method requires the unavailability scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 42

The id of unavailability to lookup


PUT https://my.tanda.co/api/v2/unavailability/42
RequestsUpdate Unavailability
Headers
Content-Type: application/json
Body
{
  "title": "Helping Grandma"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 42,
  "user_id": 123456,
  "title": "Helping Grandma",
  "start": 1459814400,
  "finish": 1459836000,
  "repeating": false,
  "repeating_info": null,
  "all_day": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the unavailability"
    },
    "user_id": {
      "type": "number",
      "description": "The user that the unavailability applies for"
    },
    "title": {
      "type": "string",
      "description": "The reason for the unavailability"
    },
    "start": {
      "type": "number",
      "description": "The start time for the unavailability"
    },
    "finish": {
      "type": "number",
      "description": "The end time for the unavailability"
    },
    "repeating": {
      "type": "boolean",
      "description": "Whether this is part of a set of repeating unavailabilities"
    },
    "repeating_info": {
      "type": "object",
      "properties": {
        "interval": {
          "type": "string",
          "description": "The time between repeating events"
        },
        "occurrences": {
          "type": "number",
          "description": "The number of unavailabilities in the repeating set of unavailabilities"
        },
        "start": {
          "type": "number",
          "description": "The start of the first unavailability in the repeating set"
        },
        "ids": {
          "type": "array",
          "description": "The ids of the unavailabilities that are part of the this repeating set"
        }
      },
      "required": [
        "interval",
        "occurrences",
        "start",
        "ids"
      ],
      "description": "Info about the unavailabilities that are part of this repeating set of unavailabilities (if the unavailability is repeating)"
    }
  },
  "required": [
    "id",
    "user_id",
    "start",
    "finish",
    "repeating"
  ]
}

Update Unavailability
PUT/api/v2/unavailability/{id}

Update the unavailability’s title (in the case of repeating unavailability, all of the event’s titles will be updated).

This method requires the unavailability scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 42

The id of unavailability to lookup


DELETE https://my.tanda.co/api/v2/unavailability/42
Responses200
Headers
Content-Type: application/json

Delete Unavailability
DELETE/api/v2/unavailability/{id}

This method requires the unavailability scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 42

The id of the leave to delete


Data Streams

Our user guide has more information on working with data streams through the API.

A data stream is a container for many Store Stats. The data stream specifies the origin of the data, an identifier for the origin (if any), and the interval of the data. All store stats added to a data stream should be totaled data for a time period equal to the data_interval.

Data streams themselves are nice for holding data, but they are made useful by joining them to other objects. See Data Stream Joins for more on how this works. The Data Streams endpoint provides some functionality for quickly creating joins, but you should use the Data Stream Joins endpoint if you need more control over their structure or additional attributes.

Team managers can read data streams that are joined to their team. General managers and payroll officers can read all data streams, and admins can create read and update all data streams.

Data Stream List

GET https://my.tanda.co/api/v2/datastreams
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 24,
    "name": "Reactor Revenue",
    "source": "generic",
    "data_interval": 900,
    "print_mode": "hidden",
    "roster_display_mode": "values"
  },
  {
    "id": 25,
    "name": "User Entered: Springfield Powerplant",
    "source": "user_entered",
    "data_interval": 86400,
    "print_mode": "hidden",
    "roster_display_mode": "values"
  },
  {
    "id": 26,
    "name": "Reactor Revenue (Retail Express)",
    "source": "retail_express",
    "section_identifier": "11223344",
    "data_interval": 900,
    "print_mode": "hidden",
    "roster_display_mode": "values"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Data Streams
GET/api/v2/datastreams

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified data streams


POST https://my.tanda.co/api/v2/datastreams
RequestsCreate Data Stream
Headers
Content-Type: application/json
Body
{
  "name": "My Special Data",
  "data_interval": 900,
  "default_stat_type": "sales"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1069,
  "name": "My Special Data",
  "source": "api",
  "data_interval": 900,
  "print_mode": "hidden",
  "roster_display_mode": "values"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the data stream"
    },
    "name": {
      "type": "string",
      "description": "The name of the data stream"
    },
    "source": {
      "type": "string",
      "description": "The data stream's source"
    },
    "data_interval": {
      "type": "number",
      "description": "The time between the data stream's store stats in seconds"
    },
    "print_mode": {
      "type": "string",
      "description": "Should the data stream be printed when printing a roster? Options: hidden, values, cumulative_sum"
    },
    "roster_display_mode": {
      "type": "string",
      "description": "Should the data stream be displayed on rosters? Options: hidden, values, cumulative_sum"
    }
  },
  "required": [
    "id",
    "name",
    "data_interval"
  ]
}

Create Data Stream
POST/api/v2/datastreams

You cannot create more than one data stream via the API with the same name. If you try to create a data stream with a name that already exists, that data stream will instead be updated and returned (effectively this will function as a PUT request).

The data interval must be either 86400, 3600, 1800, or 900. This corresponds to 1 day, 1 hour, 30 minutes, or 15 minutes.

It’s highly recommended you give a data stream a ‘default_stat_type’. Having this means that when the data stream is joined to locations or teams, the correct data is joined. Without this field you may see some unexpected results. For example, if your data stream houses ‘sales’ and ‘transactions’, and you mainly want to use the ‘sales’ data, you should set the default_stat_type to ‘sales’

This method requires the datastream scope (see Scopes for more information).


Data Stream

GET https://my.tanda.co/api/v2/datastreams/26
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 26,
  "name": "Reactor Revenue (Retail Express)",
  "source": "retail_express",
  "section_identifier": "11223344",
  "data_interval": 900,
  "print_mode": "hidden",
  "roster_display_mode": "values"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the data stream"
    },
    "name": {
      "type": "string",
      "description": "The name of the data stream"
    },
    "source": {
      "type": "string",
      "description": "The data stream's source"
    },
    "section_identifier": {
      "type": "string",
      "description": "A way to map to the external data provider"
    },
    "data_interval": {
      "type": "number",
      "description": "The time between the data stream's store stats in seconds"
    },
    "print_mode": {
      "type": "string",
      "description": "Should the data stream be printed when printing a roster? Options: hidden, values, cumulative_sum"
    },
    "roster_display_mode": {
      "type": "string",
      "description": "Should the data stream be displayed on rosters? Options: hidden, values, cumulative_sum"
    }
  },
  "required": [
    "id",
    "name",
    "source",
    "data_interval"
  ]
}

Get Data Stream
GET/api/v2/datastreams/{id}

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 26

The id of the data stream to lookup


PUT https://my.tanda.co/api/v2/datastreams/26
RequestsUpdate Data Stream
Headers
Content-Type: application/json
Body
{
  "name": "Foot Traffic!",
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1069,
  "name": "Foot Traffic!",
  "source": "api",
  "data_interval": 900,
  "print_mode": "hidden",
  "roster_display_mode": "values"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the data stream"
    },
    "name": {
      "type": "string",
      "description": "The name of the data stream"
    },
    "source": {
      "type": "string",
      "description": "The data stream's source"
    },
    "data_interval": {
      "type": "number",
      "description": "The time between the data stream's store stats in seconds"
    },
    "print_mode": {
      "type": "string",
      "description": "Should the data stream be printed when printing a roster? Options: hidden, values, cumulative_sum"
    },
    "roster_display_mode": {
      "type": "string",
      "description": "Should the data stream be displayed on rosters? Options: hidden, values, cumulative_sum"
    }
  },
  "required": [
    "id",
    "name",
    "data_interval"
  ]
}

Update Data Stream
PUT/api/v2/datastreams/{id}

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 26

The id of the data stream to update


DELETE https://my.tanda.co/api/v2/datastreams/26
Responses202
Headers
Content-Type: application/json

Delete Data Stream
DELETE/api/v2/datastreams/{id}

Only data streams created via the API can be deleted via the API. This also deletes all associated Data Stream Joins and Store Stats, and cannot be reversed.

The data stream will be scheduled for deletion, but may not be removed immediately. You can GET the data stream to check if it’s been deleted.

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 26

The id of the data stream


Data Stream Versions

GET https://my.tanda.co/api/v2/datastreams/26/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"Datastream\"",
    "changes": [
      {
        "field": "data_interval",
        "previous": 900,
        "updated": 1800
      },
      {
        "field": "name",
        "previous": "Employee Superfund",
        "updated": "Reactor Revenue"
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Data Stream Versions
GET/api/v2/datastreams/{id}/versions

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 26

The id of the data stream

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified data stream versions


Data Stream Joins

Our user guide has more information on working with data streams through the API.

Data Stream Joins connect Data Streams to the object which owns the stream’s data. For example, data from a stream may be relate to a Team, Location, or to the Organisation itself.

If a data stream is joined to the organisation, it will show its store stats in the context of the whole organisation. Similarly, if it is joined to one or many teams, it will show its store stats when looking at stats for each of those teams. Data streams that are joined to a team, but not the organisation, will show their store stats in the context of the teams, but will not show when looking at the organisation as a whole (this is often useful for team specific stats).

Data Stream Joins also connect a single ‘stat_type’ from a data stream. You should specify which stat_type you want to join from the data stream to the Organisation, Location, or Department. For example, your data stream might have both ‘sales’ data and ‘transaction’ data in it. If you want to attach sales data to a team, then you must specify the stat_type_id for sales in the payload.

If you do not specify a stat_type, one will be inferred by what kind of data your datastream has. Eg if your data stream only has sales data in it, the join will automatically be given the sales stat type.

Only admins can manage data stream joins.

As well as managing this relationship, a Data Stream Join can also be given a rostering ratio, which is used to calculate how many staff should be rostered into the join’s object (the “streamable”) based on stream data. For example, a data stream might have a total value of 30 (values themselves are provided using Store Stats) for a half hour period, and the data stream’s join to a team might have a rostering ratio of 8. In this case Tanda would recommend that 4 staff be rostered for that half hour period.

Data Stream Join List

GET https://my.tanda.co/api/v2/datastreamjoins
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 162,
    "data_stream_id": 24,
    "data_streamable_id": 111,
    "data_streamable_type": "Department",
    "rostering_ratio": 1.175,
    "head_count_map": "\"1,2.5,5\""
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Data Stream Joins
GET/api/v2/datastreamjoins

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified data stream joins


POST https://my.tanda.co/api/v2/datastreamjoins
RequestsCreate Joined to TeamCreate Joined to Organisation
Headers
Content-Type: application/json
Body
{
  "data_stream_id": 24,
  "data_streamable_id": 111,
  "data_streamable_type": "Department",
  "rostering_ratio": 2.5,
  "stat_type_id": 123
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 162,
  "data_stream_id": 24,
  "data_streamable_id": 111,
  "data_streamable_type": "Department",
  "rostering_ratio": 2.5,
  "head_count_map": "\"1,2.5,5\"",
  "stat_type_id": 123
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the data stream join"
    },
    "data_stream_id": {
      "type": "number",
      "description": "The id of the data stream join's data stream"
    },
    "data_streamable_id": {
      "type": "number",
      "description": "The id of the data stream join's data streamable (location or team)"
    },
    "data_streamable_type": {
      "type": "string",
      "description": "The type of the data stream join's data streamable (\"Location\", \"Department\", or \"Organisation\")"
    },
    "rostering_ratio": {
      "type": "number",
      "description": "The ratio of units to staff required when rostering to this data stream"
    },
    "head_count_map": {
      "type": "string",
      "description": "The exact amounts of demand each team size can handle. This can be used to describe an 'economies of scale'"
    },
    "stat_type_id": {
      "type": "number"
    }
  },
  "required": [
    "id",
    "data_stream_id",
    "data_streamable_id",
    "data_streamable_type"
  ]
}
Headers
Content-Type: application/json
Body
{
  "data_stream_id": 24,
  "data_streamable_type": "Organisation",
  "stat_type_id": 123
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 162,
  "data_stream_id": 24,
  "data_streamable_id": null,
  "data_streamable_type": "Organisation",
  "rostering_ratio": 1.175,
  "stat_type_id": 123
}

Create Data Stream Join
POST/api/v2/datastreamjoins

This method requires the datastream scope (see Scopes for more information).


Data Stream Join

GET https://my.tanda.co/api/v2/datastreamjoins/162
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 162,
  "data_stream_id": 24,
  "data_streamable_id": 111,
  "data_streamable_type": "Department",
  "rostering_ratio": 1.175,
  "head_count_map": "\"1,2.5,5\""
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the data stream join"
    },
    "data_stream_id": {
      "type": "number",
      "description": "The id of the data stream join's data stream"
    },
    "data_streamable_id": {
      "type": "number",
      "description": "The id of the data stream join's data streamable (location or team)"
    },
    "data_streamable_type": {
      "type": "string",
      "description": "The type of the data stream join's data streamable (\"Location\", \"Department\", or \"Organisation\")"
    },
    "rostering_ratio": {
      "type": "number",
      "description": "The ratio of units to staff required when rostering to this data stream"
    },
    "head_count_map": {
      "type": "string",
      "description": "The exact amounts of demand each team size can handle. This can be used to describe an 'economies of scale'"
    }
  },
  "required": [
    "id",
    "data_stream_id",
    "data_streamable_id",
    "data_streamable_type"
  ]
}

Get Data Stream Join
GET/api/v2/datastreamjoins/{id}

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The id of the data stream join to lookup


PUT https://my.tanda.co/api/v2/datastreamjoins/162
RequestsUpdate Data Stream Join
Headers
Content-Type: application/json
Body
{
  "rostering_ratio": 1.5
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 162,
  "data_stream_id": 24,
  "data_streamable_id": 111,
  "data_streamable_type": "Department",
  "rostering_ratio": 1.5,
  "head_count_map": "\"1,2.5,5\""
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the data stream join"
    },
    "data_stream_id": {
      "type": "number",
      "description": "The id of the data stream join's data stream"
    },
    "data_streamable_id": {
      "type": "number",
      "description": "The id of the data stream join's data streamable (location or team)"
    },
    "data_streamable_type": {
      "type": "string",
      "description": "The type of the data stream join's data streamable (\"Location\", \"Department\", or \"Organisation\")"
    },
    "rostering_ratio": {
      "type": "number",
      "description": "The ratio of units to staff required when rostering to this data stream"
    },
    "head_count_map": {
      "type": "string",
      "description": "The exact amounts of demand each team size can handle. This can be used to describe an 'economies of scale'"
    }
  },
  "required": [
    "id",
    "data_stream_id",
    "data_streamable_id",
    "data_streamable_type"
  ]
}

Update Data Stream Join
PUT/api/v2/datastreamjoins/{id}

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The id of the data stream join to update


DELETE https://my.tanda.co/api/v2/datastreamjoins/162
Responses200
Headers
Content-Type: application/json

Delete Data Stream Join
DELETE/api/v2/datastreamjoins/{id}

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The id of the data stream join to delete


Store Stats

Our user guide has more information on working with data streams through the API.

Store stats are the individual statistics that belong to a Data Stream. All store stats for a data stream should be totaled data for a time period equal to the data stream’s data_interval, starting at the store stat’s time.

Only store stats where the type parameter is equal to “sales” will be displayed on the weekly planner on the dashboard. You’re able to store a wide variety of stats in Tanda, and differentiate them using the type parameter, but be aware of this special case.

Store stats can be read by a user, if that user is able to read the data stream that the store stat belongs to.

Only admins can create store stats. They are able to do this for any data stream.

Store Stats for Datastream

GET https://my.tanda.co/api/v2/storestats/for_datastream/26/?from=2016-03-01&to=2016-03-20&type=sales
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 3518,
    "time": 1459295100,
    "stat": 3.5,
    "type": "sales",
    "datastream_id": 24
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Store Stats for Datastream
GET/api/v2/storestats/for_datastream/{datastream_id}/{?from,to,type}

This method requires the datastream scope (see Scopes for more information).

You will only be able to query up to 31 days using the from and to parameters.

URI Parameters
HideShow
datastream_id
number (required) Example: 26

The id of the data stream to lookup store stats for

from
string (required) Example: 2016-03-01

The start date of the range to lookup store stats in

to
string (required) Example: 2016-03-20

The id of the data stream to lookup store stats for

type
string (optional) Example: sales

The type of store stats to lookup (if not specified, all stats are returned)


Create Store Stats for Datastream

POST https://my.tanda.co/api/v2/storestats/for_datastream/27
RequestsCreate single Store StatCreate multiple Store Stats
Headers
Content-Type: application/json
Body
{
  "time": 1459296900,
  "stat": 3.5,
  "type": "sales"
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 12231,
  "time": 1459296900,
  "stat": 3.5,
  "type": "sales",
  "datastream_id": 24
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the stat"
    },
    "time": {
      "type": "number",
      "description": "The time of the stat"
    },
    "stat": {
      "type": "number",
      "description": "The value of the stat"
    },
    "type": {
      "type": "string",
      "description": "The type of the stat"
    },
    "datastream_id": {
      "type": "number",
      "description": "The id of the data stream join's data stream"
    }
  },
  "required": [
    "id",
    "time",
    "stat",
    "type",
    "datastream_id"
  ]
}
Headers
Content-Type: application/json
Body
{
  "stats": [
    {
      "time": 1459296900,
      "stat": 3.5,
      "type": "sales"
    },
    {
      "time": 1459296900,
      "stat": 1,
      "type": "transactions"
    },
    {
      "time": 1459297800,
      "stat": 20.1,
      "type": "sales"
    }
  ]
}
Responses201
Headers
Content-Type: application/json
Body
[
  {
    "id": 12231,
    "time": 1459296900,
    "stat": 3.5,
    "type": "sales"
  },
  {
    "id": 12232,
    "time": 1459296900,
    "stat": 1,
    "type": "transactions"
  },
  {
    "id": 12233,
    "time": 1459297800,
    "stat": 20.1,
    "type": "sales"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Create Store Stats for Datastream
POST/api/v2/storestats/for_datastream/{datastream_id}

Store stats can either be posted one at a time, or in bulk. When posting store stats in bulk, all the store stats must be for the same data stream.

To post store stats in bulk, simply represent them all in an array, under the stats key. Note that each combination of time and type must be unique - you must not send duplicate data.

POSSIBLE DATA DELETION: All existing store stats on the data stream within the newly posted store stats’ time parameter range will be replaced with the newly posted store stats.

Please see the general Store Stat information above for an example.

{
  "stats": [
    {
      "time": 1459296900,
      "stat": 3.5,
      "type": "sales"
    },
    {
      "time": 1459297800,
      "stat": 1,
      "type": "transactions"
    }
  ]
}

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
datastream_id
number (required) Example: 27

The id of the data stream to create store stats on


Deleting Store Stats

POST https://my.tanda.co/api/v2/storestats/for_datastream

Deleting Store Stats
POST/api/v2/storestats/for_datastream

To remove store stats generated through the API for a time period, you will need to make a POST, and provide store stats with a 0 as the stat for the start and end of that period.

For example, if you wanted to remove sales and transactions store stats for the period of 1459296900 to 1459383300 then posting the following data to the Create Store Stats endpoint would “delete” that data. This is becuase each post actually overrides existing store stat data for the period.

{
  "stats": [
    {
      "time": 1459296900,
      "stat": 0,
      "type": "sales"
    },
    {
      "time": 1459296900,
      "stat": 0,
      "type": "transactions"
    },
    {
      "time": 1459383300,
      "stat": 0,
      "type": "sales"
    },
    {
      "time": 1459383300,
      "stat": 0,
      "type": "transactions"
    }
  ]
}

Create Store Stats for multiple Datastreams

POST https://my.tanda.co/api/v2/storestats/for_datastream
RequestsCreate single Store StatCreate multiple Store Stats
Headers
Content-Type: application/json
Body
{
  "datastream_id": 123457,
  "time": 1459296900,
  "stat": 3.5,
  "type": "sales"
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 12231,
  "time": 1459296900,
  "stat": 3.5,
  "type": "sales",
  "datastream_id": 123457
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the stat"
    },
    "time": {
      "type": "number",
      "description": "The time of the stat"
    },
    "stat": {
      "type": "number",
      "description": "The value of the stat"
    },
    "type": {
      "type": "string",
      "description": "The type of the stat"
    },
    "datastream_id": {
      "type": "number",
      "description": "The id of the data stream join's data stream"
    }
  },
  "required": [
    "id",
    "time",
    "stat",
    "type",
    "datastream_id"
  ]
}
Headers
Content-Type: application/json
Body
{
      "stats": [
        {
          "datastream_id": 123456,
          "time": 1459296900,
          "stat": 7.5,
          "type": "sales"
        },
        {
          "datastream_id": 123456,
          "time": 1459296900,
          "stat": 3,
          "type": "transactions"
        },
        {
          "datastream_id": 123457,
          "time": 1459297800,
          "stat": 3.5,
          "type": "sales"
        },
        {
          "datastream_id": 123457,
          "time": 1459297800,
          "stat": 1,
          "type": "transactions"
        }
        }
      ]
    }
Responses201
Headers
Content-Type: application/json
Body
[
  {
    "id": 12231,
    "datastream_id": 123456,
    "time": 1459296900,
    "stat": 7.5,
    "type": "sales"
  },
  {
    "id": 12232,
    "datastream_id": 123456,
    "time": 1459296900,
    "stat": 3,
    "type": "transactions"
  },
  {
    "id": 12233,
    "datastream_id": 123457,
    "time": 1459297800,
    "stat": 3.5,
    "type": "sales"
  },
  {
    "id": 12234,
    "datastream_id": 123457,
    "time": 1459297800,
    "stat": 1,
    "type": "transactions"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Create Store Stats for Multiple Datastreams
POST/api/v2/storestats/for_datastream

Store stats can either be posted one at a time, or in bulk. When posting store stats in bulk, all the store stats must be for the same data stream.

To post store stats in bulk, simply represent them all in an array, with the datastream_id included for each stat. Note that each combination of datastream_id, time and type must be unique - you must not send duplicate data.

POSSIBLE DATA DELETION: All existing store stats on the data stream within the newly posted store stats’ time parameter range will be replaced with the newly posted store stats.

Please see the general Store Stat information above for an example.

{
  "stats": [
    {
      "datastream_id": 123456,
      "time": 1459296900,
      "stat": 7.5,
      "type": "sales"
    },
    {
      "datastream_id": 123456,
      "time": 1459297800,
      "stat": 3,
      "type": "transactions"
    }
    {
      "datastream_id": 123457,
      "time": 1459296900,
      "stat": 3.5,
      "type": "sales"
    },
    {
      "datastream_id": 123457,
      "time": 1459297800,
      "stat": 1,
      "type": "transactions"
    }
  ]
}

Devices

Devices are physical time clocks that are used by employees for clocking in and out, a device has many Clock Ins.

Admins and department managers can read devices, and admins can and update all devices.

Device List

GET https://my.tanda.co/api/v2/devices
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 1234,
    "location_id": 111,
    "nickname": "Reactor Timeclock",
    "returned": false,
    "last_heard_from": 1459296900,
    "dispatch_date": "2016-01-02",
    "location_specific": false
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Devices
GET/api/v2/devices

This method requires the device scope (see Scopes for more information).

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified devices


POST https://my.tanda.co/api/v2/devices
RequestsCreate new timeclock
Headers
Content-Type: application/json
Body
{
  "nickname": "Old Reactor Timeclock",
  "location_id": 111
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1234,
  "location_id": 111,
  "nickname": "Old Reactor Timeclock",
  "returned": false,
  "last_heard_from": 1459296900,
  "dispatch_date": "2016-01-02",
  "location_specific": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the device"
    },
    "location_id": {
      "type": "number",
      "description": "The ID of the time clock's [location](#locations)."
    },
    "nickname": {
      "type": "string",
      "description": "The nickname of the device. If not provided, the location's name is used."
    },
    "returned": {
      "type": "boolean",
      "description": "Whether the device has been returned"
    },
    "last_heard_from": {
      "type": "number",
      "description": "The time that the device last communicated with the Tanda server"
    },
    "dispatch_date": {
      "type": "string",
      "description": "The date that the device was sent out"
    },
    "location_specific": {
      "type": "boolean",
      "description": "Whether the device is specific to the assigned location or not"
    }
  },
  "required": [
    "id",
    "nickname",
    "returned",
    "location_specific"
  ]
}

Create Device
POST/api/v2/devices

This method requires the device scope (see Scopes for more information).

Provide one or both of location_id and nickname when registering a time clock. If a location_id is provided, but a nickname isn’t, the location’s name is used as a nickname.

You can use the following attributes to store hardware information about the device: data_provider, mobile_number, sim_number, serial_number, imei, model.


Returned Device List

GET https://my.tanda.co/api/v2/devices/returned
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 8403,
    "location_id": 111,
    "nickname": "Meltdown Reactor Timeclock",
    "returned": true,
    "return_date": "2016-03-02",
    "last_heard_from": 1456877652,
    "dispatch_date": "2015-10-12",
    "location_specific": false
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Returned Devices
GET/api/v2/devices/returned

This method requires the device scope (see Scopes for more information).

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified returned devices


Device

GET https://my.tanda.co/api/v2/devices/1234
RequestsActive deviceReturned device
This response has no content.
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1234,
  "location_id": 111,
  "nickname": "Reactor Timeclock",
  "returned": false,
  "last_heard_from": 1459296900,
  "dispatch_date": "2016-01-02",
  "location_specific": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the device"
    },
    "location_id": {
      "type": "number",
      "description": "The ID of the time clock's [location](#locations)."
    },
    "nickname": {
      "type": "string",
      "description": "The nickname of the device. If not provided, the location's name is used."
    },
    "returned": {
      "type": "boolean",
      "description": "Whether the device has been returned"
    },
    "last_heard_from": {
      "type": "number",
      "description": "The time that the device last communicated with the Tanda server"
    },
    "dispatch_date": {
      "type": "string",
      "description": "The date that the device was sent out"
    },
    "location_specific": {
      "type": "boolean",
      "description": "Whether the device is specific to the assigned location or not"
    }
  },
  "required": [
    "id",
    "nickname",
    "returned",
    "location_specific"
  ]
}
This response has no content.
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 8403,
  "location_id": 111,
  "nickname": "Meltdown Reactor Timeclock",
  "returned": true,
  "return_date": "2016-03-02",
  "last_heard_from": 1456877652,
  "dispatch_date": "2015-10-12",
  "location_specific": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the device"
    },
    "location_id": {
      "type": "number",
      "description": "The ID of the time clock's [location](#locations)."
    },
    "nickname": {
      "type": "string",
      "description": "The nickname of the device. If not provided, the location's name is used."
    },
    "returned": {
      "type": "boolean",
      "description": "Whether the device has been returned"
    },
    "return_date": {
      "type": "string",
      "description": "The date the device was returned"
    },
    "last_heard_from": {
      "type": "number",
      "description": "The time that the device last communicated with the Tanda server"
    },
    "dispatch_date": {
      "type": "string",
      "description": "The date that the device was sent out"
    },
    "location_specific": {
      "type": "boolean",
      "description": "Whether the device is specific to the assigned location or not"
    }
  },
  "required": [
    "id",
    "nickname",
    "returned",
    "return_date",
    "location_specific"
  ]
}

Get Device
GET/api/v2/devices/{id}

This method requires the device scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 1234

The id of the device to lookup


PUT https://my.tanda.co/api/v2/devices/1234
RequestsUpdate device information
Headers
Content-Type: application/json
Body
{
  "nickname": "Old Reactor Timeclock",
  "location_id": 111
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1234,
  "location_id": 111,
  "nickname": "Old Reactor Timeclock",
  "returned": false,
  "last_heard_from": 1459296900,
  "dispatch_date": "2016-01-02",
  "location_specific": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the device"
    },
    "location_id": {
      "type": "number",
      "description": "The ID of the time clock's [location](#locations)."
    },
    "nickname": {
      "type": "string",
      "description": "The nickname of the device. If not provided, the location's name is used."
    },
    "returned": {
      "type": "boolean",
      "description": "Whether the device has been returned"
    },
    "last_heard_from": {
      "type": "number",
      "description": "The time that the device last communicated with the Tanda server"
    },
    "dispatch_date": {
      "type": "string",
      "description": "The date that the device was sent out"
    },
    "location_specific": {
      "type": "boolean",
      "description": "Whether the device is specific to the assigned location or not"
    }
  },
  "required": [
    "id",
    "nickname",
    "returned",
    "location_specific"
  ]
}

Update Device
PUT/api/v2/devices/{id}

This method requires the device scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 1234

The id of the device to edit


Return Device

POST https://my.tanda.co/api/v2/devices/1234/return
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1234,
  "location_id": 111,
  "nickname": "Reactor Timeclock",
  "returned": "true",
  "last_heard_from": 1459296900,
  "dispatch_date": "2016-01-02",
  "location_specific": false,
  "return_date": "2016-04-01"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the device"
    },
    "location_id": {
      "type": "number",
      "description": "The ID of the time clock's [location](#locations)."
    },
    "nickname": {
      "type": "string",
      "description": "The nickname of the device. If not provided, the location's name is used."
    },
    "returned": {
      "type": "string",
      "description": "Whether the device has been returned"
    },
    "last_heard_from": {
      "type": "number",
      "description": "The time that the device last communicated with the Tanda server"
    },
    "dispatch_date": {
      "type": "string",
      "description": "The date that the device was sent out"
    },
    "location_specific": {
      "type": "boolean",
      "description": "Whether the device is specific to the assigned location or not"
    },
    "return_date": {
      "type": "string",
      "description": "The date the device was returned"
    }
  },
  "required": [
    "id",
    "nickname",
    "returned",
    "location_specific"
  ]
}

Return Device
POST/api/v2/devices/{id}/return

This method requires the device scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 1234

The id of the device to return


Device Versions

GET https://my.tanda.co/api/v2/devices/1234/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"Device\"",
    "changes": [
      {
        "field": "nickname",
        "previous": "Breakroom",
        "updated": "Reactor Timeclock"
      },
      {
        "field": "location_id",
        "previous": 111,
        "updated": 112
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Device Versions
GET/api/v2/devices/{id}/versions

This method requires the device scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 1234

The id of the device

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified device versions


Device Access Code

POST https://my.tanda.co/api/v2/devices/reset_access_code
Responses200
Headers
Content-Type: application/json
Body
{
  "access_code": "12345678"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "access_code": {
      "type": "string",
      "description": "Randomly generated 8 digit string"
    }
  },
  "required": [
    "access_code"
  ]
}

Reset Device Access Code
POST/api/v2/devices/reset_access_code

This method requires the device scope (see Scopes for more information).

The access code is used by admins when setting up a device as an alternative to entering their username and password.


Clock Ins

Clock ins represent actual times that the employee arrived and left from a location (most often a work site or office).

You must be able to manage the user to make a clock in for them. To read clock ins for a user or device, the user must be able to manage the the user, or read the device respectively.

Clock In

POST https://my.tanda.co/api/v2/clockins
RequestsClock InClock OutSpecific Photo & Time ClockSpecific TeamBad ImageImage Too LargeAnswer to TC Question
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "type": "start",
  "time": 1459296192
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 6108,
  "user_id": 123456,
  "device_id": 1234,
  "time": 1459296192,
  "type": "start",
  "latitude": null,
  "longitude": null,
  "photo": null,
  "department_id": null,
  "shift_id": null,
  "removed": false
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "type": "finish",
  "time": 1459296192
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 6108,
  "user_id": 123456,
  "device_id": 1234,
  "time": 1459296192,
  "type": "finish",
  "latitude": null,
  "longitude": null,
  "photo": null,
  "department_id": null,
  "shift_id": null,
  "removed": false
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "type": "start",
  "time": 1459296192,
  "device_id": 1234,
  "photo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAaCAI..."
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 6108,
  "user_id": 123456,
  "device_id": 1234,
  "time": 1459296192,
  "type": "start",
  "latitude": null,
  "longitude": null,
  "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
  "department_id": null,
  "shift_id": null,
  "removed": false
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "type": "start",
  "time": 1459296192,
  "department_id": 808
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 6108,
  "user_id": 123456,
  "device_id": 1234,
  "time": 1459296192,
  "type": "start",
  "latitude": null,
  "longitude": null,
  "photo": null,
  "department_id": 808,
  "shift_id": null,
  "removed": false
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "type": "start",
  "time": 1459296192,
  "department_id": 808,
  "photo": "non-base64 png string"
}
Responses400
Headers
Content-Type: application/json
Body
{
  "error": "Photo parameter is not a valid base64 string!"
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "type": "start",
  "time": 1459296192,
  "department_id": 808,
  "photo": "very large base64 string"
}
Responses400
Headers
Content-Type: application/json
Body
{
  "error": "Photo is too large. File size limit is 5 MB."
}
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "type": "finish",
  "time": 1459296192,
  "answers": [
    {
      "timeclock_question_id": 42,
      "answer": 63.4,
      "trigger": "finish"
    }
  ]
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 6108,
  "user_id": 123456,
  "device_id": 1234,
  "time": 1459296192,
  "type": "start",
  "latitude": null,
  "longitude": null,
  "photo": null,
  "department_id": null,
  "shift_id": null,
  "removed": false
}

Perform Clock In for User
POST/api/v2/clockins

Use this endpoint to send clock ins to Tanda in “real time” as employees clock in or out of work. The clock in will be stored as a distinct object in Tanda, but will also be copied to a Shift, which will then be visible on a Timesheets. When posting clockins to Tanda, here’s a few things to be aware of:


Time rounding

It is possible in Tanda to configure rounding settings, to do things like round clock in times to the nearest 5 minutes. At the very least, the clock in time will be rounded to the floor of the minute when processed. Therefore, you should not expect that you will find a Shift in Tanda with exactly the same start or end time as the time that you provide here. Employees in Tanda are paid based on the output of Timesheets & Shifts, not of Clock Ins, so if you want to adjust a clocked time later you should adjust the relevant Shift instead.

De-duplication

If two very similar clock ins are posted one after the other (eg. two clock ins with the same type, and times within a few minutes of each other) then it is possible that Tanda will discard one. The intent of this logic is to prevent issues like people “misclicking” on physical time clocks. If you want complete control over how a Shift will be displayed in Tanda, use the Shifts endpoint. When querying for Clock Ins directly, any Clock In with true in its removed field has been removed from the Shift as another Clock In has replaced it.

Non-immediate processing

This endpoint will return a 201 HTTP status with the newly created Clock In if the request was valid. At this point the shift_id will be null. There will be a short delay between the Clock In being created, and it being processed. This processing entails adding the Clock In to a Timesheet, and recalculating the Timesheet’s costs. Once the Clock In has been processed, the shift_id field will be updated to be the ID of the Shift that the Clock In was applied to. During processing, if the Clock In is considered to be a duplicate, or needs to be discarded for any other reason, it may never be applied to a Shift. If this is the case, the removed field will be true.

Clock Ins are copied to timesheets

Use the Timesheets and Shifts endpoints to see the net result of your Clock Ins on staff timesheets. You can lookup clock ins using the Get Clock Ins endpoint, and once the clock in has been processed, you can use its shift_id to lookup the shift it applied to. Additionally, you can use either the Clock Ins for User, or the Clock Ins for Device methods, to view raw Clock Ins created through this endpoint.

Clock In image format

Images on Clock Ins are optional. However, if you wish to include an image with a Clock In, the image must be a base64 PNG or JPEG using the Data URI scheme. An example encoded image can be seen below:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==

If you do choose to provide an image, and the image isn’t in the correct format, you will receive a response with a 400 HTTP status. An example of the response can be seen on the right.

Don’t predict the future

Clock Ins with times more than 10 minutes into the future (as computed at the server’s time) will be rejected. Ensure your client’s time is correct.


The following fields are supported when clocking in or out. Examples of all these fields can be seen in the sidebar to the right.

  • user_id - required, integer - the ID of the User clocking in or out.

  • type - required, string - must be either start, finish, break_start, or break_finish.

  • time - required, integer - a unix timestamp representing when the clock in or out happened. This time cannot be in the future.

  • device_id - required, integer - the ID of the Time Clock used to clock in or out. Used to verify the location the clock in took place at.

  • photo - optional, string - a photo of the user clocking in. If provided, must be a base64 encoded PNG or JPEG image. The size of the PNG image (decoded) must not exceed 5MB in size.

  • department_id - optional, integer - the Team being clocked in to. If provided, the User must already be in this Team (otherwise it will be ignored). This will show on the user’s timesheet.

  • answers - optional, array of objects - one or more answers to timeclock questions. For each object, a timeclock_question_id, trigger, and answer are required. There is no validation performed on this - if your answer is invalid, it will be silently ignored. If you need validation, send a POST to the timeclock question answers endpoint.

This method requires the device scope (see Scopes for more information).

You will only be able to clock in for users you can manage, on devices you can see.


Clock In List

GET https://my.tanda.co/api/v2/clockins?user_id=123456&from=2016-03-15&to=2016-04-05
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 6108,
    "user_id": 123456,
    "device_id": 1234,
    "time": 1459209907,
    "type": "start",
    "latitude": -27.459687,
    "longitude": 153.032108,
    "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
    "department_id": 808,
    "shift_id": 1337,
    "removed": false
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Clock Ins for User
GET/api/v2/clockins{?user_id,from,to}

Both from and to are required, and at least one of user_id and device_id are required.

To get a list of users who are clocked in right now, use the Get Clocked In Users endpoint.

This method requires the device scope (see Scopes for more information).

You will only be able to query up to 31 days using the from and to parameters.

URI Parameters
HideShow
user_id
number (required) Example: 123456

The id of the user to lookup clock ins for

from
string (required) Example: 2016-03-15

From date to lookup clock ins within

to
string (required) Example: 2016-04-05

To date to lookup clock ins within

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified clock ins


GET https://my.tanda.co/api/v2/clockins?device_id=1234&from=2016-03-15&to=2016-04-05
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 6108,
    "user_id": 123456,
    "device_id": 1234,
    "time": 1459209907,
    "type": "start",
    "latitude": -27.459687,
    "longitude": 153.032108,
    "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
    "department_id": 808,
    "shift_id": 1337,
    "removed": false
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Clock Ins for Device
GET/api/v2/clockins{?device_id,from,to}

Both from and to are required, and at least one of user_id and device_id are required.

This method requires the device scope (see Scopes for more information).

You will only be able to query up to 31 days using the from and to parameters.

URI Parameters
HideShow
device_id
number (required) Example: 1234

The id of the device to lookup clock ins for

from
string (required) Example: 2016-03-15

From date to lookup clock ins within

to
string (required) Example: 2016-04-05

To date to lookup clock ins within

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified clock ins


GET https://my.tanda.co/api/v2/clockins?user_id=123456&device_id=1234&from=2016-03-15&to=2016-04-05
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 6108,
    "user_id": 123456,
    "device_id": 1234,
    "time": 1459209907,
    "type": "start",
    "latitude": -27.459687,
    "longitude": 153.032108,
    "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
    "department_id": 808,
    "shift_id": 1337,
    "removed": false
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Clock Ins for User on Device
GET/api/v2/clockins{?user_id,device_id,from,to}

Both from and to are required, and at least one of user_id and device_id are required.

This method requires the device scope (see Scopes for more information).

You will only be able to query up to 31 days using the from and to parameters.

URI Parameters
HideShow
user_id
number (required) Example: 123456

The id of the user to lookup clock ins for

device_id
number (required) Example: 1234

The id of the device to lookup clock ins for

from
string (required) Example: 2016-03-15

From date to lookup clock ins within

to
string (required) Example: 2016-04-05

To date to lookup clock ins within

updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified clock ins


Clock In

GET https://my.tanda.co/api/v2/clockins/6108
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 6108,
  "user_id": 123456,
  "device_id": 1234,
  "time": 1459209907,
  "type": "start",
  "latitude": -27.459687,
  "longitude": 153.032108,
  "photo": "http://vignette1.wikia.nocookie.net/family-guyamerican-dadthe-simpsons-and-futurama/images/f/ff/250px-Lenny_Leonard.png",
  "department_id": 808,
  "shift_id": 1337,
  "removed": false
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the clock in"
    },
    "user_id": {
      "type": "number",
      "description": "The id of the user clocking in"
    },
    "device_id": {
      "type": "number",
      "description": "The id of the time clock the user clocks in using. If not provided a generic time clock record will be used."
    },
    "time": {
      "type": "number",
      "description": "The time the clock in was made"
    },
    "type": {
      "type": "string",
      "description": "`start`, `finish`, `break_start`, or `break_finish`"
    },
    "latitude": {
      "type": "number",
      "description": "The latitude of the clock in"
    },
    "longitude": {
      "type": "number",
      "description": "The longitude of the clock in"
    },
    "photo": {
      "type": "string",
      "description": "The photo the device took when the user clocked in"
    },
    "department_id": {
      "type": "number",
      "description": "The id of the department the clock in (if clock in was for a specific department)"
    },
    "shift_id": {
      "type": "number",
      "description": "The id of the shift the clock in got applied to (will be nil until the clock in has been processed)"
    },
    "removed": {
      "type": "boolean",
      "description": "True if the clock in was removed from the shift due to de-duplication or another reason, see the Clock In endpoint for more information"
    }
  },
  "required": [
    "id",
    "user_id",
    "time",
    "type",
    "removed"
  ]
}

Get Clock In
GET/api/v2/clockins/{id}

For information about how clock ins work, please see the Perform Clock In for User endpoint.

This method requires the device scope (see Scopes for more information).

You will only be able to see clock ins for users you can manage, or for devices you can see.

URI Parameters
HideShow
id
number (required) Example: 6108

The id of the clockin to lookup


Qualifications

The Qualifications Feature needs to be enabled before you can access this endpoint.

Qualifications List

GET https://my.tanda.co/api/v2/qualifications
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 123706,
    "name": "Blue Card",
    "maximum_hours": 21.34
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Qualifications
GET/api/v2/qualifications

This method requires the qualifications scope (see Scopes for more information).


POST https://my.tanda.co/api/v2/qualifications
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "name": "Responsible Service of Alcohol",
  "maximum_hours": 20.5
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123706,
  "name": "Responsible Service of Alcohol",
  "maximum_hours": "20.5"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The qualification ID"
    },
    "name": {
      "type": "string",
      "description": "The name of the qualification"
    },
    "maximum_hours": {
      "type": "string",
      "description": "Maximum number of hours that can be worked per week if this qualification is enabled"
    }
  },
  "required": [
    "id",
    "name"
  ]
}

Create Qualification
POST/api/v2/qualifications

Once created, a qualification will be visible in your qualifications list. Use its ID to add it to staff profiles, and to teams.

This method requires the qualifications scope (see Scopes for more information).


Qualification

GET https://my.tanda.co/api/v2/qualifications/123706
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123706,
  "name": "Blue Card",
  "maximum_hours": 21.34
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The qualification ID"
    },
    "name": {
      "type": "string",
      "description": "The name of the qualification"
    },
    "maximum_hours": {
      "type": "number",
      "description": "Maximum number of hours that can be worked per week if this qualification is enabled"
    }
  },
  "required": [
    "id",
    "name"
  ]
}

Get Qualification
GET/api/v2/qualifications/{id}

This method requires the qualifications scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123706

The id of the qualification


PUT https://my.tanda.co/api/v2/qualifications/123706
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "name": "RSA v2"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123706,
  "name": "RSA v2",
  "maximum_hours": 21.34
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The qualification ID"
    },
    "name": {
      "type": "string",
      "description": "The name of the qualification"
    },
    "maximum_hours": {
      "type": "number",
      "description": "Maximum number of hours that can be worked per week if this qualification is enabled"
    }
  },
  "required": [
    "id",
    "name"
  ]
}

Update Qualification
PUT/api/v2/qualifications/{id}

This method requires the qualifications scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123706

The id of the qualification to edit


DELETE https://my.tanda.co/api/v2/qualifications/123706
Responses200
Headers
Content-Type: application/json

Delete Qualification
DELETE/api/v2/qualifications/{id}

Deleting a qualification will also remove it from associated staff and teams.

This method requires the qualifications scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123706

The id of the qualification


System Settings

System settings are accessible through the API if they are visible on the Tanda settings page. Please refer to the settings page inside Tanda for up to date documentation on each setting and the options available.

Only admins are able to access settings.

Settings

GET https://my.tanda.co/api/v2/settings
Responses200
Headers
Content-Type: application/json
Body
{
  "enable_availability": false,
  "unavailability_minimum_date": "2016-02-29",
  "enable_employee_leave": true,
  "leave_request_default_length": 7.6
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "enable_availability": {
      "type": "boolean",
      "description": "Employees can use an app to enter unavailability"
    },
    "unavailability_minimum_date": {
      "type": "string",
      "description": "The earliest date for which Unavailability can be entered."
    },
    "enable_employee_leave": {
      "type": "boolean",
      "description": "Allow employees to enter leave requests through Tanda"
    },
    "leave_request_default_length": {
      "type": "number",
      "description": "Default leave request length (hours)"
    }
  }
}

Get Settings
GET/api/v2/settings

This method requires the settings scope (see Scopes for more information).

The full range of properties that are returned may vary on a per-user basis. To the right is a sample, to illustrate the structure of responses. Therefore, your code should gracefully handle the condition where a particular key is not present.


Settings Versions

GET https://my.tanda.co/api/v2/settings/versions
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "version_id": 123456,
    "time": 1459209907,
    "event": "update",
    "author": {
      "id": 123456,
      "name": "API v2"
    },
    "item_id": 1235435,
    "item_type": "\"Setting\"",
    "changes": [
      {
        "field": "enable_availability",
        "previous": true,
        "updated": false
      },
      {
        "field": "unavailability_minimum_days",
        "previous": 3,
        "updated": 4
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Settings Versions
GET/api/v2/settings/versions

This method requires the settings scope (see Scopes for more information).

The full range of properties that are returned may vary on a per-user basis. To the right is a sample, to illustrate the structure of responses. Therefore, your code should gracefully handle the condition where a particular key is not present.

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified settings versions


Award Templates

Use the award templates endpoint to read and update which managed awards an organisation has enabled.

Only admins are able to access this endpoint.

Award Templates List

GET https://my.tanda.co/api/v2/award_templates
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "award_template_id": 990,
    "name": "Clerks Private Sector",
    "identifier": "MA000002",
    "award_template_organisation_id": 5624432
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Enabled Award Templates
GET/api/v2/award_templates

This method returns a list of award templates enabled for the API user’s organisation.

This method requires the settings scope (see Scopes for more information).

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified award templates

include_custom_award_templates
boolean (optional) Example: false

If true, award template organisation will be included in the response. Defaults to false.


POST https://my.tanda.co/api/v2/award_templates
RequestsEnable Award TemplateEnable Award Template With Leave Types Extracted
Headers
Content-Type: application/json
Body
{
  "award_template_id": 990,
}
Responses200
Headers
Content-Type: application/json
Body
{
  "award_template_id": 990,
  "name": "Clerks Private Sector",
  "identifier": "MA000002",
  "award_template_organisation_id": 5624432
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "award_template_id": {
      "type": "number",
      "description": "The award template ID"
    },
    "name": {
      "type": "string",
      "description": "The name of the award or EBA"
    },
    "identifier": {
      "type": "string",
      "description": "An identifier for the award or EBA"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The internal ID linking this template to the organisation (if linked)"
    }
  },
  "required": [
    "award_template_id"
  ]
}
Headers
Content-Type: application/json
Body
{
  "award_template_id": 990,
  "extract_leave_types": true,
  "replace_leave_types": true
}
Responses200
Headers
Content-Type: application/json
Body
{
  "award_template_id": 990,
  "name": "Clerks Private Sector",
  "identifier": "MA000002",
  "award_template_organisation_id": 5624432
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "award_template_id": {
      "type": "number",
      "description": "The award template ID"
    },
    "name": {
      "type": "string",
      "description": "The name of the award or EBA"
    },
    "identifier": {
      "type": "string",
      "description": "An identifier for the award or EBA"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The internal ID linking this template to the organisation (if linked)"
    }
  },
  "required": [
    "award_template_id"
  ]
}

Enable Award Template
POST/api/v2/award_templates

Use this method to enable an award template for a particular organisation. A single field, the award_template_id, is required. This field is unique across Tanda. You can get a list of valid IDs by making a call to the available award templates method.

This method enables the award template, then triggers a background job to populate the Tanda organisation with the relevant payroll rules and allowances. It may take up to several hours for those to be created and costing information to be updated.

If you include the extract_leave_types parameter with a value of true, any leave types included in the template will be made user-visible and user-editable. The default is false which means that leave types will be managed by the template after it’s created.

If you include the replace_leave_types parameter with a value of true, any existing leave types in the organisation prior to the award template’s being added will be removed. The default is false which will not alter existing leave types.

This method requires the settings scope (see Scopes for more information).


Award Templates List

GET https://my.tanda.co/api/v2/award_templates/available
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "award_template_id": 990,
    "name": "Clerks Private Sector",
    "identifier": "MA000002",
    "award_template_organisation_id": 5624432
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Available Award Templates
GET/api/v2/award_templates/available

This method returns a full list of award templates available in Tanda.

This method requires the settings scope (see Scopes for more information).


Organisations

Use the organisations endpoint to get a list of clients you manage, and register new clients. If you have access to this endpoint, you can also get access tokens for clients you manage.

To get access to this endpoint, please contact Tanda.

Organisation List

GET https://my.tanda.co/api/v2/organisations
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 747,
    "name": "Tom's Restaurant",
    "payroll_system": "myob",
    "country": "Australia",
    "locale": "en",
    "time_zone": "Brisbane",
    "industry": "The organisation's industry",
    "customer_ids": [
      748,
      749
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Organisations
GET/api/v2/organisations

This method requires the organisation scope (see Scopes for more information).

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified organisations


POST https://my.tanda.co/api/v2/organisations
RequestsCreate Organisation
Headers
Content-Type: application/json
Body
{
  "name": "Vandelay Industries",
  "country": "New Zealand",
  "locale": "en-NZ",
  "timesheet_interval": 1,
  "week_start_day": 0,
  "time_zone": "Auckland",
  "award_template_ids": [
    1,
    2,
    3
  ],
  "customer_ids": []
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 748,
  "name": "Vandelay Industries",
  "payroll_system": "myob",
  "country": "New Zealand",
  "locale": "en",
  "time_zone": "Auckland",
  "industry": "The organisation's industry",
  "customer_ids": []
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "Organisation's unique ID"
    },
    "name": {
      "type": "string",
      "description": "The organisation's name"
    },
    "payroll_system": {
      "type": "string",
      "description": "The payroll software used by the organisation"
    },
    "country": {
      "type": "string",
      "description": "The country in which the organisation is legally based"
    },
    "locale": {
      "type": "string",
      "description": "NZ"
    },
    "time_zone": {
      "type": "string",
      "description": "The organisation's time zone name"
    },
    "industry": {
      "type": "string"
    },
    "customer_ids": {
      "type": "array",
      "description": "Organisation IDs for customers of this organisation"
    }
  },
  "required": [
    "id",
    "name",
    "country"
  ]
}

Create Organisation
POST/api/v2/organisations

This method requires the organisation scope (see Scopes for more information).

The following fields can be used when creating a new organisation:

  • name - required, string - the organisation’s name.

  • country - required, string - the country the organisation is legally established in.

  • timesheet_interval - required, integer - 1 for weekly timesheets, 2 for fortnightly timesheets.

  • week_start_day - required, integer - the day of the week that timesheets should start on. 0 is Sunday, 1 is Monday, and so on.

  • locale - optional, string - the language tag for system translation. Defaults to en. Click here for more information.

  • time_zone - optional, string - the time zone for the new organisation. If not provided, defaults to authenticated user’s time zone. Uses zone names from here, eg “Brisbane” or “Perth”.

  • award_template_ids - optional, array[integer] - IDs of award templates you’d like to make available to this organisation. Note that you’ll still need to enable the award template once the organisation is created.

  • industry - optional, string - the industry the organisation belongs to. e.g. ‘Aged Care’.

  • customer_ids - optional, array[integer] - IDs of other organisations which are customers of this organisation. This organisation will be able to access its customers and impersonate users within them through the Tanda UI.


Organisation

GET https://my.tanda.co/api/v2/organisations
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 747,
  "name": "Tom's Restaurant",
  "payroll_system": "myob",
  "country": "Australia",
  "locale": "en",
  "time_zone": "Brisbane",
  "industry": "The organisation's industry",
  "customer_ids": [
    748,
    749
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "Organisation's unique ID"
    },
    "name": {
      "type": "string",
      "description": "The organisation's name"
    },
    "payroll_system": {
      "type": "string",
      "description": "The payroll software used by the organisation"
    },
    "country": {
      "type": "string",
      "description": "The country in which the organisation is legally based"
    },
    "locale": {
      "type": "string",
      "description": "The i18n locale for the organisation"
    },
    "time_zone": {
      "type": "string",
      "description": "The organisation's time zone name"
    },
    "industry": {
      "type": "string"
    },
    "customer_ids": {
      "type": "array",
      "description": "Organisation IDs for customers of this organisation"
    }
  },
  "required": [
    "id",
    "name",
    "country"
  ]
}

Get Organisation
GET/api/v2/organisations

Get an organisation by id.

This method requires the organisation scope (see Scopes for more information).


PUT https://my.tanda.co/api/v2/organisations/747
RequestsAdd CustomerClear Customers
Headers
Content-Type: application/json
Body
{
  "customer_ids": [
    737,
    727
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 747,
  "name": "Tom's Restaurant",
  "payroll_system": "myob",
  "country": "Australia",
  "locale": "en",
  "time_zone": "Brisbane",
  "industry": "The organisation's industry",
  "customer_ids": [
    727,
    737
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "Organisation's unique ID"
    },
    "name": {
      "type": "string",
      "description": "The organisation's name"
    },
    "payroll_system": {
      "type": "string",
      "description": "The payroll software used by the organisation"
    },
    "country": {
      "type": "string",
      "description": "The country in which the organisation is legally based"
    },
    "locale": {
      "type": "string",
      "description": "The i18n locale for the organisation"
    },
    "time_zone": {
      "type": "string",
      "description": "The organisation's time zone name"
    },
    "industry": {
      "type": "string"
    },
    "customer_ids": {
      "type": "array",
      "description": "Organisation IDs for customers of this organisation"
    }
  },
  "required": [
    "id",
    "name",
    "country"
  ]
}
Headers
Content-Type: application/json
Body
{
  "customer_ids": []
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 747,
  "name": "Tom's Restaurant",
  "payroll_system": "myob",
  "country": "Australia",
  "locale": "en",
  "time_zone": "Brisbane",
  "industry": "The organisation's industry",
  "customer_ids": []
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "Organisation's unique ID"
    },
    "name": {
      "type": "string",
      "description": "The organisation's name"
    },
    "payroll_system": {
      "type": "string",
      "description": "The payroll software used by the organisation"
    },
    "country": {
      "type": "string",
      "description": "The country in which the organisation is legally based"
    },
    "locale": {
      "type": "string",
      "description": "The i18n locale for the organisation"
    },
    "time_zone": {
      "type": "string",
      "description": "The organisation's time zone name"
    },
    "industry": {
      "type": "string"
    },
    "customer_ids": {
      "type": "array",
      "description": "Organisation IDs for customers of this organisation"
    }
  },
  "required": [
    "id",
    "name",
    "country"
  ]
}

Update Organisation
PUT/api/v2/organisations/{id}

This method requires the organisation scope (see Scopes for more information).

The following fields can be updated using this endpoint:

  • name - required, string - the organisation’s name.

  • country - required, string - the country the organisation is legally established in.

  • locale - optional, string - the language tag for system translation. Defaults to en. Click here for more information.

  • award_template_ids - optional, array[integer] - IDs of award templates you’d like to make available to this organisation. Note that you’ll still need to enable the award template once the organisation is created.

  • industry - optional, string - the industry the organisation belongs to. e.g. ‘Aged Care’.

  • customer_ids - optional, array[integer] - IDs of other organisations which are customers of this organisation. This organisation will be able to access its customers and impersonate users within them through the Tanda UI.

URI Parameters
HideShow
id
number (required) Example: 747

The ID of the organisation


Organisation Access Tokens

POST https://my.tanda.co/api/oauth/token
RequestsCreate Access Token
Body
curl https://my.tanda.co/api/oauth/token -X POST -H "Cache-Control: no-cache" \
-F "access_token=YOUR_CURRENT_ACCESS_TOKEN" \
-F "organisation_id=747" \
-F "scope=user me" \
-F "grant_type=partner_token"
Responses200
Body
{
  "access_token": "6833b9ecaa84ce420da3cafaa43124d241cb28b5287b72d131f6b38bcb64cd91",
  "token_type": "bearer",
  "scope": "user me",
  "created_at": 1457304578
}

Create Access Token
POST/api/oauth/token

Use this endpoint to get an access token for an organisation that you have read access to. To request a token, make a POST to /api/oauth/token - the same path you would use to request a regular Password access token. Supply these fields:

  • access_token - required, string - your current valid access token (the one you use to get a list of organisations)

  • organisation_id - required, integer - the organisation you’d like to get an access token for - get this from the list of organisations

  • scope - required, string - one or more Scopes separated by spaces

  • grant_type - required, string - must be partner_token

The right sidebar contains an example access token reques & response. The access token in the response will give you access to the organisation ID provided in the request.


Personal Details

View & update personal details.

All endpoints here require the personal scope. Some endpoints require the financial scope to view financial data, or the user scope to view data about an employee.

Your Personal Details

These details will apply to all accounts linked under your profile

GET https://my.tanda.co/api/v2/personal_details
Responses200
Headers
Content-Type: application/json
Body
{
  "email": "bartsimpson@tanda.co",
  "gender": "male",
  "emergency_contacts": [
    {
      "name": "Marge Simpson",
      "relationship": "Mom",
      "phone": "0400 000 000"
    }
  ]
}

Get Personal Details
GET/api/v2/personal_details

Gets the personal details of the currently authenticated user

This method requires the personal scope.

To retrieve financial information, such as a Tax File Number, you must also have the financial scope.


PUT https://my.tanda.co/api/v2/personal_details

Update Personal Details
PUT/api/v2/personal_details

Update the currently authenticated user’s personal details.

Any emergency_contacts provided will be appended to existing emergency contacts.


Employee's Personal Details

GET https://my.tanda.co/api/v2/personal_details/123456
Responses200
Headers
Content-Type: application/json
Body
{
  "email": "bartsimpson@tanda.co",
  "gender": "male",
  "emergency_contacts": [
    {
      "id": 1234,
      "name": "Marge Simpson",
      "relationship": "Mom",
      "phone": "0400 000 000"
    }
  ]
}

Get Employee's Personal Details
GET/api/v2/personal_details/{user_id}

This endpoint requires the user and personal scopes. The authenticated user must also be a manager of the employee identified by user_id. The financial scope is required to see financial data.

URI Parameters
HideShow
user_id
number (required) Example: 123456

The id of the user


PUT https://my.tanda.co/api/v2/personal_details/123456

Update Employee's Personal Details
PUT/api/v2/personal_details/{user_id}

Update a user’s personal details.

This endpoint requires the user and personal scopes. The authenticated user must also be a manager of the employee identified by user_id. The financial scope is required to see financial data.

Any emergency_contacts provided will be appended to existing emergency contacts.

URI Parameters
HideShow
user_id
number (required) Example: 123456

The ID of the user


Webhooks

Get notified when things happen inside Tanda.

Check out our user guide to walk you through setting up a Webhook - there’s no programming knowledge required!

There are three concepts to understand when working with webhooks:

  • Topics: a topic is a type of event that can happen inside Tanda, for example “user.created” or “clockin.updated” - a full list of topics can be found below.

  • Subscriptions: a subscription is comprised of a URL (where we send the notification payload) and the specific events in Tanda (topics) you want sent to the URL, think of these as the events you have subscribed to be notified about.

  • Notifications: a notification is a HTTP POST request we make to the URL you configure in the subscription. All notifications received will follow the format outlined in the notification payload section below.

Notification Payload

Headers

Content-Length: 475
Content-Type: application/json
X-Webhook-Signature: g7LZCBPlwBg1vid0dOHgt7HToR0=

Payload

{
  "hook_key": "",
  "hook_time": "",
  "payload": {
    "organisation_id": "",
    "body": {},
    "topic": ""
  }
}
  • hook_key: The hook_key is a UUID associated with the webhook event, if you’re worried about duplications interfering with your integration, use this to dedup.

  • hook_time: The hook_time is the time the event was emitted in epoch format.

  • body: The contents of the payload.body depend upon what topic the subscription is for, for each topic you can generally find the payload body under the corresponding API endpoint documentation e.g. a subscription to the leaverequest.created event will have the same fields as the response to the endpoint to create a leave request.

  • topic: This is the topic name as detailed in the ‘Topic’ column below.

Available Topics

TopicDescription
clockin.updatedSent when a clockin is updated, for example to get a shift ID attached post-processing. Not sent for when a clockin with a photo is processed, use clockin.photo for this.
clockin.photoSent when a clockin with a photo is processed. Not all clockins have photos, so this will be a subset of clockin.updated.
department.createdSent when a team is created.
department.updatedSent when a team is updated.
department.destroyedSent when a team is destroyed.
leaverequest.approvedSent when a leave request is approved.
leaverequest.createdSent when a leave request is created.
leaverequest.rejectedSent when a leave request is rejected.
leaverequest.updatedSent when a leave request is updated (this includes approval and rejection).
schedule.createdSent when a schedule is created (doesn't send for roster templates).
schedule.updatedSent when a schedule is changed (doesn't send for roster templates).
schedule.destroyedSent when a schedule is deleted (doesn't send for roster templates).
schedule.publishedSent when a schedule is sent to an employee by email or SMS, or when it's printed
shift.approvedSent when a shift is approved.
shift.unapprovedSent when a shift is unapproved.
shift.updatedSent when a shift is changed (includes approval).
super_fund_membership.updatedSent when a user's super fund membership is changed.
timesheet.approvedSent when a timesheet is approved.
timesheet.exportedSent when a timesheet is exported.
timesheet.costedSent when a timesheet is recalculated due to a change elsewhere in the system. Note this is only sent if the recalculation results in a change in the total_cost field.
unavailability.createdSent when an unavailability is created.
qualification.createdSent when an qualification is created.
qualification.updatedSent when an qualification is changed.
qualification.destroyedSent when an qualification is deleted.
user.createdSent when a new user is created, either manually, by API, or by bulk import.
user.deactivatedSent when a new user is deactivated, either manually or via the API.
user.reactivatedSent when a new user is reactivated, either manually or via the API.
user.onboarding_completeSent when a user has complete their onboarding.
user.updatedSent when a user is changed.
leavebalance.createdSent when a leave balance is created.
leavebalance.updatedSent when a leave balance is updated.
platform_record.createdSent when a platform record is created.
platform_record.updatedSent when a platform record is updated.
platform_record.destroyedSent when a platform record is destroyed.

Want to see other topics added to this list? Let us know!

Creating Webhooks

To manage Webhooks you have two choices:

  • the API if this is part of a more complicated integration with Tanda.

  • the UI if the use case is simple enough.

Programmatically

Webhooks can be managed via API calls, please note you’ll need to be authenticated as an Admin user when making calls to the /api/v2/webhooks endpoints.

The available endpoints for working with subscriptions are documented below - you can also work with an individual subscription in various ways.

Through the UI

Tanda presents the Webhooks portal to manage existing and create new subscriptions through the UI.

Simply enter a URL, Security Token (covered in more detail here) and select the topics you wish to be notified about at the specified URL.

Testing your Webhooks

When working with webhooks you may find it useful to emit events to somewhere you can inspect them without having to setup a server, try and Google “testing Webhooks” or “tools for testing webhooks”.

Securing Webhooks

To validate that the webhook came from Tanda and not an unknown 3rd party, we attach a security token to each request in the X-Webhook-Signature header. The security token is constructed from a secret you provide when you first create the webhook subscription.

The token is computed using the HMAC SHA1 hashing algorithm. The secret you provide during subscription creation is used as the key and the request body (all of it) is the message passed to the hashing function.

X-Hook-Signature = HMACSHA1(Secret Token, Request Body)

By checking that the X-Webhook-Signature matches when you receive it you can be sure that the webhook came from Tanda & was not tampered with.

Some samples for validating the signature are below:

Warning: make sure you are checking the value sent in the X-Webhook-Signature header. Other headers may also be included (eg. X-Hook-Signature) but these are deprecated and should not be used.

Failures & Retries

When we send a notification, we expect to get back a 200 response code within 60 seconds. If we don’t get a 200 after 60 seconds, we’ll consider the webhook failed & begin retrying it. We process retries as described below:

  • Once every 5 minutes for the first hour

  • Once every hour for the next 12 hours

  • At this point if there has been no successful delivery, we give up

Best Practices

Before going live with your application, test that your integration is working properly.

If your webhook receiver performs complex computation or might be blocked by IO/network you may find it times out when trying to receive the webhook from Tanda. For this reason we recommend you acknowledge receipt of a webhook immediately by returning a 200.

Webhook endpoints might occasionally receive the same payload more than once. If your integrations logic is dependent upon exactly once delivery we advise you to safeguard against this by making your receiver idempotent, one way of doing this is by using the hook_key field and storing it temporarily, if you receive the same hook_key more than once you can discard it.

You should use security tokens, and verify them. See our instructions on Securing Webhooks.

Subscriptions List

Only admin users are able to access these endpoints. Webhook configuration is common across an organisation.

GET https://my.tanda.co/api/v2/webhooks
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 123456,
    "url": "https://requestb.in/TaNdA",
    "token": "IaMaSeCrEt",
    "topics": [
      "user.created",
      "clockin.updated"
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Subscriptions
GET/api/v2/webhooks


POST https://my.tanda.co/api/v2/webhooks
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "url": "https://requestb.in/TaNdA",
  "secret": "IaMaOptionalSeCrEt",
  "topics": [
    "user.created",
    "clockin.updated"
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "url": "https://requestb.in/TaNdA",
  "token": "IaMaSeCrEt",
  "topics": [
    "user.created",
    "clockin.updated"
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The Tanda defined ID for this subscription"
    },
    "url": {
      "type": "string",
      "description": "The URL to send notifications to"
    },
    "token": {
      "type": "string",
      "description": "A secret used to verify notification authenticity"
    },
    "topics": {
      "type": "array",
      "description": "A list of topics to get notifications for"
    }
  },
  "required": [
    "url",
    "topics"
  ]
}

Create Subscription
POST/api/v2/webhooks

We will send a notification with the topic created when a webhook is first created.


Subscription

GET https://my.tanda.co/api/v2/webhooks/123456
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123456,
  "url": "https://requestb.in/TaNdA",
  "token": "IaMaSeCrEt",
  "topics": [
    "user.created",
    "clockin.updated"
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The Tanda defined ID for this subscription"
    },
    "url": {
      "type": "string",
      "description": "The URL to send notifications to"
    },
    "token": {
      "type": "string",
      "description": "A secret used to verify notification authenticity"
    },
    "topics": {
      "type": "array",
      "description": "A list of topics to get notifications for"
    }
  },
  "required": [
    "url",
    "topics"
  ]
}

Get Subscription
GET/api/v2/webhooks/{id}

URI Parameters
HideShow
id
number (required) Example: 123456

The id of the subscription


DELETE https://my.tanda.co/api/v2/webhooks/123456
Responses200
Headers
Content-Type: application/json

Delete Subscription
DELETE/api/v2/webhooks/{id}

URI Parameters
HideShow
id
number (required) Example: 123456

The id of the subscription


Public Holidays

Public Holiday Regions

HideShow

Click "show" to see a list of Tanda supported public holiday regions.

Region CodeRegion Name
auAustralia (national holidays only)
au_actAustralian Capital Territory
au_nswNew South Wales
au_ntNorthern Territory
au_qldQueensland
au_saSouth Australia
au_tasTasmania
au_vicVictoria
au_waWestern Australia
cyCyprus (national holidays)
elGreece (national holidays)
fiFinland (Finnish) (national holidays)
gbUnited Kingdom (national holidays only)
gb_engEngland
gb_nirNorthern Island
gb_sctScotland
gb_wlsWales
jpJapan (national holidays)
lrLiberia (national holidays)
nzNew Zealand (national holidays)
mmMyanmar (national holidays)
mt_enMalta (English) (national holidays)
muMauritius (national holidays)
usUnited States of America (national holidays)
zaSouth Africa (national holidays)
phThe Philippines (national holidays)
viVietnam (national holidays)
caCanada (national holidays)
be_frBelgium (national holidays in French)
be_nlBelgium (national holidays in Dutch)
thThailand (national holidays only)

You can see holiday dates in your System Settings.

Public Holidays

GET https://my.tanda.co/api/v2/public_holidays?regions=au,au_qld&years=2018,2019
Responses201
Headers
Content-Type: application/json
Body
{
  "au": [
    {
      "date": "2018-01-01",
      "name": "New Year's Day"
    }
  ],
  "au_qld": [
    {
      "date": "2018-01-01",
      "name": "New Year's Day"
    }
  ]
}

Get Public Holidays
GET/api/v2/public_holidays{?regions,years}

Given a list of regions, and years, returns a list of public holidays in those regions in those years.

URI Parameters
HideShow
regions
string (required) Example: au,au_qld

one or more comma separated public holiday regions

years
string (required) Example: 2018,2019

one or more comma separated public holiday years


Temporary Files

Temporary Files

POST https://my.tanda.co/api/v2/temporary_files
Responses201
Headers
Content-Type: application/json
Body
{
  "file_id": "73fe3430-4f5d-3a0a-84a7-cffbeb5efeb2"
}

Create Temporary File
POST/api/v2/temporary_files

Use this endpoint to upload files that will then be called by other endpoints. This allows you to process files “in the background” while a user is doing other things in your app. For example, if you are building a form for a user to request time off, you might start uploading to the temporary files endpoint as soon as the user chooses a verification photo. That way, when they submit the form, you have already uploaded the file and they don’t need to wait for it to upload.

Files must not be larger than 5mb.

Unlike other endpoints, this endpoint does not accept JSON. Instead it expects binary file data.

  • If you’re writing JavaScript, use the FormData API.

  • If you’re using CURL, use the -F (--form) flag.

  • If you’re using Postman, use the Form-data option, with a param of type “File” and key file.

If you like, you can pass a comma separated list of content types to the content_types param. If provided, the API will validate these against the uploaded file, and you will get a 400 status back if the file is invalid.

If the upload is successful, you’ll get back a file_id. Use this ID with endpoints that support file attachments. There’s a few things you should know about file IDs:

  • A file ID can only be used once. It will be deleted once the uploaded file has successfully been linked via another endpoint.

  • If a file ID isn’t used for a week it will be deleted.

URI Parameters
HideShow
file
file data (required) 
content_types
string (optional) Example: image/gif,image/png

a comma separated list of content types to validate against


Shift Reminders

Shift Reminders are sent as push notifications to the Tanda App before a schedule is set to start. Use this endpoint to configure reminders.

The minutes_before_shift_start param, used to control when reminders send, must be a multiple of 5, and must be between 5 and 1435 (ie. it can’t be more than 1 day). You can set up as many reminders as you like. Reminders are tied to the current authenticated user, which means they work across all organisations the user works at.

Shift Reminder List

GET https://my.tanda.co/api/v2/shift_reminders
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 123706,
    "minutes_before_shift_start": 30
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Shift Reminders
GET/api/v2/shift_reminders

This method requires the me scope (see Scopes for more information).


POST https://my.tanda.co/api/v2/shift_reminders
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "minutes_before_shift_start": 120
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123706,
  "minutes_before_shift_start": "120"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The shift reminder ID"
    },
    "minutes_before_shift_start": {
      "type": "string",
      "description": "How long before a shift (in minutes) the reminder should send"
    }
  },
  "required": [
    "id",
    "minutes_before_shift_start"
  ]
}

Create Shift Reminder
POST/api/v2/shift_reminders

This method requires the me scope (see Scopes for more information).


Shift Reminder

GET https://my.tanda.co/api/v2/shift_reminders/123706
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123706,
  "minutes_before_shift_start": 30
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The shift reminder ID"
    },
    "minutes_before_shift_start": {
      "type": "number",
      "description": "How long before a shift (in minutes) the reminder should send"
    }
  },
  "required": [
    "id",
    "minutes_before_shift_start"
  ]
}

Get Shift Reminder
GET/api/v2/shift_reminders/{id}

This method requires the me scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123706

The ID of the shift reminder


PUT https://my.tanda.co/api/v2/shift_reminders/123706
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "minutes_before_shift_start": 45
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123706,
  "minutes_before_shift_start": "45"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The shift reminder ID"
    },
    "minutes_before_shift_start": {
      "type": "string",
      "description": "How long before a shift (in minutes) the reminder should send"
    }
  },
  "required": [
    "id",
    "minutes_before_shift_start"
  ]
}

Update Shift Reminder
PUT/api/v2/shift_reminders/{id}

This method requires the me scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123706

The ID of the shift reminder to edit


DELETE https://my.tanda.co/api/v2/shift_reminders/123706
Responses200
Headers
Content-Type: application/json

Delete Shift Reminder
DELETE/api/v2/shift_reminders/{id}

This method requires the me scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123706

The ID of the shift reminder


Custom Events

Custom Events List

GET https://my.tanda.co/api/v2/custom_events
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 123677,
    "organisation_id": 23100,
    "start": "2018-09-01",
    "finish": "2018-09-01",
    "name": "Tanda Panda Day",
    "discourage_time_off": true,
    "locations": [
      2002,
      2003,
      2004
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Custom Events List
GET/api/v2/custom_events

Get a full list of custom events in a single request.

This method requires the roster and department scopes (see Scopes for more information).

URI Parameters
HideShow
from
string (required) Example: 2018-09-01

From date to lookup custom events

to
string (required) Example: 2018-09-01

To date to lookup custom events


POST https://my.tanda.co/api/v2/custom_events
RequestsCreate Custom Event
Headers
Content-Type: application/json
Body
{
  "name": "Tanda Panda Day",
  "start": "2018-09-01",
  "finish": "2018-09-01",
  "discourage_time_off": true,
  "custom_event_joins_attributes": [
    {
      "location_id": 2002
    },
    {
      "location_id": 2003
    },
    {
      "location_id": 2004
    }
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123677,
  "organisation_id": 23100,
  "start": "2018-09-01",
  "finish": "2018-09-01",
  "name": "Tanda Panda Day",
  "discourage_time_off": true,
  "locations": [
    2002,
    2003,
    2004
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The custom event ID"
    },
    "organisation_id": {
      "type": "number",
      "description": "The organisation id where this custom event belongs to"
    },
    "start": {
      "type": "string",
      "description": "The date of the first day of the custom event"
    },
    "finish": {
      "type": "string",
      "description": "The last date of the custom event"
    },
    "name": {
      "type": "string",
      "description": "The name of the custom event"
    },
    "discourage_time_off": {
      "type": "boolean",
      "description": "This states whether a custom events blocks time off or not"
    },
    "locations": {
      "type": "array",
      "description": "The location ids to where the custom event applies"
    }
  },
  "required": [
    "id",
    "organisation_id",
    "start",
    "finish",
    "name",
    "discourage_time_off",
    "locations"
  ]
}

Create Custom Events List
POST/api/v2/custom_events

Creates a custom event under the current organisation and placed under the specified location

This method requires the roster and department scopes (see Scopes for more information).


PUT https://my.tanda.co/api/v2/custom_events
RequestsUpdate Custom Event
Headers
Content-Type: application/json
Body
{
  "name": "Tanda Panda Month",
  "start": "2018-09-01",
  "finish": "2018-09-30",
  "discourage_time_off":true,
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123677,
  "organisation_id": 23100,
  "start": "2018-09-01",
  "finish": "2018-09-30",
  "name": "Tanda Panda Month",
  "discourage_time_off": "true",
  "locations": [
    2002,
    2003,
    2004
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The custom event ID"
    },
    "organisation_id": {
      "type": "number",
      "description": "The organisation id where this custom event belongs to"
    },
    "start": {
      "type": "string",
      "description": "The date of the first day of the custom event"
    },
    "finish": {
      "type": "string",
      "description": "The last date of the custom event"
    },
    "name": {
      "type": "string",
      "description": "The name of the custom event"
    },
    "discourage_time_off": {
      "type": "string",
      "description": "This states whether a custom events blocks time off or not"
    },
    "locations": {
      "type": "array",
      "description": "The location ids to where the custom event applies"
    }
  },
  "required": [
    "id",
    "organisation_id",
    "start",
    "finish",
    "name",
    "discourage_time_off",
    "locations"
  ]
}

Update Custom Event Request
PUT/api/v2/custom_events

This method requires the roster and department scopes (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123677

The id of the custom event to update


DELETE https://my.tanda.co/api/v2/custom_events
Responses200
Headers
Content-Type: application/json

Delete Custom Event
DELETE/api/v2/custom_events

This method requires the roster and department scopes (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123677

The id of the custom event to delete


Custom Event Locations

PUT https://my.tanda.co/api/v2/custom_events/123677/locations
RequestsUpdate Custom Event locations
Headers
Content-Type: application/json
Body
{
  "location_ids": [
    2007
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123677,
  "organisation_id": 23100,
  "start": "2018-09-01",
  "finish": "2018-09-30",
  "name": "Tanda Panda Month",
  "discourage_time_off": "true",
  "locations": [
    "2002",
    "2003",
    "2004",
    "2005",
    "2007"
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The custom event ID"
    },
    "organisation_id": {
      "type": "number",
      "description": "The organisation id where this custom event belongs to"
    },
    "start": {
      "type": "string",
      "description": "The date of the first day of the custom event"
    },
    "finish": {
      "type": "string",
      "description": "The last date of the custom event"
    },
    "name": {
      "type": "string",
      "description": "The name of the custom event"
    },
    "discourage_time_off": {
      "type": "string",
      "description": "This states whether a custom events blocks time off or not"
    },
    "locations": {
      "type": "array",
      "description": "The location ids to where the custom event applies"
    }
  },
  "required": [
    "id",
    "organisation_id",
    "start",
    "finish",
    "name",
    "discourage_time_off",
    "locations"
  ]
}

Update Custom Event Locations
PUT/api/v2/custom_events/{id}/locations

This method requires the roster and department scopes (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123677

The id of the custom event to update

location_ids
array[number] (required) Example: 2007

DELETE https://my.tanda.co/api/v2/custom_events/123677/locations
RequestsUpdate Custom Event locations
Headers
Content-Type: application/json
Body
{
  "location_ids": [
    2005,
    2007
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 123677,
  "organisation_id": 23100,
  "start": "2018-09-01",
  "finish": "2018-09-30",
  "name": "Tanda Panda Month",
  "discourage_time_off": "true",
  "locations": [
    "2002",
    "2003",
    "2004"
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The custom event ID"
    },
    "organisation_id": {
      "type": "number",
      "description": "The organisation id where this custom event belongs to"
    },
    "start": {
      "type": "string",
      "description": "The date of the first day of the custom event"
    },
    "finish": {
      "type": "string",
      "description": "The last date of the custom event"
    },
    "name": {
      "type": "string",
      "description": "The name of the custom event"
    },
    "discourage_time_off": {
      "type": "string",
      "description": "This states whether a custom events blocks time off or not"
    },
    "locations": {
      "type": "array",
      "description": "The location ids to where the custom event applies"
    }
  },
  "required": [
    "id",
    "organisation_id",
    "start",
    "finish",
    "name",
    "discourage_time_off",
    "locations"
  ]
}

Delete Custom Event Location
DELETE/api/v2/custom_events/{id}/locations

This method requires the roster and department scopes (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 123677

The id of the custom event to update

location_ids
array[number] (required) Example: 2007

Schedule Swap Plans

About

Models the life cycle of swapping a shift between two people. The two people involved in a swap are referred to as the sender (the original staff member) and the recipient (the new staff member).

Strategies

Schedule swap plans can be handled with different strategies. The strategy states include undecided, broadcasted and curated. Schedule swap plans in an undecided state, represent a plan that is new and has not had a strategy selected.

When a schedule swap plan is using the broadcasted strategy, managers will need to approve a person offering to cover the schedule.

When a schedule swap plan is using the curated strategy, the swap will be assigned to the first person accepting to cover the schedule.

Schedule swap plans created less than 3 days in advance of a schedule’s start are automatically broadcated.

States

A schedule swap plan can be in 3 states. The states are pending, approved and rejected.

Schedule Swap Plan List

GET https://my.tanda.co/api/v2/schedule_swap_plans
Requestsexample 1
Headers
Content-Type: appplication/json
Body
{
  "statuses": "pending,approved,rejected"
}
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 1231342,
    "recipient_id": 3249234,
    "sender_id": 4593929,
    "schedule_id": 2340280,
    "status": "approved",
    "strategy": "broadcasted",
    "reason": "cannot work this shift"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Schedule Swap Plan
GET/api/v2/schedule_swap_plans

Returns a list of schedule swap plans. Gets all plans by default, but you may specify which plans you would like to return using the statuses parameter. Schedule Swap Plans that are visible include:

  • Schedule swap plans where you are the sender

  • Schedule swap plans where you are a manager of the sender

This method requires the roster scope. (see Scopes for more information)


POST https://my.tanda.co/api/v2/schedule_swap_plans
Requestsexample 1
Headers
Content-Type: application/json
Body
{
    "schedule_id": 10203834,
    // "prepare_auto_broadcast": true
  }
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1231342,
  "recipient_id": 3249234,
  "sender_id": 4593929,
  "schedule_id": 2340280,
  "status": "approved",
  "strategy": "broadcasted",
  "reason": "cannot work this shift"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The schedule swap plan ID"
    },
    "recipient_id": {
      "type": "number",
      "description": "The person who received the schedule"
    },
    "sender_id": {
      "type": "number",
      "description": "The person who offered to swap the schedule"
    },
    "schedule_id": {
      "type": "number",
      "description": "The schedule being swapped"
    },
    "status": {
      "type": "string",
      "description": "The status of the swap. Will be one of 'pending', 'approved' or 'rejected'"
    },
    "strategy": {
      "type": "string",
      "description": "the method of swapping the schedule. Will be one of 'undecided', 'broadcasted' or 'curated'"
    },
    "reason": {
      "type": "string",
      "description": "the reason the sender cannot work the schedule"
    }
  },
  "required": [
    "id",
    "sender_id",
    "strategy"
  ]
}

Schedule Swap Plan
POST/api/v2/schedule_swap_plans

Creates a new schedule swap plan. If the schedule’s start is more than 3 days away, the schedule swap plan will have a strategy of undecided, else it will automatically be broadcasted - unless the request is sent with the prepare_auto_broadcast: false parameter.

This method requires the roster scope. (see Scopes for more information)

Schedule swap plans can only be created for yourself or someone you manage

Schedule swap plans can only be created for schedules that meet the following criteria:

  • Is in the future

  • Has a start

  • Has a team


Broadcast

Transistions a swap from undecided to broadcasted making all concealed schedule swap proposals transition to pending. A schedule swap proposal will still require to be approved for this schedule swap plan to transition to approved

PUT https://my.tanda.co/api/v2/schedule_swap_plans/26/broadcast
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1231342,
  "recipient_id": 3249234,
  "sender_id": 4593929,
  "schedule_id": 2340280,
  "status": "approved",
  "strategy": "broadcasted",
  "reason": "cannot work this shift"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The schedule swap plan ID"
    },
    "recipient_id": {
      "type": "number",
      "description": "The person who received the schedule"
    },
    "sender_id": {
      "type": "number",
      "description": "The person who offered to swap the schedule"
    },
    "schedule_id": {
      "type": "number",
      "description": "The schedule being swapped"
    },
    "status": {
      "type": "string",
      "description": "The status of the swap. Will be one of 'pending', 'approved' or 'rejected'"
    },
    "strategy": {
      "type": "string",
      "description": "the method of swapping the schedule. Will be one of 'undecided', 'broadcasted' or 'curated'"
    },
    "reason": {
      "type": "string",
      "description": "the reason the sender cannot work the schedule"
    }
  },
  "required": [
    "id",
    "sender_id",
    "strategy"
  ]
}

Broadcast A Swap
PUT/api/v2/schedule_swap_plans/{id}/broadcast

This method requires the roster scope. (see Scopes for more information)

URI Parameters
HideShow
id
number (required) Example: 26

The schedule swap plan ID


Curate

Transistions a schedule swap plan from undecided to curated making all specified concealed schedule swap proposals transition to pending. This schedule swap plan will transition directly to approved when a user accepts to cover the schedule

PUT https://my.tanda.co/api/v2/schedule_swap_plans/26/curate
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "proposal_ids": [
    12312983,
    12890371
  ]
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1231342,
  "recipient_id": 3249234,
  "sender_id": 4593929,
  "schedule_id": 2340280,
  "status": "approved",
  "strategy": "broadcasted",
  "reason": "cannot work this shift"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The schedule swap plan ID"
    },
    "recipient_id": {
      "type": "number",
      "description": "The person who received the schedule"
    },
    "sender_id": {
      "type": "number",
      "description": "The person who offered to swap the schedule"
    },
    "schedule_id": {
      "type": "number",
      "description": "The schedule being swapped"
    },
    "status": {
      "type": "string",
      "description": "The status of the swap. Will be one of 'pending', 'approved' or 'rejected'"
    },
    "strategy": {
      "type": "string",
      "description": "the method of swapping the schedule. Will be one of 'undecided', 'broadcasted' or 'curated'"
    },
    "reason": {
      "type": "string",
      "description": "the reason the sender cannot work the schedule"
    }
  },
  "required": [
    "id",
    "sender_id",
    "strategy"
  ]
}

Curate A Swap
PUT/api/v2/schedule_swap_plans/{id}/curate

This method requires the roster scope. (see Scopes for more information)

URI Parameters
HideShow
id
number (required) Example: 26

The schedule swap plan ID


Reject

PUT https://my.tanda.co/api/v2/schedule_swap_plans/26/reject
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1231342,
  "recipient_id": 3249234,
  "sender_id": 4593929,
  "schedule_id": 2340280,
  "status": "approved",
  "strategy": "broadcasted",
  "reason": "cannot work this shift"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The schedule swap plan ID"
    },
    "recipient_id": {
      "type": "number",
      "description": "The person who received the schedule"
    },
    "sender_id": {
      "type": "number",
      "description": "The person who offered to swap the schedule"
    },
    "schedule_id": {
      "type": "number",
      "description": "The schedule being swapped"
    },
    "status": {
      "type": "string",
      "description": "The status of the swap. Will be one of 'pending', 'approved' or 'rejected'"
    },
    "strategy": {
      "type": "string",
      "description": "the method of swapping the schedule. Will be one of 'undecided', 'broadcasted' or 'curated'"
    },
    "reason": {
      "type": "string",
      "description": "the reason the sender cannot work the schedule"
    }
  },
  "required": [
    "id",
    "sender_id",
    "strategy"
  ]
}

Reject A Swap
PUT/api/v2/schedule_swap_plans/{id}/reject

Transitions a schedule swap plan to rejected making all its schedule swap proposals also transition to rejected

This method requires the roster scope. (see Scopes for more information)

Schedule swap plans can only be rejected yourself or for someone you manage

URI Parameters
HideShow
id
number (required) Example: 26

The schedule swap plan ID


Notify

PUT https://my.tanda.co/api/v2/schedule_swap_plans/26/notify
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1231342,
  "recipient_id": 3249234,
  "sender_id": 4593929,
  "schedule_id": 2340280,
  "status": "approved",
  "strategy": "broadcasted",
  "reason": "cannot work this shift"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The schedule swap plan ID"
    },
    "recipient_id": {
      "type": "number",
      "description": "The person who received the schedule"
    },
    "sender_id": {
      "type": "number",
      "description": "The person who offered to swap the schedule"
    },
    "schedule_id": {
      "type": "number",
      "description": "The schedule being swapped"
    },
    "status": {
      "type": "string",
      "description": "The status of the swap. Will be one of 'pending', 'approved' or 'rejected'"
    },
    "strategy": {
      "type": "string",
      "description": "the method of swapping the schedule. Will be one of 'undecided', 'broadcasted' or 'curated'"
    },
    "reason": {
      "type": "string",
      "description": "the reason the sender cannot work the schedule"
    }
  },
  "required": [
    "id",
    "sender_id",
    "strategy"
  ]
}

Notify Everyone Who Can Cover
PUT/api/v2/schedule_swap_plans/{id}/notify

Will send a notification to all users available to cover this shift through the Tanda App

Notifications will only be sent to users who have a schedule swap proposals in a pending or seen state.

This method requires the roster scope. (see Scopes for more information)

Only a manager of a swap can notify the users available

URI Parameters
HideShow
id
number (required) Example: 26

The schedule swap plan ID


Schedule Swap Proposals

About

Models the life cycle of vetting one potential recipient for a schedule swap plan.

States

Used to specify where a proposal is in its life cycle:

  • Schedule swap proposals which are concealed are only visible to managers. and are visible to enable a manager to curate a schedule swap plan.

  • Schedule swap proposals which are pending are new and have not been actioned by a user.

  • Schedule swap proposals which are seen have been marked as viewed by the users (e.g. a swap can be marked as seen through the API, or by the Tanda App)

  • Schedule swap proposals which are accepted have had a user offer to cover the shift but are awaiting approval by a manager.

  • Schedule swap proposals which are approved have been accepted, and the user of this proposal is now scheduled to work the shift.

  • Schedule swap proposals which are rejected have been declined by either the user or a manager of the user

Schedule Swap Proposal List

GET https://my.tanda.co/api/v2/schedule_swap_proposals
Requestsexample 1
Headers
Content-Type: appplication/json
Body
{
  "statuses": "concealed,seen,pending,approved,rejected,accepted"
}
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 23409,
    "schedule_swap_plan_id": 23,
    "user_id": 1263,
    "status": "pending",
    "strategy": "curated",
    "response": "Thankyou for covering this shift 🙏",
    "complete": true,
    "created_at": 1643637600,
    "updated_at": 1646056800,
    "schedule_details": {
      "automatic_break_length": 30,
      "cost": 196.48,
      "department_id": 23423,
      "finish": 230948239048,
      "start": 1239182309902,
      "shift_detail_id": 9210,
      "breaks": [
        {
          "start": 1456909200,
          "finish": 1456911000
        }
      ]
    },
    "roster_details": {
      "hours_in_week": 32,
      "errors": [
        {
          "message": "shift starts to early",
          "rule": 180,
          "type": "EARLIEST_START"
        }
      ]
    }
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Schedule Swap Proposals
GET/api/v2/schedule_swap_proposals

Returns a list of schedule swap proposals. Gets all proposals by default, but you may specify which proposals to return using the statuses parameter. Schedule swap proposals that are visible include:

  • schedule swap proposals of users you manage

  • schedule swap proposals for yourself (that are not concealed)

If a user has another commitment at the same time as the proposed schedule. There will be no proposal for this user

This method requires the roster scope. (see Scopes for more information)


Schedule Swap Proposal

PUT https://my.tanda.co/api/v2/schedule_swap_proposals/23409/status
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 23409,
  "schedule_swap_plan_id": 23,
  "user_id": 1263,
  "status": "pending",
  "strategy": "curated",
  "response": "Thankyou for covering this shift 🙏",
  "complete": true,
  "created_at": 1643637600,
  "updated_at": 1646056800,
  "schedule_details": {
    "automatic_break_length": 30,
    "cost": 196.48,
    "department_id": 23423,
    "finish": 230948239048,
    "start": 1239182309902,
    "shift_detail_id": 9210,
    "breaks": [
      {
        "start": 1456909200,
        "finish": 1456911000
      }
    ]
  },
  "roster_details": {
    "hours_in_week": 32,
    "errors": [
      {
        "message": "shift starts to early",
        "rule": 180,
        "type": "EARLIEST_START"
      }
    ]
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The schedule swap proposal ID"
    },
    "schedule_swap_plan_id": {
      "type": "number",
      "description": "The schedule swap plan ID that this proposal belongs to."
    },
    "user_id": {
      "type": "number",
      "description": "The user ID that this proposal is for"
    },
    "status": {
      "type": "string",
      "description": "The state of the proposal. Will be one of 'concealed', 'pending', 'seen', 'accepted', 'approved', 'rejected'"
    },
    "strategy": {
      "type": "string",
      "description": "The strategy of the schedule swap plan this proposal belongs to. Will be one of 'undecided', 'broadcasted', 'curated'"
    },
    "response": {
      "type": "string",
      "description": "A response for the user of the proposal from a manager"
    },
    "complete": {
      "type": "boolean",
      "description": "Whether the schedule swap proposal has been processed yet - most data will be empty until this is true"
    },
    "created_at": {
      "type": "number",
      "description": "The date the schedule swap proposal was created, in unix time"
    },
    "updated_at": {
      "type": "number",
      "description": "The date the schedule swap proposal was last updated, in unix time"
    },
    "schedule_details": {
      "type": "object",
      "properties": {
        "automatic_break_length": {
          "type": "number",
          "description": "the length of automatic breaks in minutes"
        },
        "cost": {
          "type": "number",
          "description": "the cost the shift would have"
        },
        "department_id": {
          "type": "number",
          "description": "the team ID the schedule will be in"
        },
        "finish": {
          "type": "number",
          "description": "the time the schedule would finish at"
        },
        "start": {
          "type": "number",
          "description": "the time the schedule would start at"
        },
        "shift_detail_id": {
          "type": "number",
          "description": "the shift detail ID for the detail the shift would have"
        },
        "breaks": {
          "type": "array",
          "description": "the breaks the schedule would have"
        }
      },
      "required": [
        "automatic_break_length",
        "cost",
        "department_id",
        "start"
      ],
      "description": "the details of the proposed schedule"
    },
    "roster_details": {
      "type": "object",
      "properties": {
        "hours_in_week": {
          "type": "number",
          "description": "number of hours the employee will work"
        },
        "errors": {
          "type": "array"
        }
      },
      "description": "the details of the proposed roster"
    }
  },
  "required": [
    "id",
    "schedule_swap_plan_id",
    "user_id",
    "status",
    "strategy",
    "complete",
    "created_at",
    "updated_at"
  ]
}

Schedule Swap Proposal
PUT/api/v2/schedule_swap_proposals/{id}/status

Useful to transition a proposal between states.

Proposals are only eligible for transitions under specific circumstances. The conditions are:

  • Transition to seen

    • proposal must currently be pending or accepted
    • proposal must be your own
  • Transition to acccepted

    • proposal must currently be pending or seen
    • proposal must be your own
  • Transition to approved

    • proposal must be accepted
    • plan must be pending
  • Transition to rejected

    • proposal must be pending, seen or accepted
    • proposal must be your own, or someones who you manage
URI Parameters
HideShow
id
number (required) Example: 23409

The ID of the schedule swap proposal to update

status
string (required) Example: 'seen'

Must be one of ‘seen’, ‘accepted’, ‘approved’, ‘rejected’


Timeclock Questions

Use Timeclock Questions to create workflows around clocking in. There are currently three types of questions. The types are allowance, shift_tag and shift_note. Answering the questions will perform the following:

  • An allowance question will apply an allowance to the shift

  • A shift_tag question will set the tag on the shift

  • A shift_note question will add a note to the shift

These triggers are available:

  • start – question is asked when a staff member enters a clockin.

  • finish – question is asked when a staff member enters a clockout.

These conditions are available:

  • early – question is only asked when a trigger is early for its corresponding schedule.

  • late – question is only asked when a trigger is late for its corresponding schedule.

  • unscheduled – question is only asked when a trigger has no corresponding schedule.

  • schedule_needs_acceptance - question is asked if the schedule still needs acceptance or if the schedule is accepted, but the clock in is early or late.

  • shift_length_over - question is only asked if the shift length exceeds the condition threshold in hours

All methods require the device scope (see Scopes for more information).

Timeclock Questions List

GET https://my.tanda.co/api/v2/timeclock_questions?ask_on_devices=timeclock,app
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 42,
    "question": "What was your cash tips balance?",
    "required": false,
    "trigger_on": "finish",
    "ask_on_devices": [
      "timeclock"
    ],
    "condition": "early",
    "type": "allowance",
    "lenience": 15,
    "process": "ask_question"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Timeclock Questions
GET/api/v2/timeclock_questions{?ask_on_devices}

URI Parameters
HideShow
ask_on_devices
string (optional) Example: timeclock,app

Filter to a particular type of question. Comma separated list of devices.


POST https://my.tanda.co/api/v2/timeclock_questions
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "condition": "late" // (optional),
  "name": "What is the meaning of life?",
  "trigger_on": "finish",
  "type": "shift_note",
  "required": true,
  "answer_options_attributes": [ // (optional)
    { answer: "42" },
  ]
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 42,
  "question": "What was your cash tips balance?",
  "required": false,
  "trigger_on": "finish",
  "ask_on_devices": [
    "timeclock"
  ],
  "condition": "early",
  "type": "allowance",
  "lenience": 15,
  "process": "ask_question"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "the question ID"
    },
    "question": {
      "type": "string",
      "description": "The question to ask"
    },
    "required": {
      "type": "boolean",
      "description": "Should the shift data be considered incomplete if the question is not answered? (displays warning message to ensure employee is aware the question is required)"
    },
    "trigger_on": {
      "type": "string",
      "description": "when should the question be asked?"
    },
    "ask_on_devices": {
      "type": "array",
      "description": "what devices should this question show on?"
    },
    "condition": {
      "type": "string",
      "description": "conditions under which this question should show"
    },
    "type": {
      "type": "string",
      "description": "type of answer expected"
    },
    "lenience": {
      "type": "number",
      "description": "for conditional question, how much lenience when asked"
    },
    "process": {
      "type": "string",
      "description": "what action should take place if the given criteria is met. ask_question | block_clockin"
    }
  },
  "required": [
    "id",
    "question",
    "trigger_on",
    "type",
    "lenience",
    "process"
  ]
}

Create Timeclock Questions
POST/api/v2/timeclock_questions

When creating a timeclock questions you can also create answer options. This will allow tanda to suggest options when asking the question.


Timeclock Question

DELETE https://my.tanda.co/api/v2/timeclock_questions/42
Responses200
Headers
Content-Type: application/json

Delete Timeclock Question
DELETE/api/v2/timeclock_questions/{id}

Deleting a timeclock question will not delete the corresponding allowance.

URI Parameters
HideShow
id
number (required) Example: 42

The id of the question


Answer Questions

POST https://my.tanda.co/api/v2/timeclock_questions/42/answer
RequestsSubmit a cash tips balance
Headers
Content-Type: application/json
Body
{
  "user_id": 234,
  "shift_id": 23432,
  "answer": 63.4
}
Responses200
Headers
Content-Type: application/json

Answer Questions
POST/api/v2/timeclock_questions/{id}/answer

This answer submits an answer to a timeclock question. The answer will be stored based on how the question is configured. For example it might be set as an allowance value, or a tag on a shift.

You can post answers through this endpoint, or as part of a clock in. If you use this endpoint, the answer will be validated, and you’ll get an error if it’s the wrong format. If you use the clock ins endpoint, no validation is performed.

The answers type depends on the question type. Expected types for answers are:

  • shift_note question expects string

  • allowance question expects number

URI Parameters
HideShow
id
number (required) Example: 42

The ID of the question

user_id
number (required) Example: 234

the ID of the user answering

shift_id
number (required) Example: 23432

the ID of the shift this question relates to

answer
string | number (required) Example: 63.4

the actual answer to the question. the value type depends on the question.


Platform

All methods require the platform scope (see Scopes for more information).

Object List

GET https://my.tanda.co/api/v2/platform/objects
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 8,
    "name": "Employee",
    "api_name": "users",
    "friendly_name": "Employee",
    "fields": [
      {
        "id": 99,
        "model_id": 8,
        "name": "Nickname",
        "type": "text",
        "key": "nickname",
        "visible_to": [
          "admin",
          "manager"
        ],
        "editable_by": [
          "admin",
          "manager"
        ]
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Objects
GET/api/v2/platform/objects

Gets all of your current platform objects


POST https://my.tanda.co/api/v2/platform/objects
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "name": "Invoice",
  "api_name": "invoices",
  "fields": [
    {
      "name": "Description",
      "key": "description",
      "type": "text"
    },
    {
      "name": "Amount",
      "key": "amount",
      "type": "float"
    }
  ],
  "owned_associations": [
    {
      "name": "Client",
      "key": "client_id",
      "subject_id": 1234,
      "type": "has_one"
    },
    {
      "name": "Sales Rep",
      "key": "sales_rep_id",
      "subject_id": 3245,
      "type": "has_many"
    }
  ]
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 8,
  "name": "Employee",
  "api_name": "users",
  "friendly_name": "Employee",
  "fields": [
    {
      "id": 99,
      "model_id": 8,
      "name": "Nickname",
      "type": "text",
      "key": "nickname",
      "visible_to": [
        "admin",
        "manager"
      ],
      "editable_by": [
        "admin",
        "manager"
      ]
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number"
    },
    "name": {
      "type": "string"
    },
    "api_name": {
      "type": "string"
    },
    "friendly_name": {
      "type": "string",
      "description": "Deprecated. This field will be removed in V3."
    },
    "fields": {
      "type": "array"
    }
  },
  "required": [
    "id",
    "name",
    "friendly_name"
  ]
}

Post Object
POST/api/v2/platform/objects

Creates a new platform object


Object

GET https://my.tanda.co/api/v2/platform/objects/42
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 8,
  "name": "Employee",
  "api_name": "users",
  "friendly_name": "Employee",
  "fields": [
    {
      "id": 99,
      "model_id": 8,
      "name": "Nickname",
      "type": "text",
      "key": "nickname",
      "visible_to": [
        "admin",
        "manager"
      ],
      "editable_by": [
        "admin",
        "manager"
      ]
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number"
    },
    "name": {
      "type": "string"
    },
    "api_name": {
      "type": "string"
    },
    "friendly_name": {
      "type": "string",
      "description": "Deprecated. This field will be removed in V3."
    },
    "fields": {
      "type": "array"
    }
  },
  "required": [
    "id",
    "name",
    "friendly_name"
  ]
}

Get Object
GET/api/v2/platform/objects/{id}

Gets a specific platform object by id

URI Parameters
HideShow
id
number (required) Example: 42

The id of the object


PUT https://my.tanda.co/api/v2/platform/objects/42
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "fields": [
    {
      "name": "Description",
      "key": "description",
      "type": "text"
    },
    {
      "name": "Amount",
      "key": "amount",
      "type": "float"
    }
  ],
  "owned_associations": [
    {
      "name": "Client",
      "key": "client_id",
      "type": "has_one"
    },
    {
      "name": "Sales Rep",
      "key": "employee_id",
      "type": "has_many"
    }
  ]
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 8,
  "name": "Employee",
  "api_name": "users",
  "friendly_name": "Employee",
  "fields": [
    {
      "id": 99,
      "model_id": 8,
      "name": "Nickname",
      "type": "text",
      "key": "nickname",
      "visible_to": [
        "admin",
        "manager"
      ],
      "editable_by": [
        "admin",
        "manager"
      ]
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number"
    },
    "name": {
      "type": "string"
    },
    "api_name": {
      "type": "string"
    },
    "friendly_name": {
      "type": "string",
      "description": "Deprecated. This field will be removed in V3."
    },
    "fields": {
      "type": "array"
    }
  },
  "required": [
    "id",
    "name",
    "friendly_name"
  ]
}

Put Object
PUT/api/v2/platform/objects/{id}

Updates a specific platform object

URI Parameters
HideShow
id
number (required) Example: 42

The id of the object


DELETE https://my.tanda.co/api/v2/platform/objects/42
Responses204
Headers
Content-Type: application/json

Delete Object
DELETE/api/v2/platform/objects/{id}

Deletes a specific platform object

URI Parameters
HideShow
id
number (required) Example: 42

The id of the object


Record List

GET https://my.tanda.co/api/v2/platform/invoices
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 19283,
  "description": 'an invoice',
  "amount": 99.99
}

Get Records
GET/api/v2/platform/{api_name}

Gets all platform records for a specific platform object

You cannot use this endpoint for native objects (shift, user, etc), only for custom ones.

URI Parameters
HideShow
api_name
string (required) Example: invoices

The api name of the object


POST https://my.tanda.co/api/v2/platform/invoices
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "description": 'an invoice',
  "amount": 99.99
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 19283,
  "description": 'an invoice',
  "amount": 99.99
}

Post Record
POST/api/v2/platform/{api_name}

Creates a platform record for a specific platform object

URI Parameters
HideShow
api_name
string (required) Example: invoices

The api name of the object


Record

GET https://my.tanda.co/api/v2/platform/invoices/42
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 19283,
  "description": 'an invoice',
  "amount": 99.99
}

Get Record
GET/api/v2/platform/{api_name}/{id}

Gets a specific platform record for a specific platform object

URI Parameters
HideShow
api_name
string (required) Example: invoices

The api name of the object

id
number (required) Example: 42

The id of the object


PUT https://my.tanda.co/api/v2/platform/invoices/42
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "description": 'another invoice'
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 19283,
  "description": 'an invoice',
  "amount": 99.99
}

Put Record
PUT/api/v2/platform/{api_name}/{id}

Updates a specific platform record for a specific platform object

URI Parameters
HideShow
api_name
string (required) Example: invoices

The api name of the object

id
number (required) Example: 42

The id of the object


DELETE https://my.tanda.co/api/v2/platform/invoices/42
Responses204
Headers
Content-Type: application/json

Delete Record
DELETE/api/v2/platform/{api_name}/{id}

Deletes a specific platform record for a specific platform object

URI Parameters
HideShow
api_name
string (required) Example: invoices

The api name of the object

id
number (required) Example: 42

The id of the object


Reports

The reports endpoint contains read-only endpoints to answer questions that get asked a lot where the answer is better off automated.

All reports require the cost scope (see Scopes for more information).

Adoption Metrics

GET https://my.tanda.co/api/v2/reports/adoption_metrics?weeks=1&include_user_ids=false
Responses200
Headers
Content-Type: application/json
Body
{
  "last_sign_in": 1586962894,
  "active_employees": 1797,
  "app": {
    "average": 655,
    "delta": 0
  },
  "timesheets": {
    "average": 0,
    "delta": 0
  },
  "approved_timesheets": {
    "average": 67,
    "delta": 3.728436282693378
  },
  "clockins": {
    "average": 307,
    "delta": 17.028380634390654
  },
  "rostering": {
    "average": 224,
    "delta": 10.127991096271565
  },
  "onboarding": {
    "completed": 0,
    "added_manually": 1792,
    "new": 1797
  }
}

Get Adoption Metrics
GET/api/v2/reports/adoption_metrics{?weeks,include_user_ids}

Provides a summary of adoption of key product features across the organisation.

URI Parameters
HideShow
weeks
number (required) Example: 1

1 | 2 | 4 - number of weeks to aggregate data for

include_user_ids
boolean (optional) Example: false

if true, include user IDs for every property. Defaults to false.


Shift Ratings

Either the user_id or employee_number fields are required to submit a shift rating. The user_id is the systems unique id (id field from /users) and the employee_number is the employee payroll_number (employee_number from /users).

Posting another shift rating for a user for that day will override the current shift rating.

Shift Rating requires the timesheet scope (see Scopes for more information).

Shift Ratings

POST https://my.tanda.co/api/v2/shift_ratings
RequestsSubmit Shift Rating with `user_id`Submit Shift Rating with `employee_number`
Headers
Content-Type: application/json
Body
{
  "user_id": 12345,
  "date": "2020-07-22",
  "rating": 5
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 9665,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-12",
  "start": 1457741040,
  "break_start": null,
  "break_finish": null,
  "break_length": null,
  "finish": 1457762640,
  "status": "PENDING",
  "allowances": [],
  "tag": null,
  "tag_id": null,
  "department_id": 808,
  "department_export_name": "abc123",
  "metadata": "My special metadata",
  "leave_request_id": null,
  "rating": 5,
  "last_rated_by": 123345
}
Headers
Content-Type: application/json
Body
{
  "employee_number": "abc123",
  "date": "2020-07-22",
  "rating": 5
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 9665,
  "timesheet_id": 7007,
  "user_id": 123456,
  "date": "2016-03-12",
  "start": 1457741040,
  "break_start": null,
  "break_finish": null,
  "break_length": null,
  "finish": 1457762640,
  "status": "PENDING",
  "allowances": [],
  "tag": null,
  "tag_id": null,
  "department_id": 808,
  "department_export_name": "abc123",
  "metadata": "My special metadata",
  "leave_request_id": null,
  "rating": 5,
  "last_rated_by": 123345
}

Post Shift Ratings
POST/api/v2/shift_ratings

Allows for a shift rating from 1 to 5 to be added to a users shift in Tanda if they worked on that day.


Cognitive Creator Configuration

Either the department_id or cognitive_creator_configuration_id fields are required to for creating or updating a cognitive creator configuration.

Cognitive creator configuration requires the department scope (see Scopes for more information).

Cognitive Creator Configuration list

GET https://my.tanda.co/api/v2/cognitive_creator_configuration?updated_after=1451570400
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 12,
    "minimum_staff": 1,
    "maximum_staff": 3,
    "max_concurrent_start": 2,
    "min_length": 3.5,
    "max_length": 8,
    "time_to_open": 0.5,
    "time_to_close": 0.5,
    "undercoverage_penalty_ratio": 1.3,
    "round_down_head_count": false,
    "consolidate_shift_count": true
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Cognitive Creator Configuration
GET/api/v2/cognitive_creator_configuration{?updated_after}

Gets all your Cognitive Creator Configurations.

URI Parameters
HideShow
updated_after
number (optional) Example: 1451570400

Time filter to find recently created or modified users


Cognitive Creator Configuration

GET https://my.tanda.co/api/v2/cognitive_creator_configuration
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 12,
  "minimum_staff": 1,
  "maximum_staff": 3,
  "max_concurrent_start": 2,
  "min_length": 3.5,
  "max_length": 8,
  "time_to_open": 0.5,
  "time_to_close": 0.5,
  "undercoverage_penalty_ratio": 1.3,
  "round_down_head_count": false,
  "consolidate_shift_count": true
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The cognitive creator configuration ID"
    },
    "minimum_staff": {
      "type": "number",
      "description": "The minimum amount of staff required for a shift in the department"
    },
    "maximum_staff": {
      "type": "number",
      "description": "The maximum amount of staff required for a shift in the department"
    },
    "max_concurrent_start": {
      "type": "number",
      "description": "The maximum amount of staff that can start a shift in the department at once"
    },
    "min_length": {
      "type": "number",
      "description": "The minimum length of a shift required for this department in hours"
    },
    "max_length": {
      "type": "number",
      "description": "The maximum length of a shift required for this department in hours"
    },
    "time_to_open": {
      "type": "number",
      "description": "The amount of time in hours required to have staff in this department before demand data"
    },
    "time_to_close": {
      "type": "number",
      "description": "The amount of time in hours required to have staff in this department after demand data"
    },
    "undercoverage_penalty_ratio": {
      "type": "number",
      "description": "The ratio of appetite to over or under roster based on the demand data for this department"
    },
    "round_down_head_count": {
      "type": "boolean",
      "description": "Round down the required head count for this department 1 becomes 0, 2 becomes 1, etc"
    },
    "consolidate_shift_count": {
      "type": "boolean",
      "description": "Creating longer shifts in place of short shifts"
    }
  },
  "required": [
    "id"
  ]
}

Get Cognitive Creator Configuration
GET/api/v2/cognitive_creator_configuration

Gets the specified Cognitive Creator Configuration by ID.


PUT https://my.tanda.co/api/v2/cognitive_creator_configuration
RequestsCognitive Creator Configuration
Headers
Content-Type: application/json
Body
{
  "minimum_staff": 0,
  "maximum_staff": 3,
  "max_concurrent_start": 2,
  "min_length": 3.5,
  "max_length": 8,
  "time_to_open": 0.5,
  "time_to_close": 0.5,
  "undercoverage_penalty_ratio": 1.3,
  "round_down_head_count": true,
  "consolidate_shift_count": true
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 12,
  "minimum_staff": 1,
  "maximum_staff": 3,
  "max_concurrent_start": 2,
  "min_length": 3.5,
  "max_length": 8,
  "time_to_open": 0.5,
  "time_to_close": 0.5,
  "undercoverage_penalty_ratio": 1.3,
  "round_down_head_count": false,
  "consolidate_shift_count": true
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The cognitive creator configuration ID"
    },
    "minimum_staff": {
      "type": "number",
      "description": "The minimum amount of staff required for a shift in the department"
    },
    "maximum_staff": {
      "type": "number",
      "description": "The maximum amount of staff required for a shift in the department"
    },
    "max_concurrent_start": {
      "type": "number",
      "description": "The maximum amount of staff that can start a shift in the department at once"
    },
    "min_length": {
      "type": "number",
      "description": "The minimum length of a shift required for this department in hours"
    },
    "max_length": {
      "type": "number",
      "description": "The maximum length of a shift required for this department in hours"
    },
    "time_to_open": {
      "type": "number",
      "description": "The amount of time in hours required to have staff in this department before demand data"
    },
    "time_to_close": {
      "type": "number",
      "description": "The amount of time in hours required to have staff in this department after demand data"
    },
    "undercoverage_penalty_ratio": {
      "type": "number",
      "description": "The ratio of appetite to over or under roster based on the demand data for this department"
    },
    "round_down_head_count": {
      "type": "boolean",
      "description": "Round down the required head count for this department 1 becomes 0, 2 becomes 1, etc"
    },
    "consolidate_shift_count": {
      "type": "boolean",
      "description": "Creating longer shifts in place of short shifts"
    }
  },
  "required": [
    "id"
  ]
}

Put Cognitive Creator Configuration
PUT/api/v2/cognitive_creator_configuration

Update the specified Cognitive Creator Configuration by ID.


DELETE https://my.tanda.co/api/v2/cognitive_creator_configuration
Responses200
Headers
Content-Type: application/json

Delete Cognitive Creator Configuration
DELETE/api/v2/cognitive_creator_configuration

Delete the specified Cognitive Creator Configuration by ID. This will effectively reset the settings to default.


Cognitive Creator Configuration by department

GET https://my.tanda.co/api/v2/cognitive_creator_configuration/for_department
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 12,
  "minimum_staff": 1,
  "maximum_staff": 3,
  "max_concurrent_start": 2,
  "min_length": 3.5,
  "max_length": 8,
  "time_to_open": 0.5,
  "time_to_close": 0.5,
  "undercoverage_penalty_ratio": 1.3,
  "round_down_head_count": false,
  "consolidate_shift_count": true
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The cognitive creator configuration ID"
    },
    "minimum_staff": {
      "type": "number",
      "description": "The minimum amount of staff required for a shift in the department"
    },
    "maximum_staff": {
      "type": "number",
      "description": "The maximum amount of staff required for a shift in the department"
    },
    "max_concurrent_start": {
      "type": "number",
      "description": "The maximum amount of staff that can start a shift in the department at once"
    },
    "min_length": {
      "type": "number",
      "description": "The minimum length of a shift required for this department in hours"
    },
    "max_length": {
      "type": "number",
      "description": "The maximum length of a shift required for this department in hours"
    },
    "time_to_open": {
      "type": "number",
      "description": "The amount of time in hours required to have staff in this department before demand data"
    },
    "time_to_close": {
      "type": "number",
      "description": "The amount of time in hours required to have staff in this department after demand data"
    },
    "undercoverage_penalty_ratio": {
      "type": "number",
      "description": "The ratio of appetite to over or under roster based on the demand data for this department"
    },
    "round_down_head_count": {
      "type": "boolean",
      "description": "Round down the required head count for this department 1 becomes 0, 2 becomes 1, etc"
    },
    "consolidate_shift_count": {
      "type": "boolean",
      "description": "Creating longer shifts in place of short shifts"
    }
  },
  "required": [
    "id"
  ]
}

Get Cognitive Creator Configuration
GET/api/v2/cognitive_creator_configuration/for_department

Get Cognitive Creator Configuration for a department.


POST https://my.tanda.co/api/v2/cognitive_creator_configuration/for_department
RequestsCognitive Creator Configuration
Headers
Content-Type: application/json
Body
{
  "minimum_staff": 0,
  "maximum_staff": 3,
  "max_concurrent_start": 2,
  "min_length": 3.5,
  "max_length": 8,
  "time_to_open": 0.5,
  "time_to_close": 0.5,
  "undercoverage_penalty_ratio": 1.3,
  "round_down_head_count": true,
  "consolidate_shift_count": true
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 12,
  "minimum_staff": 1,
  "maximum_staff": 3,
  "max_concurrent_start": 2,
  "min_length": 3.5,
  "max_length": 8,
  "time_to_open": 0.5,
  "time_to_close": 0.5,
  "undercoverage_penalty_ratio": 1.3,
  "round_down_head_count": false,
  "consolidate_shift_count": true
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The cognitive creator configuration ID"
    },
    "minimum_staff": {
      "type": "number",
      "description": "The minimum amount of staff required for a shift in the department"
    },
    "maximum_staff": {
      "type": "number",
      "description": "The maximum amount of staff required for a shift in the department"
    },
    "max_concurrent_start": {
      "type": "number",
      "description": "The maximum amount of staff that can start a shift in the department at once"
    },
    "min_length": {
      "type": "number",
      "description": "The minimum length of a shift required for this department in hours"
    },
    "max_length": {
      "type": "number",
      "description": "The maximum length of a shift required for this department in hours"
    },
    "time_to_open": {
      "type": "number",
      "description": "The amount of time in hours required to have staff in this department before demand data"
    },
    "time_to_close": {
      "type": "number",
      "description": "The amount of time in hours required to have staff in this department after demand data"
    },
    "undercoverage_penalty_ratio": {
      "type": "number",
      "description": "The ratio of appetite to over or under roster based on the demand data for this department"
    },
    "round_down_head_count": {
      "type": "boolean",
      "description": "Round down the required head count for this department 1 becomes 0, 2 becomes 1, etc"
    },
    "consolidate_shift_count": {
      "type": "boolean",
      "description": "Creating longer shifts in place of short shifts"
    }
  },
  "required": [
    "id"
  ]
}

Post Cognitive Creator Configuration
POST/api/v2/cognitive_creator_configuration/for_department

Create cognitive creator configuration for a department. Posting another cognitive creator configuration for a department will override the current configuration.


Predicted Store Stats

Our user guide has more information on working with data streams through the API.

Predicted store stats are identical to the Store Stats model, however, instead of being for what actually happened, they are the prediction of what will happen. All predicted store stats for a data stream should be totaled data for a time period equal to the data stream’s data_interval, ending at a predicted store stat’s time.

Only predicted store stats where the type parameter is equal to “sales” will be displayed on the weekly planner on the dashboard. You’re able to store a wide variety of stats in Tanda, and differentiate them using the type parameter, but be aware of this special case.

Predicted store stats can be read by a user, if that user is able to read the data stream that the store stat belongs to.

Only admins can create predicted store stats. They are able to do this for any data stream.

The api currently only supports POST and GET methods of Predicted Store Stats.

Predicted Store Stats for Datastream

GET https://my.tanda.co/api/v2/predicted_storestats/for_datastream/26?from=2016-03-01&to=2016-03-20&type=sales
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 3518,
    "time": 1459295100,
    "stat": 3.5,
    "type": "sales",
    "datastream_id": 24
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Predicted Store Stats for Datastream
GET/api/v2/predicted_storestats/for_datastream/{datastream_id}{?from,to,type}

This method requires the datastream scope (see Scopes for more information).

You will only be able to query up to 31 days using the from and to parameters.

URI Parameters
HideShow
datastream_id
number (required) Example: 26

The id of the data stream to lookup store stats for

from
string (required) Example: 2016-03-01

The start date of the range to lookup store stats in

to
string (required) Example: 2016-03-20

The id of the data stream to lookup store stats for

type
string (optional) Example: sales

The type of store stats to lookup (if not specified, all stats are returned)


Predicted Store Stats for Location

GET https://my.tanda.co/api/v2/predicted_storestats/for_location/26?from=2016-03-01&to=2016-03-20
Responses200
Headers
Content-Type: application/json
Body
{
  "data_stream": {
    "id": 24,
    "name": "Reactor Revenue",
    "source": "generic",
    "data_interval": 900,
    "print_mode": "hidden",
    "roster_display_mode": "values"
  },
  "data_stream_joins": [
    {
      "id": 162,
      "data_stream_id": 24,
      "data_streamable_id": 111,
      "data_streamable_type": "Department",
      "rostering_ratio": 1.175,
      "head_count_map": "\"1,2.5,5\""
    }
  ],
  "stat_type": "sales",
  "stats": [
    {
      "id": 3518,
      "time": 1459295100,
      "stat": 3.5,
      "type": "sales",
      "datastream_id": 24
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "data_stream": {
      "type": "object",
      "properties": {
        "id": {
          "type": "number",
          "description": "The id of the data stream"
        },
        "name": {
          "type": "string",
          "description": "The name of the data stream"
        },
        "source": {
          "type": "string",
          "description": "The data stream's source"
        },
        "data_interval": {
          "type": "number",
          "description": "The time between the data stream's store stats in seconds"
        },
        "print_mode": {
          "type": "string",
          "description": "Should the data stream be printed when printing a roster? Options: hidden, values, cumulative_sum"
        },
        "roster_display_mode": {
          "type": "string",
          "description": "Should the data stream be displayed on rosters? Options: hidden, values, cumulative_sum"
        }
      },
      "required": [
        "id",
        "name",
        "source",
        "data_interval"
      ]
    },
    "data_stream_joins": {
      "type": "array"
    },
    "stat_type": {
      "type": "string"
    },
    "stats": {
      "type": "array"
    }
  }
}

Predicted Store Stats for Location
GET/api/v2/predicted_storestats/for_location/{location_id}{?from,to}

This method requires the datastream scope (see Scopes for more information).

You will only be able to query up to 31 days using the from and to parameters.

URI Parameters
HideShow
location_id
number (required) Example: 26

The id of the location to lookup store stats for

from
string (required) Example: 2016-03-01

The start date of the range to lookup store stats in.

to
string (required) Example: 2016-03-20

The id of the data stream to lookup store stats for. We will crop the data to the nearest business day, eg if the location is open 8am -> midnight, then we will set the cuttoff time for the data to be 4am. Data before then will go to the previous business day, data after will come in for this business day.


Predicted Store Stats for Multiple Datastreams

POST https://my.tanda.co/api/v2/predicted_storestats/for_datastream
RequestsCreate single Predicted Store StatCreate multiple Store Stats
Headers
Content-Type: application/json
Body
{
  "datastream_id": 123457,
  "time": 1459296900,
  "stat": 3.5,
  "type": "sales"
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 12231,
  "time": 1459296900,
  "stat": 3.5,
  "type": "sales",
  "datastream_id": 123457
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the stat"
    },
    "time": {
      "type": "number",
      "description": "The time of the stat"
    },
    "stat": {
      "type": "number",
      "description": "The value of the stat"
    },
    "type": {
      "type": "string",
      "description": "The type of the stat"
    },
    "datastream_id": {
      "type": "number",
      "description": "The id of the data stream join's data stream"
    }
  },
  "required": [
    "id",
    "time",
    "stat",
    "type",
    "datastream_id"
  ]
}
Headers
Content-Type: application/json
Body
{
      "stats": [
        {
          "datastream_id": 123456,
          "time": 1459296900,
          "stat": 7.5,
          "type": "sales"
        },
        {
          "datastream_id": 123456,
          "time": 1459296900,
          "stat": 3,
          "type": "transactions"
        },
        {
          "datastream_id": 123457,
          "time": 1459297800,
          "stat": 3.5,
          "type": "sales"
        },
        {
          "datastream_id": 123457,
          "time": 1459297800,
          "stat": 1,
          "type": "transactions"
        }
        }
      ]
    }
Responses201
Headers
Content-Type: application/json
Body
[
  {
    "id": 12231,
    "datastream_id": 123456,
    "time": 1459296900,
    "stat": 7.5,
    "type": "sales"
  },
  {
    "id": 12232,
    "datastream_id": 123456,
    "time": 1459296900,
    "stat": 3,
    "type": "transactions"
  },
  {
    "id": 12233,
    "datastream_id": 123457,
    "time": 1459297800,
    "stat": 3.5,
    "type": "sales"
  },
  {
    "id": 12234,
    "datastream_id": 123457,
    "time": 1459297800,
    "stat": 1,
    "type": "transactions"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Predicted Store Stats for Multiple Datastreams
POST/api/v2/predicted_storestats/for_datastream

To post predicted store stats in bulk, simply represent them all in an array, with the datastream_id included for each stat. Note that each combination of datastream_id, time and type must be unique - you must not send duplicate data.

POSSIBLE DATA DELETION: All existing predicted store stats on the data stream within the newly posted store stats’ time parameter range will be replaced with the newly posted predicted store stats.

Please see the general Store Stat information above for an example.

{
  "stats": [
    {
      "datastream_id": 123456,
      "time": 1459296900,
      "stat": 7.5,
      "type": "sales"
    },
    {
      "datastream_id": 123456,
      "time": 1459297800,
      "stat": 3,
      "type": "transactions"
    }
    {
      "datastream_id": 123457,
      "time": 1459296900,
      "stat": 3.5,
      "type": "sales"
    },
    {
      "datastream_id": 123457,
      "time": 1459297800,
      "stat": 1,
      "type": "transactions"
    }
  ]
}

Delete Predicted Store Stats

DELETE https://my.tanda.co/api/v2/predicted_storestats/for_datastream/26?from=2016-03-01&to=2016-03-20
Responses200
Headers
Content-Type: application/json
Body
{
  "stats": [
    {
      "id": 3518,
      "time": 1459295100,
      "stat": 3.5,
      "type": "sales"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "stats": {
      "type": "array"
    }
  }
}

Delete Predicted Store Stats
DELETE/api/v2/predicted_storestats/for_datastream/{datastream_id}{?from,to}

This method requires the datastream scope (see Scopes for more information).

You will only be able to query up to 31 days using the from and to parameters.

URI Parameters
HideShow
datastream_id
number (required) Example: 26

The id of the datastream to lookup store stats for

from
string (required) Example: 2016-03-01

The start date of the range to lookup store stats in.

to
string (required) Example: 2016-03-20

The end of the date range of to lookup store stats in. We will crop the data to the nearest business day, eg if the location is open 8am -> midnight, then we will set the cuttoff time for the data to be 4am. Data before then will go to the previous business day, data after will come in for this business day.


Stat Types

Stat Types connect Data Streams to the object which owns the stream’s data. For example, data from a stream may be relate to a Team, Location, or to the Organisation itself.

Stat Type List

GET https://my.tanda.co/api/v2/stat_types
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 162,
    "stat_type": "sales",
    "label": "Sales",
    "format": "currency",
    "data_type": "sum"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Stat Types
GET/api/v2/stat_types

This method requires the datastream scope (see Scopes for more information).


Stat Type

GET https://my.tanda.co/api/v2/stat_types/162
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 162,
  "stat_type": "sales",
  "label": "Sales",
  "format": "currency",
  "data_type": "sum"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the data stream join"
    },
    "stat_type": {
      "type": "string",
      "description": "The ket of the stat type, this much exactly match whats uploaded to StoreStats"
    },
    "label": {
      "type": "string",
      "description": "The human readable name for this stat type"
    },
    "format": {
      "type": "string",
      "description": "How this stat type is formatted"
    },
    "data_type": {
      "type": "string",
      "description": "What kind of data this is (sum or static)"
    }
  },
  "required": [
    "id",
    "stat_type",
    "label"
  ]
}

Get Stat Type
GET/api/v2/stat_types/{id}

This method requires the datastream scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The id of the stat type to lookup


POST https://my.tanda.co/api/v2/stat_types
RequestsCreate Stat TypeCreate stat type with custom formatCreate stat type for head counts
Headers
Content-Type: application/json
Body
{
  "stat_type": "sales",
  "label": "Sales",
  "format": "currency",
  "data_type": "sum"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 162,
  "stat_type": "sales",
  "label": "Sales",
  "format": "currency",
  "data_type": "sum"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the data stream join"
    },
    "stat_type": {
      "type": "string",
      "description": "The ket of the stat type, this much exactly match whats uploaded to StoreStats"
    },
    "label": {
      "type": "string",
      "description": "The human readable name for this stat type"
    },
    "format": {
      "type": "string",
      "description": "How this stat type is formatted"
    },
    "data_type": {
      "type": "string",
      "description": "What kind of data this is (sum or static)"
    }
  },
  "required": [
    "id",
    "stat_type",
    "label"
  ]
}
Headers
Content-Type: application/json
Body
{
  "stat_type": "deliveries",
  "label": "Deliveries",
  "format": "%{whole_number} 🚚",
  "data_type": "sum"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 162,
  "stat_type": "deliveries",
  "label": "Deliveries",
  "format": "%{whole_number} 🚚",
  "data_type": "sum"
}
Headers
Content-Type: application/json
Body
{
  "stat_type": "required staff",
  "label": "Required Staff",
  "format": "people",
  "data_type": "static"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 162,
  "stat_type": "required staff",
  "label": "Required Staff",
  "format": "people",
  "data_type": "static"
}

Create Stat Type
POST/api/v2/stat_types

This method requires the datastream scope (see Scopes for more information).


PUT https://my.tanda.co/api/v2/stat_types/162
RequestsUpdate Stat Type
Headers
Content-Type: application/json
Body
{
  "format": "whole_number"
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 162,
  "stat_type": "sales",
  "label": "Sales",
  "format": "whole_number",
  "data_type": "sum"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The id of the data stream join"
    },
    "stat_type": {
      "type": "string",
      "description": "The ket of the stat type, this much exactly match whats uploaded to StoreStats"
    },
    "label": {
      "type": "string",
      "description": "The human readable name for this stat type"
    },
    "format": {
      "type": "string",
      "description": "How this stat type is formatted"
    },
    "data_type": {
      "type": "string",
      "description": "What kind of data this is (sum or static)"
    }
  },
  "required": [
    "id",
    "stat_type",
    "label"
  ]
}

Update Stat Type
PUT/api/v2/stat_types/{id}

This method requires the datastream scope (see Scopes for more information).

You cannot modify the stat_type field on a Stat Type. You must create a new stat type instead.

URI Parameters
HideShow
id
number (required) Example: 162

The id of the stat type to update


DELETE https://my.tanda.co/api/v2/stat_types/162
Responses200
Headers
Content-Type: application/json

Delete Stat Type
DELETE/api/v2/stat_types/{id}

This method requires the datastream scope (see Scopes for more information).

This will delete ALL store stats, and data stream joins that have been created with this stat type. Please be careful.

URI Parameters
HideShow
id
number (required) Example: 162

The id of the stat type to delete


Wage Comparison

Wage Comparisons are used to compare the wage cost of employees under different rates of pay.

Wage Comparison List

GET https://my.tanda.co/api/v2/wage_comparisons
Responses200
Headers
Content-Type: application/json
Body
[
  {
    "id": 34,
    "from_date": "2020-12-31",
    "to_date": "2021-11-29",
    "award_template_organisation_id": 56,
    "hourly_rate": 32.47,
    "salary": 1234.12,
    "award_tags": "\"Level 8,Full Time,First Aid Certificate\""
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Get Wage Comparisons
GET/api/v2/wage_comparisons

This method requires the cost scope (see Scopes for more information).


Wage Comparison

GET https://my.tanda.co/api/v2/wage_comparisons/162
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 34,
  "from_date": "2020-12-31",
  "to_date": "2021-11-29",
  "award_template_organisation_id": 56,
  "hourly_rate": 32.47,
  "salary": 1234.12,
  "award_tags": "\"Level 8,Full Time,First Aid Certificate\""
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The Wage Comparison ID"
    },
    "from_date": {
      "type": "string",
      "description": "The date the Wage comparison Starts"
    },
    "to_date": {
      "type": "string",
      "description": "the date the wage comparison Ends"
    },
    "award_template_organisation_id": {
      "type": "number",
      "description": "The award template organisation id belonging to the desired award."
    },
    "hourly_rate": {
      "type": "number",
      "description": "The hourly rate of the user"
    },
    "salary": {
      "type": "number",
      "description": "The weekly salary of the user"
    },
    "award_tags": {
      "type": "string",
      "description": "a list of award tags that applies to the employee."
    }
  },
  "required": [
    "id",
    "from_date",
    "to_date"
  ]
}

Get Wage Comparison
GET/api/v2/wage_comparisons/{id}

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The id of the wage comparison to lookup


POST https://my.tanda.co/api/v2/wage_comparisons
RequestsCreate Wage Comparison
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "from_date": "2016-03-12",
  "to_date": "2017-04-12",
  "hourly_rate": 22.36,
  "salary": 808,
  "award_tags": "full time, meal break",
  "award_template_organisation_id": 4
}
Responses201
Headers
Content-Type: application/json
Body
{
  "id": 0,
  "from_date": "2016",
  "to_date": "2017",
  "award_template_organisation_id": "4",
  "hourly_rate": "22.36",
  "salary": "808",
  "award_tags": "full time, meal break",
  "user_id": "123456"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The Wage Comparison ID"
    },
    "from_date": {
      "type": "string",
      "description": "03-12"
    },
    "to_date": {
      "type": "string",
      "description": "04-12"
    },
    "award_template_organisation_id": {
      "type": "string",
      "description": "The award template organisation id belonging to the desired award."
    },
    "hourly_rate": {
      "type": "string",
      "description": "The hourly rate of the user"
    },
    "salary": {
      "type": "string",
      "description": "The weekly salary of the user"
    },
    "award_tags": {
      "type": "string",
      "description": "a list of award tags that applies to the employee."
    },
    "user_id": {
      "type": "string"
    }
  },
  "required": [
    "id",
    "from_date",
    "to_date"
  ]
}

Create Wage Comparison
POST/api/v2/wage_comparisons

To post a wage comparison for an employee, include the user_id and from_date along with any required optional parameters. Note that from_date and to_date must not overlap for different wage comparisons for the same user.

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
user_id
number (required) Example: 1

The ID of the user being compared.

from_date
string (required) Example: 2016-03-02

The date comparison starts from.

to_date
string (optional) Example: 2016-03-02

The date the comparison goes to, will go forever and ever, if it’s left blank.

hourly_rate
number (optional) Example: 22.56

The hourly rate of the comparison.

salary
number (optional) Example: 70592

the salary of the comparison.

award_tags
string (optional) Example: 'full time, meal break'

A comma separated list of award tags that apply to the comparison.

award_template_organisation_id
number (optional) Example: 4

the relevant award template organisation id.


PUT https://my.tanda.co/api/v2/wage_comparisons/162
RequestsUpdate Wage Comparison
Headers
Content-Type: application/json
Body
{
  "user_id": 123456,
  "from_date": "2016-03-12",
  "to_date": "2017-04-12",
  "hourly_rate": 22.36,
  "salary": 808,
  "award_tags": "full time, meal break",
  "award_template_organisation_id": 4
}
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 0,
  "from_date": "2016",
  "to_date": "2017",
  "award_template_organisation_id": "4",
  "hourly_rate": "22.36",
  "salary": "808",
  "award_tags": "full time, meal break",
  "user_id": "123456"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The Wage Comparison ID"
    },
    "from_date": {
      "type": "string",
      "description": "03-12"
    },
    "to_date": {
      "type": "string",
      "description": "04-12"
    },
    "award_template_organisation_id": {
      "type": "string",
      "description": "The award template organisation id belonging to the desired award."
    },
    "hourly_rate": {
      "type": "string",
      "description": "The hourly rate of the user"
    },
    "salary": {
      "type": "string",
      "description": "The weekly salary of the user"
    },
    "award_tags": {
      "type": "string",
      "description": "a list of award tags that applies to the employee."
    },
    "user_id": {
      "type": "string"
    }
  },
  "required": [
    "id",
    "from_date",
    "to_date"
  ]
}

Update Wage Comparison
PUT/api/v2/wage_comparisons/{id}

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The id of the wage comparison to update

user_id
number (optional) Example: 1

The ID of the user being compared.

from_date
string (required) Example: 2016-03-02

The date comparison starts from.

to_date
string (optional) Example: 2016-03-02

The date the comparison goes to, will go forever and ever, if it’s left blank.

hourly_rate
number (optional) Example: 22.56

The hourly rate of the comparison.

salary
number (optional) Example: 70592

the salary of the comparison.

award_tags
string (optional) Example: 'full time, meal break'

A comma separated list of award tags that apply to the comparison.

award_template_organisation_id
number (optional) Example: 4

the relevant award template organisation id.


DELETE https://my.tanda.co/api/v2/wage_comparisons/162
Responses200
Headers
Content-Type: application/json

Delete Wage Comparison
DELETE/api/v2/wage_comparisons/{id}

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The id of the wage comparison to delete


Wage Comparison Outer Limits User Setting

GET https://my.tanda.co/api/v2/wage_comparisons/162/outer_limits
Responses200404404
Headers
Content-Type: application/json
Body
{
  "id": 34,
  "penalty_hours": 6,
  "overtime_hours": 6,
  "averaging_cadence: pay_cycle": "Hello, world!",
  "custom_cycle_length": "weekly",
  "custom_anchor_date": "Hello, world!"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The Outer Limits User Settings ID."
    },
    "penalty_hours": {
      "type": "number",
      "description": "The outer limit of penalty hours."
    },
    "overtime_hours": {
      "type": "number",
      "description": "The outer limit of overtime hours."
    },
    "averaging_cadence: pay_cycle": {
      "type": "string",
      "description": "The averaging cadence to use. One of `pay_cycle`, `overtime_averaging`, or `other`."
    },
    "custom_cycle_length": {
      "type": "string",
      "description": "If `averaging_cadence` is set to `other`, this value is the cycle length that will be used - one of `weekly`, `fortnightly`, `three_weekly`, or `four_weekly`. Otherwise, it is always null."
    },
    "custom_anchor_date": {
      "type": "string",
      "description": "If `averaging_cadence` is set to `other`, this value is the anchor for each cycle. For example, if the anchor date is set to Monday 24th January and the cycle length is weekly, the outer limit test period will be each Monday to the following Saturday."
    }
  },
  "required": [
    "id",
    "penalty_hours",
    "overtime_hours",
    "averaging_cadence: pay_cycle"
  ]
}
Headers
Content-Type: application/json
Body
{
  "error": "No known Wage Comparison with id 162"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  }
}
Headers
Content-Type: application/json
Body
{
  "error": "Wage comparison does not have any outer limits set"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  }
}

Get Wage Comparison Outer Limits User Setting
GET/api/v2/wage_comparisons/{id}/outer_limits

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The ID of the wage comparison that has the outer limit user setting.


POST https://my.tanda.co/api/v2/wage_comparisons/162/outer_limits
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "penalty_hours": 6,
  "overtime_hours": 6,
  "averaging_cadence": "other",
  "custom_cycle_length": "weekly",
  "custom_anchor_date": "2022-01-24"
}
Responses200409404
Headers
Content-Type: application/json
Body
{
  "id": 34,
  "penalty_hours": 6,
  "overtime_hours": 6,
  "averaging_cadence: pay_cycle": "Hello, world!",
  "custom_cycle_length": "weekly",
  "custom_anchor_date": "Hello, world!"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The Outer Limits User Settings ID."
    },
    "penalty_hours": {
      "type": "number",
      "description": "The outer limit of penalty hours."
    },
    "overtime_hours": {
      "type": "number",
      "description": "The outer limit of overtime hours."
    },
    "averaging_cadence: pay_cycle": {
      "type": "string",
      "description": "The averaging cadence to use. One of `pay_cycle`, `overtime_averaging`, or `other`."
    },
    "custom_cycle_length": {
      "type": "string",
      "description": "If `averaging_cadence` is set to `other`, this value is the cycle length that will be used - one of `weekly`, `fortnightly`, `three_weekly`, or `four_weekly`. Otherwise, it is always null."
    },
    "custom_anchor_date": {
      "type": "string",
      "description": "If `averaging_cadence` is set to `other`, this value is the anchor for each cycle. For example, if the anchor date is set to Monday 24th January and the cycle length is weekly, the outer limit test period will be each Monday to the following Saturday."
    }
  },
  "required": [
    "id",
    "penalty_hours",
    "overtime_hours",
    "averaging_cadence: pay_cycle"
  ]
}
Headers
Content-Type: application/json
Body
{
  "error": "Wage comparison already has outer limits set"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  }
}
Headers
Content-Type: application/json
Body
{
  "error": "No known Wage Comparison with id 162"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  }
}

Create Wage Comparison Outer Limits User Setting
POST/api/v2/wage_comparisons/{id}/outer_limits

If a wage comparison does not have outer limits set, this endpoint creates them. If the wage comparison already has outer limits, an error will be returned.

The outer limit user setting that is created will also be returned in the response.

The request fields are as follows:

  • penalty_hours number: (required) Example: 6.
    The outer limit of penalty hours.

  • overtime_hours number: (required) Example: 6.
    The outer limit of overtime hours.

  • averaging_cadence string: (required) Example: pay_cycle.
    The averaging cadence to use. Must be one of pay_cycle, overtime_averaging, or other.

  • custom_cycle_length string: (optional) Example: weekly.
    If averaging_cadence is set to other, this value is required and is the cycle length that will be used. Otherwise, the value is ignored. Must be one of weekly, fortnightly, three_weekly, or four_weekly.

  • custom_anchor_date date: (optional) Example: 2022-01-24.
    If averaging_cadence is set to other, this value is required and is used as the anchor for each cycle. For example, if the anchor date is set to Monday 24th January and the cycle length is weekly, the outer limit test period will be each Monday to the following Sunday.

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The ID of the wage comparison that the outer limit setting will be created for.


PUT https://my.tanda.co/api/v2/wage_comparisons/162/outer_limits
Requestsexample 1
Headers
Content-Type: application/json
Body
{
  "penalty_hours": 9
}
Responses200404404
Headers
Content-Type: application/json
Body
{
  "id": 34,
  "penalty_hours": 6,
  "overtime_hours": 6,
  "averaging_cadence: pay_cycle": "Hello, world!",
  "custom_cycle_length": "weekly",
  "custom_anchor_date": "Hello, world!"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "number",
      "description": "The Outer Limits User Settings ID."
    },
    "penalty_hours": {
      "type": "number",
      "description": "The outer limit of penalty hours."
    },
    "overtime_hours": {
      "type": "number",
      "description": "The outer limit of overtime hours."
    },
    "averaging_cadence: pay_cycle": {
      "type": "string",
      "description": "The averaging cadence to use. One of `pay_cycle`, `overtime_averaging`, or `other`."
    },
    "custom_cycle_length": {
      "type": "string",
      "description": "If `averaging_cadence` is set to `other`, this value is the cycle length that will be used - one of `weekly`, `fortnightly`, `three_weekly`, or `four_weekly`. Otherwise, it is always null."
    },
    "custom_anchor_date": {
      "type": "string",
      "description": "If `averaging_cadence` is set to `other`, this value is the anchor for each cycle. For example, if the anchor date is set to Monday 24th January and the cycle length is weekly, the outer limit test period will be each Monday to the following Saturday."
    }
  },
  "required": [
    "id",
    "penalty_hours",
    "overtime_hours",
    "averaging_cadence: pay_cycle"
  ]
}
Headers
Content-Type: application/json
Body
{
  "error": "No known Wage Comparison with id 162"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  }
}
Headers
Content-Type: application/json
Body
{
  "error": "Wage comparison does not have any outer limits set"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  }
}

Update Wage Comparison Outer Limits User Setting
PUT/api/v2/wage_comparisons/{id}/outer_limits

Updates an existing outer limits user setting with new data. This endpoint supports partial updates - you only need to specify the fields that you wish to update.

The full outer limits user setting will be returned in the response.

See Create Wage Comparison Outer Limits User Settings for more information about the request fields.

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The ID of the wage comparison that the outer limit setting will be created for.


DELETE https://my.tanda.co/api/v2/wage_comparisons/162/outer_limits
Responses200404404
Headers
Content-Type: application/json
Headers
Content-Type: application/json
Body
{
  "error": "No known Wage Comparison with id 162"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  }
}
Headers
Content-Type: application/json
Body
{
  "error": "Wage comparison does not have any outer limits set"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    }
  }
}

Delete Wage Comparison Outer Limits User Setting
DELETE/api/v2/wage_comparisons/{id}/outer_limits

This endpoint deletes the outer limits settings for a wage comparison. If the deletion was successful, the response is empty.

This method requires the cost scope (see Scopes for more information).

URI Parameters
HideShow
id
number (required) Example: 162

The ID of the wage comparison that the outer limit setting will be created for.


GET https://my.tanda.co/api/v2/recommended_hours?department_id=1234&from_date=2016-03-02&to_date=2016-03-02
Responses200
Headers
Content-Type: application/json
Body
{
  "department_id": 1234,
  "department_name": "Delivery Team",
  "total_recommended_hours_for_date_range": "110.0",
  "recommended_hours_by_date": {
    "2016-04-01": 31,
    "2016-04-02": 10,
    "2016-04-03": 25
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "department_id": {
      "type": "number",
      "description": "The ID of the department"
    },
    "department_name": {
      "type": "string",
      "description": "The name of the department"
    },
    "total_recommended_hours_for_date_range": {
      "type": "string",
      "description": "The total recommended hours for the date range"
    },
    "recommended_hours_by_date": {
      "type": "object",
      "properties": {
        "2016-04-01": {
          "type": "number",
          "description": "The number of hours for that date."
        },
        "2016-04-02": {
          "type": "number",
          "description": "The number of hours for that date."
        },
        "2016-04-03": {
          "type": "number",
          "description": "The number of hours for that date."
        }
      },
      "required": [
        "2016-04-01",
        "2016-04-02",
        "2016-04-03"
      ]
    }
  },
  "required": [
    "department_id",
    "department_name"
  ]
}