10,000ft API (Pro, Enterprise, and Business plans)

The 10,000ft API provides programmatic access to projects, users and time entries in your account, commonly referred to as resources in the rest of this API documentation. The API implements a standard HTTP REST pattern and allows callers with appropriate authentication and authorization to programmatically create, read, update and delete these resources.

API access is available on Pro, Enterprise and Business plans of 10000ft. As of June 2019, all new plans purchased are Business, and include API access. For customers prior to this date, API access is based on your current plan.

Overview

Need help?

  • Contact us via our Support Page
    • Read more on how to report a problem here.
  • Have a suggestion for improving our API documentation? Send us a pull-request or email support.

Endpoints

The API provides access to the following data collections in your account via RESTful endpoints.

Webhook Support

The 10,000ft API supports webhooks for certain events. See the webhooks section for details.

Zapier Integration

Our Zapier integration helps you integrating with the 10,000ft API in convenient and powerful ways and connect many other apps and services used by yor team.

Third party libraries

A few of our customers have implemented and shared API client libraries to help using the 10Kft API easier. Depending on your scenario, you may benefit from adopting and improving on them. Here are a couple of references,

Questions?

Questions or feedback about our API, please submit a support ticket at our Support Page

Sections

Before starting to use the 10,000ft API

This documentation assumes that you have either signed up for a 10,000ft trial or you have an active subscription, and that you are familiar with the basic features of the application. The information that follows give you an overview of accessing the same functionality, from an API, so that you can implement additional functionality and custom integrations that meet your specific business needs.

We also assume that you are familiar with basic RESTful API concepts.

  IMPORTANT

  Do not perform stress or performance testing in any 
  account without informing 10,000ft support and obtaining explicit 
  approval. Violation of this may result in your account being suspended.

Being notified about important changes

There are several ways in which you can stay informed about important changes to the API.

  • Ask your friendly account Administrator to add your email as the developer contact for your account.
  • Subscribe to be notified when updates are made to this github repo by following it or using the watch feature.

Collections & Objects

The API follows a typical RESTful pattern where it allows you to access collections of objects via HTTP. These Collections are paginated, and are always delivered in a structure that has a ‘data’ array and 'paging’ meta-data, as shown below. This is true top level as well as nested collections.

Some objects returned by the API may have sub-collections. For example, a tags collection for a given user object. These sub-collections are paginated in the same manner as top level collections.

curl -X GET https://api.rm.smartsheet.com/api/v1/users \
  -H "Content-Type: application/json"
  -H "auth: TOKEN"

Will get a JSON response like,

{
  "data" : [
    { "id" : 1, "first_name" : "Tom", "last_name" : "Perera" },
    { "id" : 2, "first_name" : "Jane", "last_name" : "Albert" },
    ...
  ],
  "paging": {
    "page": 1,
    "per_page": 20,
    "previous": null,
    "self": "/api/v1/users/1/statuses?user_id=1&per_page=20&page=1",
    "next": null
  }
}

Unless otherwise noted, the API always responds with JSON.

Pagination

The pagination section in collections provide mechanisms to fetch additional data. The previous and next links provide access to the corresponding pages in the collection. You can override the default per_page value by providing an appropriate value in the URL query parameter. For example,

GET https://api.rm.smartsheet.com/api/v1/users?per_page=100&page=3

Filtering

Some resources in the 10,000ft API respect certain filtering parameters. Those optional parameters are as follows:

  • filter_field - The property to filter on.
  • filter_list - The value of filter_field to match.

Authentication

The API currently supports service token based authentication. This can be sent as a query parameter named auth, or as an HTTP header with the same name.

# Token in http header (recommended)
curl -X GET https://api.rm.smartsheet.com/api/v1/users \
  -H "Content-Type: application/json"
  -H "auth: TOKEN"

# Token on URL
curl -X GET https://api.rm.smartsheet.com/api/v1/users?auth=URL-ENCODED-TOKEN \
  -H "Content-Type: application/json"

Account administrators can obtain the API token from Settings > Developer API in the application.

Optional Fields

To reduce the number of roundtrips that might be required to fetch all related data for a given collection or resource (e.g. fetching a user and all their tags), the API supports a concept of optional fields. These fields are a comma separated list of field names that are supported as a URL parameter when making a request to fetch a resource or a resource collection.

curl -X GET https://api.rm.smartsheet.com/api/v1/users?fields=tags \
  -H "Content-Type: application/json"
  -H "auth: TOKEN"

Each field requested is included in the response as nested collections. The page size for these nested collections will be the same as the page size used for the parent API request.

{
  "data" : [
    {
      "id" : 1,
      "first_name" : "Tom",
      "last_name" : "Perera",
      "tags": {
        "data" : [
          { "id" : 1, "value" : "developer" },
          { "id" : 2, "value" : "javascript" },
        ],
        "paging" : {
          ...
        }
      }
    },
    ...
  ],
  "paging": {
    ...
  }
}

Multiple optional fields can be requested in a single API call like fields=f1,f2.

Date & Time Formatting

The API handles or expects dates and date-time values in various scenarios, and expects the values to be in specific formats.

Date values provided as query parameters when making API calls must be in the 2013-01-31 format.

Time values are accepted in the 2013-09-31T22:10:24Z format, which is a date and time value in UTC time.

Error Handling

Respond with standard HTTP error messages, with 4XX codes to indicate client (caller) errors. There may be an optional response body with a message that has details for debugging / error logging. This message is not meant to end user display or consumption.

HTTP/1.1 400 Bad Request { "message" : "The request body had invalid json" }

Throttling & Rate-Limiting

The API throttles incoming requests to prevent abuse and ensure fair use.

When an application exceeds the rate limit, the API will return a standard HTTP 429 Too Many Requests response.

How to handle being throttled

The specific details of rate limit policies in effect may vary without notice. Application developers should implement detection and handling of rate-limiting behavior using X-Ratelimit-* headers described below.

When a request from your application receives a 429 Too many Requests response, you can check the returned HTTP headers to see your current rate limit status:

X-RateLimit-Limit:120
X-RateLimit-Remaining:0
X-RateLimit-Reset:1482966442

The X-RateLimit-Reset provides the time at which the current rate limit window resets in UTC epoch seconds.

// pseudo-code

MAX_RETRIES = 25

retry_count = 0

while(running == true) {
  response = get_api_response(request_params)

  // if the server throttled the request, re-try until a valid
  // response is received or a maximum number of re-try attempts
  // have been reached
  //
  while(response.status == 429 && retry_count < MAX_RETRIES) {
    // extract the Time in X-RateLimit-Reset
    x_rate_limit_reset_time = get_x_rate_limit_reset(response)

    // wait until the rate limit time window has been reset
    wait_until(x_rate_limit_reset_time)

    // retry the call
    response = get_api_response(request_params)

    retry_count += 1
  }

  handle_response(response)

  retry_count = 0
}

Getting help & reporting problems

There are several ways you can ask for help or report a problem with using the API.

  • For issues that require immediate attention, contact us via our Support Page

When contacting support for assistance with using the API, please provide example API calls where possible. This greatly speeds up the time to resolve support requests. You can use cURL, available on unix platforms as well as windows, to create an example of your scenario, and including the curl command(s) along with your request for support.

Here are some example curl commands;

# get the collection of users
curl -X GET https://api.rm.smartsheet.com/api/v1/users?auth=TOKEN \
  -H "Content-Type: application/json"

# update user 100 with a new last_name
curl -X PUT https://api.rm.smartsheet.com/api/v1/users/100?auth=TOKEN \
  -H "Content-Type: application/json" \
  -d '{"last_name":"Silva"'}'

Approvals

Endpoint: /api/v1/approvals

In 10,000ft, certain record types are considered “approvable.” Currently, these record types are time entries and expense items. Approvals are created when time entries or expense items are “submitted for approval.”

List Approvals

GET /api/v1/approvals

While you can get approvals directly from /api/v1/approvals, a more typical scenario is to include approvals when getting time entries or expense items by specifying “approvals” as a field. One advantage of this is that you also get “unsubmitted” records that do not yet have an associated approval record.

Example

GET /api/v1/users/<user_id>/time_entries

# note "fields=approvals"
curl 'https://api.rm.smartsheet.com/api/v1/users/1/time_entries?fields=approvals&auth=..'

Response

{
  "paging": {
    ...
  },
  "data": [
    {
      "id": 123,
      "user_id": 1,
      "hours": 8,
      "scheduled_hours": null,
      ...
      "approvals": {
        "paging": {
          ...
        },
        "data": [
          {
            "id": 789,
            "status": "pending",
            "approvable_id": 123,
            "approvable_type": "TimeEntry",
            "submitted_by": 1,
            "submitted_at": "2016-10-13T01:52:09Z",
            "approved_by": null,
            "approved_at": null,
            "created_at": "2016-10-13T01:52:09Z",
            "updated_at": "2016-10-13T01:52:09Z"
          }
        ]
      }
    },
    ...
  ]
}

If you do get approvals from /api/v1/approvals, you can similarly specify “approvables” as a field.

Submitting and Approving Approvables

POST /api/v1/approvals

Approvals are not created or updated directly. Rather, approvable records are submitted or approved through a POST request to /api/v1/approvals. Note that only administrators and project managers can approve time and expenses, which means that API users can only submit time and expenses, but not approve.

Required parameters:
Parameter Description
approvables an array of approvable objects
status either “pending” (submitting for approval) or “approved” (approving)
Approvable object:
Parameter Description
id the id of the time entry or expense item
type either “TimeEntry” or “ExpenseItem”
updated_at the “updated_at” time stamp of the time entry or expense item

updated_at is required to ensure that the time entry or expense item has not changed since the submitter or approver has viewed it. For example, if an approver views a time entry of 4 hours and intends to approve that time, but meanwhile someone else updates the time entry to be 5 hours instead of 4, the approver might unintentionally approve a 5 hour time entry while believing they are approving a 4 hour time entry. For this reason, approvals will only be created or updated for approvables that have the correct updated_at value.

Example

POST /api/v1/approvals

# request body
{
  "approvables": [
    {
      "id": 123,
      "type":"TimeEntry",
      "updated_at": "2016-10-04T15:33:32Z"
    }
  ],
  "status": "pending"
}

Response

{
  "paging": {
    ...
  },
  "data": [
    {
      "id": 890,
      "status": "pending",
      "approvable_id": 123,
      "approvable_type": "TimeEntry",
      "submitted_by": 8,
      "submitted_at": "2016-10-13T20:16:40Z",
      "approved_by": null,
      "approved_at": null,
      "created_at": "2016-10-13T20:16:40Z",
      "updated_at": "2016-10-13T20:16:40Z"
    }
  ]
}

Deleting Approvals

DELETE /api/v1/approvals/<approval_id>

Approvals can only be deleted if the status is “pending”.

Assignables

Endpoint: /api/v1/assignables

An assignable in 10K Plans is an object to which an assignment can be made, i.e. a person, placeholder, etc. can be assigned to this object. Currently, there are two types of assignables in 10K Plans, Projects and Leave Types. Phases are also an assignable, but they can be accessed through the projects endpoint.

It is useful to have an understanding of Assignables as an API entity because the Assignments endpoint returns an assignable-id to indicate the object to which the assignment is made, but without knowing the type of that object, it is not clear which endpoint to use to get more details about the object if desired. The assignables endpoint allows you to query directly using the assignable-id from an assignment.

The endpoint supports two actions, index and show. It is not possible to create a generic assignable or to delete one, the Projects/LeaveTypes endpoints should be used for those actions.

List Assignables (index)

GET  /api/v1/assignables

 curl 'https://api.rm.smartsheet.com/api/v1/assignables?auth=...'

Show an Assignable

GET  /api/v1/assignables/<assignable-id>

 curl 'https://api.rm.smartsheet.com/api/v1/assignables/12345?auth=...'

Return values based on type

The format returned by this endpoint depends on the type of the object returned. If a project, the return value will look exactly like what is returned by the Projects endpoint, and if a LeaveType, the return value looks exactly like what is returned by the LeaveTypes endpoint. In both cases, the return value has a type property, which will be Project or LeaveType, respectively (phases also have the type Project).

Sample Response

{
"paging":
    {
        "per_page":20,
        "page":1,"previous":null,
        "self":"/api/v1/assignables?&page=1",
        "next":null
    },
"data": [
    {
        "id":1,
        "description":null,
        "guid":"bd5fa048-b3f4-467a-a3b5-18211d488d21",
        "name":"Vacation",
        "deleted_at”:null,
        "type":"LeaveType",
    },
    {
        "id":4,
        "description":null,
        "guid":"76c4d8d0-4351-4842-8da2-de715d3a37e5",
        "name":"Project A",
        "deleted_at":null,
        "type":"Project",
        "starts_at":"2018-09-15",
        "ends_at":"2018-09-19",
        "parent_id":null,
        "phase_name":null,
        "thumbnail":null,
        "project_code":"",
        "timeentry_lockout":-1,
        "client":""
    }]
}

Assignments

Endpoint: /api/v1/assignments
Endpoint: /api/v1/users/<user_id>/assignments
Endpoint: /api/v1/projects/<project_id>/assignments

Assignments connect a User to a Project or a Phase (part of a project) or a LeaveType.

List all assignments

Optional parameters:
Parameter Description
from get assignments that end after this date
to get assignments that start before this date
per_page, page Parameters for pagination. Default values are per_page = 20 , page = 1 ( the first )
with_phases true to include assignment to phases ( child projects )
GET /api/v1/assignments

 curl 'https://api.rm.smartsheet.com/api/v1/assignments?auth=..'

List assignments for a User or Project

Optional parameters:
Parameter Description
from get assignments that end after this date
to get assignments that start before this date
per_page, page Parameters for pagination. Default values are per_page = 20 , page = 1 ( the first )
with_phases true to include assignment to phases ( child projects )
GET /api/v1/users/<user_id>/assignments

 curl 'https://api.rm.smartsheet.com/api/v1/users/<user_id>/assignments?auth=..'
GET /api/v1/projects/<project_id>/assignments

 curl 'https://api.rm.smartsheet.com/api/v1/projects/<project_id>/assignments?auth=..'

Show an Assignment

GET /api/v1/assignments/<assignment_id>

 curl 'https://api.rm.smartsheet.com/api/v1/assignments/<assignment_id>?auth=..'

Show an Assignment for a User or Project

GET /api/v1/users/<user_id>/assignments/<assignment_id>

 curl 'https://api.rm.smartsheet.com/api/v1/users/<user_id>/assignments/<assignment_id>?auth=..'
GET /api/v1/projects/project_id/assignments/<assignment_id>

 curl 'https://api.rm.smartsheet.com/api/v1/projects/<project_id>/assignments/<assignment_id>?auth=..'

Similarly, in the create and delete examples below, you can call the assignments API on projects specifying a user_id to create an assignment for that user, or to delete an assignment.

Create an Assignment

Typical parameters: starts_at, ends_at, allocation_mode (percent, hours_per_day, fixed), percent, hours_per_day, fixed_hours

POST /api/v1/users/<user_id>/assignments

 curl -d 'leave_id=<leave_id>&starts_at=<YEAR-MO-DAY>&ends_at=<YEAR-MO-DAY>'  \
                 'https://api.rm.smartsheet.com/api/v1/users/<user_id>/assignments?auth=...'

 curl -d 'leave_id=<leave_id>&starts_at=<YEAR-MO-DAY>&ends_at=<YEAR-MO-DAY>&percent=0.25'  \

                 'https://api.rm.smartsheet.com/api/v1/users/<user_id>/assignments?auth=...'

 curl -d 'leave_id=<leave_id>&starts_at=<YEAR-MO-DAY>&ends_at=<YEAR-MO-DAY>&allocation_mode=hours_per_day&hours_per_day=<hours>'  \
                 'https://api.rm.smartsheet.com/api/v1/users/<user_id>/assignments?auth=...'

Remove an Assignment for a User

DELETE /api/v1/users/<user_id>/assignments/<assignment_id>

 curl -XDELETE 'https://api.rm.smartsheet.com/api/v1/users/<user_id>/assignments/<assignment_id>?auth=...'

Sample Response

{
    "data": [
        {
            "id":889,
            "allocation_mode":"percent",
            "percent":1.0 /* only present when allocation_mode is percent */,
            "hours_per_day":8 /* only present when allocation_mode is hours_per_day */,
            "fixed_hours":8 /* only present when allocation_mode is fixed */,
            "user_id":5612,
            "assignable_id":123,
            "ends_at":"2013-10-07",
            "starts_at":"2013-10-03",
            "bill_rate":1.0,
            "bill_rate_id":0
            "repetition_id:" 886,
        },
        ...
    ],
    "paging": {
        "next": null,
        "page": 1,
        "per_page": 20,
        "previous": null,
        "self": "/api/v1/users/1/assignments?user_id=1&per_page=20&page=1"
    }
}

Notes: repetition_id is used for repeated assignments. The value will be NULL when the assignment is not part or a repeating series. repetition_id is equal to the parent assignment.

Create Assignment with Subtasks

Endpoint: /api/v1/assignments

This endpoint allows an assignment to be created with subtasks. It takes all the same post parameters as a regular assignment create with the addition of the subtasks POST parameter. This endpoint returns the assignment object created with the nested subtasks created within it.

Endpoint

POST /api/v1/assignments

Params
param description
subtasks array of one or more subtask objects
Example POST params
POST {
  "user_id": null,
  "assignable_id": 123,
  "ends_at": "2018-06-27",
  "starts_at": "2018-06-21",
  "status_option_id": 1,
  "description": "Build wireframes",
  "note": null,
  "subtasks": [
    {
      "description": "New Task",
      "completed": false
    }
  ]
}
Example JSON Response
{
  "data": [
    {
        "id": 12345,
        "allocation_mode": "percent",
        "percent": 1,
        "user_id": null,
        "assignable_id": 123,
        "ends_at": "2018-06-27",
        "starts_at": "2018-06-21",
        "bill_rate": null,
        "bill_rate_id": null,
        "repetition_id": null,
        "created_at": "2018-06-21T23:01:09Z",
        "updated_at": "2018-06-21T23:01:09Z",
        "all_day_assignment": true,
        "resource_request_id": null,
        "status": null,
        "status_option_id": 1,
        "description": "Build wireframes",
        "note": null,
        "subtasks": {
          "paging": {
              "self": "/api/v1/assignments/12345/subtasks?per_page=20&page=1",
              "next": null,
              "previous": null,
              "page": 1,
              "per_page": 20
          },
          "data": [
            {
              "id": 436,
              "assignment_id": 12345,
              "assignable_id": 123,
              "description": "New Task",
              "completed": false,
              "updated_at": "2018-11-01T20:00:34Z",
              "created_at": "2018-11-01T20:00:34Z",
              "updated_by": 1
            }
          ]
      }
    },
    ...
}

Subtask Counts

Endpoint: /api/v1/projects/<project_id>/assignments?fields=subtasks_counts

This endpoint returns an array of subtasks counts for completed and total subtasks under each assignment record. This endpoint is a view-only endpoint.

Example JSON Response
{
  "data": [
    {
        "id": 12345,
        "allocation_mode": "percent",
        "percent": 1,
        "user_id": null,
        "assignable_id": 123,
        "ends_at": "2018-06-27",
        "starts_at": "2018-06-21",
        "bill_rate": null,
        "bill_rate_id": null,
        "repetition_id": null,
        "created_at": "2018-06-21T23:01:09Z",
        "updated_at": "2018-06-21T23:01:09Z",
        "all_day_assignment": true,
        "resource_request_id": null,
        "status": null,
        "status_option_id": 1,
        "description": "Build wireframes",
        "note": null,
        "subtask_counts": {
            "completed": 5,
            "total": 10
        }
    },
    ...
}

Bill Rates

Bill rates in 10,000ft are maintained at both the account level (defaults) and project level. When a new project is created, the account level bill rates are used as a template for setting up initial bill rates for the project. Adding a user to the project (for example, by making an assignment) causes additional user-specific rates to be created in the project. These user specific bill rates are determined by looking up the existing role and discipline specific rates and matching them up with the user’s role and discipline to find the best match.

A phase is a child project and may have its own bill rate or refer to the parent project. You can add and edit phase-specific bill rates through the user interface of the application. When setting up a phase to have its own bill rate, the parent project bill rates are used as a template, much like the way account default bill rates are used as a template when setting up project bill rates. If a phase is set up to have its own bill rate, adding users to the phase results in user-specific rates being created for the phase, just like it does for projects.

The API allows you to directly manipulate project and phase specific bill rates. Changing account default bill rates are restricted to Administrators.

Endpoints:

Account specific bill rates

GET /api/v1/bill_rates

Project specific bill rates

GET /api/v1/projects/<project_id>/bill_rates

GET /api/v1/projects/<project_id>/bill_rates/<id>

PUT /api/v1/projects/<project_id>/bill_rates/<id>

DELETE /api/v1/projects/<project_id>/bill_rates/<id>

POST /api/v1/projects/<project_id>/bill_rates

Optional Query Parameters

Name Description
rebuild_assignments rebuild all assignments for this project with the new bill rate

Fields:

Name Type Description Optional Readonly
id number bill rate id yes
discipline_id number discipline specific bill rate if set yes
role_id number role specific bill rate if set yes
assignable_id number the project id that the bill rate belongs to
user_id number user id for the bill rate yes
rate float bill rate
starts_at date effective start date for the bill rate yes
ends_at date effective end date for the bill rate yes
startdate date deprecated yes
enddate date deprecated yes
created_at date-time time of creation yes
updated_at date-time time of last update yes

Project-specific bill rates editable via the API require a valid assignable_id attribute value.

Project and user specific bill rate must not specify a role_id or discipline_id, because a specific user has been chosen and role and discipline do not apply for such a bill rate.

See more examples below.

Examples

A bill rate should have the following JSON structure:

/* project default rate */

{
  "id":991618,
  "rate":100.0,
  "discipline_id":null,
  "role_id":30,
  "assignable_id":1234,
  "user_id":null,
  "starts_at":null,
  "ends_at":null,
  "created_at":"2013-09-27T22:10:24Z",
  "updated_at":"2013-09-27T22:10:24Z"
}

/* project rate for discipline id 15 */

{
  "id":991618,
  "rate":100.0,
  "discipline_id":15,
  "role_id":30,
  "assignable_id":1234,
  "user_id":null,
  "starts_at":null,
  "ends_at":null,
  "created_at":"2013-09-27T22:10:24Z",
  "updated_at":"2013-09-27T22:10:24Z"
}

Account-specific bill rates will not have an assignable_id or a user_id, and will look like below. They may optionally have a role_id or discipline_id, to indicate a default rate for that role and/or discipline.

{
  "id":991618,
  "rate":200.0,
  "discipline_id":null,
  "role_id":null,
  "assignable_id":null,
  "user_id":null,
  "starts_at":null,
  "ends_at":null,
  "created_at":"2013-09-27T22:10:24Z",
  "updated_at":"2013-09-27T22:10:24Z"
}

User-specific bill rates on a project will have an assignable_id and a user_id. They may optionally also have a starts_at and ends_at values to indicate that the particular rate is applicable to a specific date range. When date range-specific bill rates are added via the API, they will be preferred over the default rate for the same user. This preference is determined based on the start date of the assignment or time entry in question.

{
  "id":991618,
  "rate":100.0,
  "discipline_id":null,
  "role_id":null,
  "assignable_id":123,
  "user_id":1001,
  "starts_at":"2013-09-27T00:00:00Z",
  "ends_at":null,
  "created_at":"2013-09-27T22:10:24Z",
  "updated_at":"2013-09-27T22:10:24Z"
}

Budget Item Categories

Budget item categories are a set of lookup values for your organization which can be used for specifying project specific budgets. These categories may represent a fee budget, a time budget, or an expense budget. The same categories may be used when reporting time or expenses to classify the budget line item the entry is to be counted against.

There is an account level definition of budget categories, made available via:

/api/v1/time_entry_categories

or

/api/v1/expense_item_categories 

in the format:

{
  "data": [
    {
      "category": "Time Fees Category 1",
      "id": 1083
    },
    {
      "category": "Time Fees Category 2",
      "id": 1084
    }
  ],
  "paging": {
    "next": null,
    "page": 1,
    "per_page": 20,
    "previous": null,
    "self": "/api/v1/time_entry_categories?per_page=20&page=1"
  }
}

Project Specific

There is also a set of budget item categories defined at each project level, available via:

/api/v1/projects/<project_id>/time_entry_categories

or

/api/v1/projects/<project_id>/expense_item_categories

Here you get the actual budget line items defined for the project. The specific categories applicable to the project can be extracted through these.

{
  "id": 1132,
  "assignable_id": null,
  "assignable_parent_id": null,
  "category": 'Printing Material',
  "amount": 123,
  "item_type": "TimeFees",
  "peritem_amount": null,
  "peritem_label": null,
  "created_at": "2013-09-26T20:35:14Z",
  "updated_at": "2013-09-26T20:35:14Z"
}

Note that at the project level, category may also be null. This implies a project budget line item that is not assigned any particular category.

General API Use Examples

Fetching a Collection

GET /api/v1/time_entry_categories

or

GET /api/v1/expense_item_categories

Sample Response

{
      "data": [
        {
          "category": “Design Fees",
          "id": 1083
        },
        {
          "category": “Stationary",
          "id": 1084
        }
      ],
      "paging": {
        "next": null,
        "page": 1,
        "per_page": 20,
        "previous": null,
        "self": “/api/v1/time_entry_categories?per_page=20&page=1"
      }
}

Project Budgets

Endpoint: /api/v1/projects/<project_id>/budget_items?item_type=...

Budget items are always specified with an “item_type” when accessed through the api. This is to keep from mixing amount and hours.

Value for item_type could be one of TimeFees / TimeFeesDays / Expenses

TimeFeesDays are actually in unit hours.

List Budget Items

Required Parameters:

item_type: (one of TimeFees / TimeFeesDays / Expenses)

GET /api/v1/projects/<project_id>/budget_items
 curl "https://api.rm.smartsheet.com/api/v1/projects/12345/budget_items?item_type=TimeFees&auth=..

Show Budget Item by id

curl "https://api.rm.smartsheet.com/api/v1/budget_items/6789?auth=...
 curl "https://api.rm.smartsheet.com/api/v1/projects/12345/budget_items/6789?auth=...

Create a Budget Item

Required Parameters:

item_type: (one of TimeFees / TimeFeesDays / Expenses) amount: value

curl -d "amount=5000&item_type=TimeFees"  \
            "https://api.rm.smartsheet.com/api/v1/projects/4/budget_items?auth=..."

Update Budget Item by id

curl -XPUT -d "amount=567"  \
        "https://api.rm.smartsheet.com/api/v1/budget_items/6789?auth=..."
 or
 curl -XPUT -d "amount=567"   \
        "https://api.rm.smartsheet.com/api/v1/projects/12345/budget_items/6789?auth=..."

Delete a Budget Item

curl -XDELETE "https://api.rm.smartsheet.com/api/v1/budget_items/6789?auth=..."

Sample Response

{
    "data": [
        {
            "amount": 20.0,
            "assignable_id": 4,
            "assignable_parent_id": null,
            "category": "Dragging our Feet",
            "created_at": "2013-09-12T20:09:46Z",
            "id": 4,
            "item_type": "TimeFeesDays",
            "peritem_amount": null,
            "peritem_label": null,
            "updated_at": "2013-09-12T20:09:46Z"
        }
    ],
    "paging": {
        "next": null,
        "page": 1,
        "per_page": 20,
        "previous": null,
        "self": "/api/v1/projects/4/budget_items?item_type=TimeFeesDays&project_id=4&per_page=20&page=1"
    }
}

Custom Fields and Custom Field Values

Custom Fields

Endpoint /api/v1/custom_fields

Fields:

Name Type Description Optional Readonly
id number custom field id n/a readonly
namespace string either assignables or users required readonly
data_type string can be string, selection_list, or multiple_choice_selection_list required readonly
name string name of the custom field required editable
description string description of the custom field optional editable
default_value string the value to be applied if none is specified optional editable
is_visible_on_info_page boolean boolean value, defaults to true optional editable
is_visible_as_filter boolean boolean value, defaults to false optional editable
options array array of possible values (only applies to selection_list and multiple_choice_selection_list) required (only for selection lists) editable

Creating Custom Fields

POST /api/v1/custom_fields
Required parameters:
Parameter Type Description
namespace string either assignables or users
name string the name of the field
data_type string can be string, selection_list, or multiple_choice_selection_list
options array array of possible values (only applies to selection_list and multiple_choice_selection_list)
Optional parameters:
Parameter Type Description
description string a short description of the field
default_value string the value to be applied if none is specified
is_visible_on_info_page boolean boolean value, defaults to true
is_visible_as_filter boolean boolean value, defaults to false
apply_default_to_existing_objects boolean non-persisting boolean value that, if true, triggers a one time application of the default value to all existing projects or users

Example: POST /api/v1/custom_fields { "name": "Skills", "namespace": "users", "is_visible_on_info_page": true, "is_visible_as_filter": true, "data_type": "multiple_choice_selection_list", "options": [ "Audio/Video", "Graphic Design", "UX", "Analytics", "Python", "Ruby", "JavaScript" ] }

Updating Custom Fields

PUT /api/v1/custom_fields/<custom_field_id>
Editable parameters:
Parameter Type Description
name string the name of the field
description string a short description of the field
options array array of possible values (only applies to selection_list and multiple_choice_selection_list)
default_value string the value to be applied if none is specified
is_visible_on_info_page boolean boolean value, defaults to true
is_visible_as_filter boolean boolean value, defaults to false

:warning: When removing a value from options that is also the default_value, the default_value needs to be updated as well.

Getting Custom Fields

GET /api/v1/custom_fields
GET /api/v1/custom_fields/<custom_field_id>

Deleting Custom Fields

DELETE /api/v1/custom_fields/<custom_field_id>

Deleting a custom field will also delete all of its associated custom field values.

Custom Field Values

Endpoints
/api/v1/projects/<project_id>/custom_field_values
/api/v1/users/<user_id>/custom_field_values

Fields:

Name Type Description Optional Readonly
id number custom field value id n/a readonly
custom_field_id number id of the associated custom field required readonly
user_id or project_id number id of the associated user or assignable required readonly
value string or array the actual value required editable

Creating Custom Field Values

POST /api/v1/projects/<project_id>/custom_field_values
POST /api/v1/users/<user_id>/custom_field_values
Required parameters:
Parameter Type Description
custom_field_id number id of the associated custom field
user_id or project_id number id of the associated user or assignable (can be inferred from URL)
value string or array the actual value

Note: Only custom fields with a data_type of multiple_choice_selection_list can accept an array with multiple values as its value in a POST request. Note that this array is treated as the complete set of values for the given custom field and project/user. Subsequent POST requests for the same custom field and project/user will result in the deletion of previous values if those values are not also included in the value array. In other words, subsequent POST requests do not append new values, but rather replace the set of values as a whole.

Updating Custom Field Values

PUT /api/v1/projects/<project_id>/custom_field_values/<id>
PUT /api/v1/users/<user_id>/custom_field_values/<id>
Editable parameters:
Parameter Type Description
value string the actual value

Getting Custom Field Values

GET /api/v1/projects/<project_id>/custom_field_values
GET /api/v1/users/<user_id>/custom_field_values

In addition to getting custom field values directly, you can also include custom field values as a nested collection when getting users or projects by specifying custom_field_values in the fields parameter. GET /api/v1/projects/<project_id>?fields=custom_field_values GET /api/v1/users/<user_id>?fields=custom_field_values

Deleting Custom Field Values

Custom field values cannot be deleted directly. To delete all custom field values that belong to a specific custom field, you can delete that custom field itself, and all associated values will be deleted as well.

Disciplines

Disciplines currently must be created and assigned through the UI.

Endpoints:

Get Disciplines

  • GET /api/v1/disciplines will return a paginated list of Disciplines.

Optional parameters:

Example JSON Response
{
  "paging": {
    "per_page": 20,
    "page": 1,
    "previous": null,
    "self": "/api/v1/disciplines?&page=1",
    "next": null
  },
  "data": [
    {
      "id": 1,
      "value": "JavaScript Developer"
    },
    {
      "id": 2,
      "value": "Ruby Developer"
    }
  ]
}


Get a Discipline

  • GET /api/v1/disciplines/1 will return the role with the ID of 1.
Example JSON Response
{
  "id": 1,
  "value": "Developer"
}

Expense Items

Endpoint: /api/v1/users/<user_id>/expense_items

Expense items are reported by a user on a project or leave type.

List Expense Items for a User

Optional parameters:
Parameter Description
from get expenses reported on or after this date
to get expenses reported on or before this date
per_page, page Parameters for pagination. Default values are per_page = 20 , page = 1 ( the first )

Expenses by User

GET /api/v1/users/<user_id>/expense_items
GET /api/v1/users/<user_id>/expense_items/<id>

Expenses by Project

GET /api/v1/projects/<project_id>/expense_items
GET /api/v1/projects/<project_id>/expense_items/<id>

Create Expense Item

When creating expense items, at least date and amount need to be specified. Project/Leave Type can be specified by one of project_id, leave_type_id, or an assignable_id. These three parameters refer to the same and are interchangeable. You should only specify one project/leave type parameter per expense item call.

| date | amount | leave_type_id | project_id | assignable_id |

POST /api/v1/users/<user_id>/expense_items

Update an Expense Item

PUT /api/v1/projects/<project_id>/users/<user_id>/expense_items/<expense_item_id>

Delete an Expense Item

DELETE /api/v1/users/<user_id>/expense_items/<expense_items_id>

Sample Response

{
  "data": [
    {
      "id": 1,
      "assignable_id": 32,
      "assignable_type": "Project",
      "user_id": 2,
      "amount": 10,
      "date": "2015-04-09",
      "category": null,
      "notes": "Testing exp",
      "created_at": "2015-04-09T21:54:13Z",
      "updated_at": "2015-04-09T21:54:13Z"
    }
  ]
  {
    "paging": {
    "per_page": 1000,
    "page": 1,
    "previous": null,
    "self": "/api/v1/users/2/expense_items?per_page=1000&user_id=2&page=1",
    "next": null
  }
}

Holidays

Holidays are dates that your organization treats as non-working days, and entered into 10,000ft by an account administrator. The API provides an endpoint for reading this information.

Endpoints:

GET /api/v1/holidays

Optional Query Parameters

Parameter Description
per_page, page Parameters for pagination. Default values are per_page = 20 , page = 1 ( the first )

Fields:

Name Type Description Optional Readonly
id number holiday id yes
date date the date of the holiday yes
name string the name of the holiday yes
created_at date-time time of creation yes
updated_at date-time time of last update yes

Examples

A holiday has the following JSON structure:

{
  "id": 20019,
  "date": "2015-01-01",
  "name": "New Years Day",
  "created_at": "2015-10-23T04:16:36Z",
  "updated_at": "2016-08-24T23:44:16Z"
}

Leave Types

Endpoint: /api/v1/leave_types

LeaveType is a subclass of Assignable. You will see the id refering to a project as assignable_id in other models. LeaveType is an assignable that you can assign time to, not being part of a project, such as Vacation.

List Leave Types (index)

GET  /api/v1/leave_types

 curl 'https://api.rm.smartsheet.com/api/v1/leave_types?auth=...'

Show a LeaveType

GET  /api/v1/leave_types/<leave_type_id>

 curl 'https://api.rm.smartsheet.com/api/v1/leave_types/12345?auth=...'

Sample Response

{
    "data": [
        {
            "id": 2,
            "name": "Sick",
            "description": null,
            "guid": "FAFC777B-8CD2-4434-9C0E-59366A1A65B9",
            "deleted_at": null,
            "created_at": "2013-09-10T21:31:06Z",
            "updated_at": "2013-09-10T21:31:06Z"
        }
    ],
    "paging": {
        "next": null,
        "page": 1,
        "per_page": 20,
        "previous": null,
        "self": "/api/v1/leave_types?per_page=20&page=1"
    }
}

Phases

Endpoint: /api/v1/projects/<project_id>/phases

Phase is a subclass of Project which is a subclass of Assignable. You will see the id refering to a project as assignable_id in other models. A Phase always has a parent_id set to the id of the parent Project.

List Phases for a Project

GET /api/v1/projects/<project_id>/phases
 curl 'https://api.rm.smartsheet.com/api/v1/projects/[project_id]/phases?auth=...'

Create a Phase for a Project

curl  -d "phase_name=Winding%20up&starts_at=2013-09-15&ends_at=2013-09-16"  \
                         "https://api.rm.smartsheet.com/api/v1/projects/[project_id]/phases?auth=..."

Update a Phase for a Project

curl  -XPUT -d "phase_name=Another%20Name&"  \
                         "https://api.rm.smartsheet.com/api/v1/projects/[project_id]/phases/456?auth=..."

Bill Rates

If you wish for the phase to inherit the parent project’s bill rates after create, the use_parent_bill_rates flag can be passed with a PUT request as follows:

curl  -XPUT -d "use_parent_bill_rates=true"  \
                         "https://api.rm.smartsheet.com/api/v1/projects/[project_id]/phases/456?auth=..."

Delete a Phase for a Project

curl  -i -X DELETE "https://api.rm.smartsheet.com/api/v1/projects/[project_id]/phases/[phase_id]?auth=..."

NOTE: A phase cannot be deleted unless it contains no assignments.

Placeholder Resources

Endpoint: /api/v1/placeholder_resources

Placeholder resources can be used for temporary resourcing on projects where the final resources are not yet known. Placeholders behave quite similarly to users, with a few differences discussed below.

List Placeholder Resources (index)

Optional Parameters:
Parameter Description
fields A comma separated list of additional fields to include in the response [ “assignments”, “custom_field_values”]
per_page, page Parameters for pagination. Default values are per_page = 20 , page = 1 ( the first )
GET  /api/v1/placeholder_resources
 curl 'https://api.rm.smartsheet.com/api/v1/placeholder_resources?fields=assignments,custom_field_values&auth=...'

Note that custom field values can only be accessed if custom fields are enabled for the account. This is only possible for pro plans and up. See custom fields for details.

Show Placeholder

Optional Parameters:
Parameter Description
fields A comma separated list of additional fields to include in the response [ “assignments”, “custom_field_values”]
per_page, page Parameters for pagination. Default values are per_page = 20 , page = 1 ( the first )
GET  /api/v1/placeholder_resources/<placeholder_resource_id>
 curl 'https://api.rm.smartsheet.com/api/v1/placeholder_resources/12345?fields=assignments&auth=...'

Create a Placeholder Resource

Required Parameters
  • title
POST  /api/v1/placeholder_resources
 curl -d 'title=Designer' \
             'https://api.rm.smartsheet.com/api/v1/placeholder_resources?auth=...'

Placeholders are referred to by title. The title is displayed wherever placeholders appear in the application e.g., on projects, the schedule, etc. Therefore, it is required to specify this parameter.

Optional Parameters:
Parameter Description
role The placeholder’s role in the organization.
discipline The placeholder’s discipline.
location The organizational location the placeholder belongs to.
Parameters not exposed through the API

In the application’s user interface, there are certain options available when creating and editing placeholder resources. For example, if a role and discipline are selected, the placeholder title is auto-populated as a combination of discipline and role. For example, a placeholder with discipline ‘Engineering’ and role 'Director’ would be auto-assigned the title 'Engineering, Director’. Options also exist to upload a thumbnail image for the placeholder, or to choose a color and abbreviation and then auto-generate a thumbnail. These options are currently not available through the API, and can only be used via the user interface.

Update a Placeholder

Placeholder specified by id

PUT  /api/v1/placeholder_resources/<placeholder_resource_id>
 curl -XPUT -d 'title=Senior Designer' \
             'https://api.rm.smartsheet.com/api/v1/placeholder_resources/12345?auth=...'

Delete a Placeholder

Placeholder resources may be deleted via the API, as follows.

DELETE  /api/v1/placeholder_resources/<placeholder_resource_id>
 curl -XDELETE \
             'https://api.rm.smartsheet.com/api/v1/placeholder_resources/12345?auth=...'

Placeholders and Users/People

As noted above, placeholders behave similarly to real users in certain cases. However, there are some key differences. Here we discuss ways in which placeholders can be used similar to users in the API, and ways they are different.

Placeholder Assignments

Assignments can be made, updated, and removed via the Assignments API just as they can for users. The only difference is that this is accessed through the placeholder_resources endpoint. In general, for the Assignments API, a placeholder resource ID can be used as the user_id parameter.

GET  /api/v1/placeholder_resources/<placeholder_resource_id>/assignments
 curl 'https://api.rm.smartsheet.com/api/v1/placeholder_resources/12345/assignments?&auth=...'
Placeholder Bill Rates

If a placeholder is given a role/discipline, they will inherit account default bill rates for that role/discipline. Specific bill rates can also be created for placeholders using the bill rates API. A placeholder ID can be specified as the user_id parameter. No additional parameters are required.

Placeholder Custom Fields

Custom fields can be created for placeholders through the application UI. API docs coming soon.

Placeholder Time Entries

Time tracking for placeholders is not supported - i.e. it is not possible to create or edit time entries for a placeholder. However, system-generated suggested entries are supported for placeholders. When a placeholder is assigned to a project, the system will generate scheduled hours based on the type of assignment and update budget projections, so that placeholders can be used for forecasting/projection. However, placeholders do not incur time, and no explicit time entry changes can be made for them. System-generated time entries for placeholders can be viewed via the time entries API, by passing in the placeholder ID as the user_id parameter, similar to assignments.

Not Supported: Expense Items and Tags

Expense items are not available for placeholders.

Tags for placeholders are also not supported. Custom fields should be used instead.

Placeholders on a Project

Similar to users on a project, you can get the placeholder resources assigned to a project using the following API endpoint:

/api/v1/projects/<project_id>/placeholder_resources

Tags per Project

Endpoint: /api/v1/projects/<project_id>/tags

There are two ways to list project tags:

  • Get a list of tags for a single project using the /api/v1/projects/<project_id>/tags endpoint.
  • Adding the parameter fields=tags when listing/viewing through /api/v1/projects

Create and attach tags to projects

Attaching a tag to a project is technically a “find-or-create” operation. If you post a tag with information that does not exist for your organization it will be created and attached to the project specified. If the tag already exists, it will just be attached. If you try to create the same tag multiple times, it will just be attached once.

curl -d "value=Awesome"  "https://api.rm.smartsheet.com/api/v1/projects/1/tags?auth=..."

Disconnect a tag from a project

You can remove a tag from a project without deleting it from your account settings by using the /api/v1/projects endpoint.

curl -XDELETE  "https://api.rm.smartsheet.com/api/v1/projects/1/tags/456?auth=..."

Response for Tags Listing

{
    "data": [
        {
            "id": 31,
            "value": "MyFirstTag"
        }
    ],
    "paging": {
        "next": null,
        "page": 1,
        "per_page": 20,
        "previous": null,
        "self": "/api/v1/projects/1/tags?project_id=1&per_page=20&page=1"
    }
}

Users per Project

Endpoint: /api/v1/projects/<project_id>/users

List Users for a given Project

Users are associated to a project by Assignments.

Optional Parameters:
Parameter Description
per_page, page Parameters for pagination. Default values are per_page = 20 , page = 1 ( the first )
fields A comma separated list of additional fields to include in the response, optional values [ “tags”, “assignments”, “availabilities”, “custom_field_values” ]
sort_field Field to sort the return document. Possible values: created, updated, first_name, last_name, hire_date, termination_date
sort_order Order to sort the results on. Possible values: ascending or descending
with_phases If set to true, includes users who are assigned to phases ( child projects )
with_archived If set to true, includes archived users
include_placeholders If set to true, includes placeholder users

List Users

GET  /api/v1/projects/<project_id>/users

 curl 'https://api.rm.smartsheet.com/api/v1/projects/project_id/users?fields=tags,assignments&auth=...'

Projects

Endpoint: /api/v1/projects

Project is a subclass of Assignable. You will see the id referring to a project as assignable_id in other models. Sub-projects are called phases and share the same data model. A Phase has a parent_id that is not null. A project or phase can be deleted by setting the optional archived parameter to true, it can also be unarchived by setting archived to false.

Projects where archived is set to true cannot be updated. You must first unarchive (set archived to false) before updating the project.

Project State

project_state describes the state of the project:

  • Confirmed
  • Tentative
  • Internal

List Projects (index)

Optional Parameters:
Parameter Description
from get projects that end on or after this date
to get projects that start on or before this date
strict set to true to restrict the projects to only those contained entirely within the from and to params
fields a comma separated list, optional values [ “children”, “tags”, “budget_items”, “project_state” , “phase_count”, “summary”, “custom_field_values” ] Will add additional fields to the output
filter_field Specifies the property to filter on. “project_state” is the only supported value
filter_list The value of “filter_field” to match, outputs will be projects with state matching this value. Possible values: Internal, Tentative, Confirmed
sort_field Field to sort the return document. Possible values: created or updated
sort_order order to sort the results on. Possible values: ascending or descending
project_code project code to find, exact match
phase_name phase name to find, exact match
with_archived true to include deleted/archived projects
with_phases true to include phases ( child projects )
per_page, page Parameters for pagination. Default values are per_page = 20 , page = 1 ( the first )
archived true to archive/false to unarchive

List projects

GET  /api/v1/projects?fields=tags,budget_items

List projects with archived

GET  /api/v1/projects?fields=tags,budget_items&with_archived=true

Notes: Set with_archived to true to include archived projects in searches. Set archived to true to archive a project. Set archived to false to unarchive a project.

List projects with sorting

GET  /api/v1/projects?sort_field=created&sort_order=ascending

Filter projects

GET  /api/v1/projects?filter_field=project_state&filter_list=Confirmed

Notes: project_state is the only supported filter field at present.

Show a project

GET  /api/v1/projects/<project_id>

Show a project with its phases

GET  /api/v1/projects/<project_id>?fields=children

Create a project

Note: You cannot add thumbnails to the project through the API

POST  /api/v1/projects

{
"name": "My Project",
"starts_at": "2015-03-01",
"ends_at": "2015-06-01"
}

Update a Project

Note: You cannot add thumbnails to the project through the API

PUT  /api/v1/projects/1245

{
  "id": 1245,
  "name": "New Project Name",
  "ends_at": "2015-05-31"
}

Locking Time Entries

timeentry_lockout is used to control when new time entries are no longer accepted to a project.

Value Description
-1 Not locked
0 Locked
7 Locked for entries more than 7 calendar days ago. This can be any positive integer value

Note that positive integer values in this attribute are numbers of days relative to today’s date on the calendar. We do not support setting this lockout value to a specific date.

If your project has phases, note that this must also be set for each phase assignable_id for it to take effect as intended.

Delete a Project

DELETE  /api/v1/projects/1245

Notes:

Dates need to be in UTC

Sample Response

GET  https://api.rm.smartsheet.com/api/v1/projects/<project_id>?fields=tags,summary,children,has_pending_updates&today=27-07-2016&per_page=100000&auth=<token>
{
  "id":821065,
  "archived":false,
  "archived_at":null,
  "description":"",
  "guid": "xxxx-xxxx-xxxx-xxxx-xxxx-xxxx",
  "name":"10K Example for Wayne",
  "parent_id":null,
  "phase_name":null,
  "project_code":"",
  "secureurl":"https://10kftprojectimages.s3.amazonaws.com/a62ffd30-316f-4cb6-9c7f-eca45d07a35d/499af1a7-bc6b-446f-8535-4472e6159246.png",
  "secureurl_expiration":"3000-01-01T00:00:00Z",
  "settings":0,
  "timeentry_lockout":-1,
  "ends_at":"2015-12-31",
  "starts_at":"2015-01-01",
  "deleted_at":null,
  "created_at":"2015-11-06T18:00:40Z",
  "updated_at":"2016-04-19T18:21:16Z",
  "use_parent_bill_rates":false,
  "thumbnail":"https://10kftprojectimages.s3.amazonaws.com/a62ffd30-316f-4cb6-9c7f-eca45d07a35d/499af1a7-bc6b-446f-8535-4472e6159246.png",
  "type":"Project",
  "has_pending_updates":false,
  "client":null,
  "project_state":"Internal",
  "tags":{
    "paging":{
      "self":"/api/v1/projects/821065/tags?per_page=1&page=1",
      "next":null,
      "previous":null,
      "page":1,
      "per_page":1
    },
    "data":[
      {
        "id":1207009,
        "value":"Sales"
      }
    ]
  },
  "children":{
    "paging":{
      "self":"/api/v1/projects/821065/tags?per_page=100000&page=1",
      "next":null,
      "previous":null,
      "page":1,
      "per_page":100000
    },
    "data":[

    ]
  },
  "bounding_startdate":"2015-01-01",
  "bounding_enddate":"2016-07-01",
  "confirmed_hours":1283.600000000003,
  "confirmed_dollars":160450.0,
  "approved_hours":0,
  "approved_dollars":0,
  "unconfirmed_hours":87.60000000000002,
  "unconfirmed_dollars":10950.0,
  "scheduled_hours":1322.400000000003,
  "scheduled_dollars":165300.0,
  "future_hours":0,
  "future_dollars":0
}

Reports API

The reports endpoints allow you to generate report rows or totals by specifying the parameters of a report in the JSON payload of a POST request. The response is a JSON representation of the report rows or totals as seen in the reports UI.

Endpoints

  • /api/v1/reports/rows
  • /api/v1/reports/totals

Parameters

With the exception of today and calc_incurred_using, each of the following parameters has a corresponding menu in the reports UI.

param data type description default
view string the name of the view (e.g. time_fees_hours, utilization, etc.) "time_fees_hours"
time_frame object or string a custom time frame object or the name of the time frame "this_week"
group_by array of strings the attributes to group rows by ["project_id"] (or ["user_id"] for utilization)
filters object of objects the attributes and values to include or exclude null
today string the date on which “future scheduled” begins, in YYYY-MM-DD format current UTC date
calc_incurred_using string one of confirmed-unconfirmed, confirmed, or approved "confirmed-unconfirmed"

Example Request Params:

// POST /api/v1/reports/rows
{
  "view": "time_fees_hours",
  "time_frame": "this_week",
  "group_by": ["project_id", "user_id"],
  "filters": {
    "client": {
      "operation": "inclusion",
      "values": ["Mango Inc."]
    },
    "people_tags": {
      "operation": "exclusion",
      "values": ["intern"]
    }
  },
  "today": "2018-03-28",
  "calc_incurred_using": "confirmed-unconfirmed"
}

Example Response:

{
  "params": {
    "view": "time_fees_hours",
    // ... Other request params
  },
  "dates": {
    "today": "2018-03-28",
    "range": {
      "from": "2018-03-26",
      "to": "2018-04-01"
    }
  },
  "rows": [
    {
      "project_id": 1771900,
      "project_name": "Design Planning & Management",
      "user_id": 200088,
      "user_name": "Bobby Taleb",
      "incurred_hours": 6,
      "scheduled_hours": 10,
      "difference_from_past_scheduled_hours": 0,
      "future_scheduled_hours": 4,
      "total_hours": 10
    },
    // ... More rows
  ]
}

view

There are currently ten supported views, which correspond to the reports available in the reports UI. The view determines which columns are returned.

Time and Fees

  • time_fees_hours
  • time_fees_days
  • time_fees_amounts
  • time_fees_hours_and_amounts
  • time_fees_days_and_amounts

Budgets

  • budgets_hours
  • budgets_days
  • budgets_amounts

Utilization, Expenses

  • utilization
  • expenses

time_frame

The time frame of a report is specified as an object with “from” and “to” attributes that each specify a date in the format YYYY-MM-DD.

"time_frame": {
  "from": "2018-01-01",
  "to": "2018-12-31"
}

There are also several shortcut strings for common time frames.

  • this_week
  • this_month
  • this_quarter
  • this_year
  • last_week
  • last_month
  • last_quarter
  • last_year
  • next_30
  • next_60
  • next_90
  • last_30
  • last_60
  • last_90
  • last_and_next_90

group_by

The group_by param is an array of strings that specify which attributes to group and sort rows by. Note that, while the reports UI restricts grouping to 2 levels, the API currently allows up to 5 levels.

"group_by": ["client", "phase_name", "user_id", "date"]

The following are all the valid attributes that rows can be grouped by. Note that utilization reports have an additional restriction such that rows can only be grouped by user attributes or date attributes.

User Attributes

  • user_id
  • role
  • discipline
  • location
  • assignment_status

Date Attributes

  • date
  • week
  • month

Assignable Attributes

  • project_id
  • client
  • leave_type
  • project_type
  • project_state
  • phase_name

Time Entry or Expense Attributes

  • record_type
  • entry_type
  • category
  • approval_status
  • approved_by

filters

Attributes that can be used as grouping values can also be used as filters. Additionally, the following attributes can be used as filters as well.

  • people_tags
  • project_tags
  • custom_fields

The filters parameter is expected to be an object where the keys are the attribute names, and the values are objects that specify what to filter on. The filter objects are expected to specify an operation and an array of values. operation can be either inclusion or exclusion. The values array may contain either integers or strings, depending on the attribute.

"filters": {
  "project_id": {
    "operation": "inclusion",
    "values": [432, 561, 642]
  },
  "people_tags": {
    "operation": "exclusion",
    "values": ["intern"]
  }
}

Filtering on custom_fields is slightly different in that, instead of a single object with an operation and values, the expectation is an array of objects, each with an operation, values, and id, which is the custom field id.

"filters": {
  "custom_fields": [
    {
      "id": 4321,
      "operation": "inclusion",
      "values": ["E", "S", "R"]
    },
    {
      "id": 5678,
      "operation": "exclusion",
      "values": ["tentative"]
    }
  ]
}

today

The today param is the date on which past/incurred time ends and future scheduled time begins. The expected format is “YYYY-MM-DD”.

calc_incurred_using

There are 3 options for calculating incurred time:

  • confirmed-unconfirmed (default, always used in reports UI)
  • confirmed
  • approved

The reports UI always uses confirmed-unconfirmed. If your account settings specify that incurred time should use confirmed time only, the reports UI will still use the confirmed-unconfirmed option, but will additionally apply a default filter on entry_type, removing unconfirmed time, which has the same effect with regards to incurred calculations.

"calc_incurred_using": "confirmed-unconfirmed",
"filters": {
  "entry_type": {
    "operation": "exclusion",
    "values": ["Unconfirmed"]
  }
}

The only difference between the two methods (filtering out unconfirmed time vs specifying calc_incurred_using as confirmed) is in how past scheduled time is calculated in the case where no corresponding confirmed time exists for a given day of an assignment. Filtering out unconfirmed time affects both incurred and past scheduled time, whereas specifying calc_incurred_using as confirmed does not affect past scheduled time. One way to think about it is, when calc_incurred_using is set to confirmed, the report is calculated as if the “clear suggestions” button was pushed on everyone’s timesheets.

Roles

Roles currently must be created and assigned through the UI.

Endpoints:

Get Roles

Optional parameters:

Example JSON Response
{
  "paging": {
    "per_page": 20,
    "page": 1,
    "previous": null,
    "self": "/api/v1/roles?&page=1",
    "next": null
  },
  "data": [
    {
      "id": 1,
      "value": "Senior"
    },
    {
      "id": 2,
      "value": "Junior"
    }
  ]
}

Get a Role

  • GET /api/v1/roles/1 will return the role with the ID of 1.
Example JSON Response
{
  "id": 1,
  "value": "Senior"
}

Status Options

Endpoint: /api/v1/status_options

Status options are required in order to set the status_option_id on assignments. This corresponds to the work status in the work list. Status options are account level resources and do not belong to any assignable, user, or assignment.

Create a status option

POST /api/v1/status_options
Required params
param description
color one of the valid colors listed below
label string
stage one of the valid stages listed below
order a float number used for sorting options within UI menus
Valid colors
  • blue_bright
  • blue_dark
  • green_bright
  • green_dark
  • yellow
  • orange
  • red
  • purple
Valid stages
  • planned
  • in_progress
  • done
Example
POST {
  "color": "green_bright",
  "label": "On Track",
  "stage": "in_progress",
  "order": 100.0
}

List status options

GET /api/v1/status_options

Get list with deleted options. GET /api/v1/status_options?with_deleted=true

Show a single status option

GET /api/v1/status_options/<status_option_id>

Update a status option

PUT /api/v1/status_options/<status_option_id>

Delete a status option

DELETE /api/v1/status_options/<status_option_id>

In order to maintain consistency with historical data, deleting a status option only flags the resource as deleted. It does not permanently destroy the record.

Subtasks

Endpoint: /api/v1/projects/<project_id>/assignments/<assignment_id>/subtasks

Subtasks belong to assignments. They correspond to the checklist of items called a tasklist listed under work items/assignments in the worklist. Tasks are an optional addition to any work item/assignment.

Create a subtask

POST /api/v1/projects/<project_id>/assignments/<assignment_id>/subtasks
Required params
param description
description string used to describe the subtask
Optional params
param description
completed boolean value that corresponds with checkbox, default false
Example
POST {
  "description": "Create wireframe",
  "completed": true,
}

List subtasks

GET /api/v1/projects/:project_id/assignments/:assignment_id/subtasks

Show a single subtask

GET /api/v1/projects/:project_id/assignments/:assignment_id/subtasks/<subtask_id>

Update a subtask

PUT /api/v1/projects/:project_id/assignments/:assignment_id/subtasks/<subtask_id>

Delete a subtask

DELETE /api/v1/projects/:project_id/assignments/:assignment_id/subtasks/<subtask_id>

Deleting a subtask will permantently destroy the record. For updates to subtasks we record the user_id of the last update and the time of the last update.

Time Entries

Time Entries are a collection of hours tracked per project and user. There are two types of time entries: suggested and confirmed

Suggested (Unconfirmed) time entries

Suggested time entries (also know as unconfirmed time entries) are created by 10,000ft as a result of resources being assigned to a project. These are identifiable by the is_suggestion: true attribute on the time entry objects. Suggested time entries are not returned by the API by default and must be requested using the with_suggestions=true parameter on the GET API call to fetch time entries.

Suggested time entries are read-only and are kept up to date by 10Kft as the corresponding assignments are updated.

Confirmed time entries

Confirmed time entries are what a user (or the API) has explicitly created to indicate that they have spent some time working on a project.

Note that just like in the application UI, you cannot create new confirmed time entries for managed resources via the API. You can read suggested time entries for all users via the API.

Fields

Name Type Description Required Readonly Default value
id number Time entry id yes NEXT(ID)
user_id number User id (licensed user only) yes
assignable_id number Project, Phase or Leave type id yes
assignable_type string Project or LeaveType yes
date date The date yes
hours number Number of hours confirmed yes
is_suggestion boolean Is this a suggested time entry yes
scheduled_hours number Number of hours scheduled (suggested time only) yes
task string A task category
notes string A note
bill_rate number The hourly rate for the time entered yes
bill_rate_id number The rate id reference Detect rate
created_at date-time time of creation yes NOW()
updated_at date-time time of last update yes NOW()

Endpoints:

# Time entries by user
GET /api/v1/users/<user_id>/time_entries
GET /api/v1/users/<user_id>/time_entries/<id>

# Time entries for given date-range
GET /api/v1/users/<user_id>/time_entries?from=2017-03-14&to=2017-03-21

# Time entries by project
GET /api/v1/projects/<project_id>/time_entries
GET /api/v1/projects/<project_id>/time_entries/<id>

# All time entries in the account
GET /api/v1/time_entries
GET /api/v1/time_entries/<id>

# Time entries for given date-range
GET /api/v1/time_entries?from=2017-03-14&to=2017-03-21

# Updating a time entry
PUT /api/v1/users/<user_id>/time_entries/id

# Deleting a time entry
DELETE /api/v1/users/<user_id>/time_entries/id

Optional Query Parameters:

Name Description format
from get projects that start on or after this date &from=2017-03-14
to get projects that end on or before this date &to=2017-03-21
sort_field Field to sort the return document. Possible values: created or updated
sort_order order to sort the results on. Possible values: ascending or descending
with_suggestions true to include suggested (unconfirmed) time entries based on assignments on the schedule &with_suggestions=true

IMPORTANT: to and from must be a valid date formatted as yyyy-mm-dd

Bill Rates

Time entries have an associated bill rate attached to them. When a new time entry is created, 10Kft will determine the appropriate bill rate for it (based on your account and project settings) and assign a values. When reading time entries, you can see this assigned bill rate.

Creating Time Entries

When creating time entries, a valid user_id, assignable_id, date and hours must be supplied. Assignable id can be assignable_id, project_id or leave_type_id.

You can optionally specify values for task and notes, which must be fewer than 256 characters in length. If you know a valid bill_rate_id matching the user and project of the time entry, you can specify that at the time of creating a time entry as well.

POST /api/v1/users/<user_id>/time_entries

{
  "user_id": <user_id>,
  "assignable_id": 1001,
  "date": "2012-01-21",
  "hours": 0.5,
  "task": 'Travel',
  "notes": 'Drive to Seattle, WA to meet with 10Kft'
}

Note that the user_id in the URL must match the user_id in the POST data in the above example. In this example, the user_id in post data is optional. Similar rules apply when you manipulate time entries within a project time entries collection, like below

POST /api/v1/projects/<project_id>/time_entries

{
  "user_id": 123,
  "assignable_id": <project_id>,
  "date": "2012-01-01",
  "hours": 4.0,
}

Examples

A confirmed time entry (note is_suggestion is false).

{
  "id":100001,
  "user_id": 123,
  "assignable_id": 1001,
  "assignable_type": "Project",
  "date": "2013-09-11",
  "hours": 8.0,
  "is_suggestion": false,
  "scheduled_hours": null,
  "task": null,
  "bill_rate": 150,
  "bill_rate_id": 4,
  "created_at": "2013-09-12T04:32:28Z",
  "updated_at": "2013-09-18T04:32:28Z"
}

A suggested time entry (note is_suggestion is true) and hours are given in scheduled_hours instead of hours. Task and notes are null in suggested time entries as well.

{
  "id":100000,
  "user_id": 123,
  "assignable_id": 1001,
  "assignable_type": "Project",
  "date": "2013-09-11",
  "hours": null,
  "is_suggestion": true,
  "scheduled_hours": 8.0,
  "task": null,
  "notes": null,
  "bill_rate": 150,
  "bill_rate_id": 4,
  "created_at": "2013-09-12T04:32:28Z",
  "updated_at": "2013-09-18T04:32:28Z"
}

Availabilities

In 10,000ft we have the concept of a work week. It defines the days of the week that are to be considered work days and the number of work hours for those days. Given this work week, you can determine the number of work hours per day, in any given date range. The work week is configurable by an account administrator, via the account settings pages.

User availabilities are a mechanism by which you can further customize the work days for individuals in your team. When an individual has a work schedule that deviates from the normal work week observed by your team, say, because they are working part time during some time period, an administrator can specify that by adding one or more availability time blocks to that user’s profile.

When a user has one or more availability time blocks specified, 10,000ft will always take those into consideration in addition to the normal work week information of the company.

NB: In the current version of the API, updating part time availabilities will NOT automatically update existing assignments and their suggested time entries to match.

Days 0

Day0 represents Sunday of the week, day1 Monday and so on. This is irrespective of the values of start and end dates for a given availability block.

Start and End

Availability block start and end dates specify a date range during which the given custom available hours apply. Both starts_at and ends_at values are optional. If starts_at is nil, it implies that the given availabilities are to be used infinitely into the past. Similarly a null ends_at implies that the values are to be used infinitely into the future.

Overlapping date ranges in multiple availability blocks for the same user are accepted but will produce unpredictable results.

Endpoints:

GET /api/v1/users/<user_id>/availabilities

GET /api/v1/users/<user_id>/availabilities/<id>

PUT /api/v1/users/<user_id>/availabilities/<id>

DELETE /api/v1/users/<user_id>/availabilities/<id>

POST /api/v1/users/<user_id>/availabilities

Fields:

Name Type Description Optional Readonly
id number availability block id yes
user_id number The user id yes
starts_at date effective start date for the availability block yes
ends_at date effective end date for the availability block yes
day0 number available hours on day0 of the week
day1 number available hours on day1 of the week
day2 number available hours on day2 of the week
day3 number available hours on day3 of the week
day4 number available hours on day4 of the week
day5 number available hours on day5 of the week
day6 number available hours on day6 of the week
created_at date-time time of creation yes
updated_at date-time time of last update yes

See more examples below.

Examples

An availability block should have the following JSON structure:


{
  "id": 52,
  "user_id": 269,
  "starts_at": "2017-01-30",
  "ends_at": "2017-07-28",
  "day0": 0,
  "day1": 8,
  "day2": 8,
  "day3": 4,
  "day4": 8,
  "day5": 8,
  "day6": 0,
}

User Status

Endpoint: /api/v1/users/<user_id>/statuses

Current status for a user is a collection of Statuses.

Valid statuses are:

  • ITO (In the Office)
  • WFH (Working from home)
  • SIC (Sick)
  • OOO ( On the Road)
  • VAC (Vacation)
  • OOF (Out of office)

A new “current status” is set by simply creating a new status for the user.

Show List of Statuses For a User

GET  /api/v1/users/statuses
  curl "https://api.rm.smartsheet.com/api/v1/users/7/statuses?auth=..."

Create/update status for a user

Required Parameter:

| status |

Optional parameters:

| assignable_id | current_task | status | end | message |

Usage

POST  /api/v1/users/<user_id>/statuses
  curl  -d 'status=OOO' \
            'https://api.rm.smartsheet.com/api/v1/users/12345/statuses?auth=...''

Sample Response

{
    "data": [
        {
            "assignable_id": 4,
            "created_at": "2013-09-12T14:33:05Z",
            "current_task": null,
            "end": null,
            "id": 1,
            "message": "Hacking away",
            "start": null,
            "status": "ITO",
            "updated_at": "2013-09-12T14:33:05Z",
            "user_id": 1
        }
    ],
    "paging": {
        "next": null,
        "page": 1,
        "per_page": 20,
        "previous": null,
        "self": "/api/v1/users/1/statuses?user_id=1&per_page=20&page=1"
    }
}

Tags per User

Endpoint: /api/v1/users/<user_id>/tags

There are two ways to list user tags:

  • Get a list of tags for a single user using the /api/v1/user/<user_id>/tags endpoint.
  • Adding the parameter fields=tags when listing/viewing through /api/v1/users

Create and attach tags to users

Attaching a tag to a user is technically a “find-or-create” operation. If you post a tag with information that does not exist for your organization it will be created and attached to the user specified. If the tag already exists, it will just be attached. If you try to create the same tag multiple times, it will just be attached once.

curl -d "value=Awesome"  "https://api.rm.smartsheet.com/api/v1/users/1/tags?auth=..."

Disconnect a tag from a user

You can remove a tag from a user without deleting it from your account settings by using the /api/v1/users endpoint.

curl -XDELETE  "https://api.rm.smartsheet.com/api/v1/users/1/tags/456?auth=..."

Response for Tags Listing

{
    "data": [
        {
            "id": 31,
            "value": "MyFirstTag"
        }
    ],
    "paging": {
        "next": null,
        "page": 1,
        "per_page": 20,
        "previous": null,
        "self": "/api/v1/users/1/tags?user_id=1&per_page=20&page=1"
    }
}

Users

The users collection allows you to access information about all users in the API.

Optional parameters:
Parameter Description
per_page, page Parameters for pagination. Default values are per_page = 20 , page = 1 ( the first )
fields A comma separated list of additional fields to include in the response, optional values [ “tags”, “assignments”, “availabilities”, “custom_field_values” ]
sort_field Field to sort the return document. Possible values: created, updated, first_name, last_name, hire_date, termination_date
sort_order Order to sort the results on. Possible values: ascending or descending
with_archived If set to true, includes archived users
include_placeholders If set to true, includes placeholder users

Endpoints

GET /api/v1/users

GET /api/v1/users/<id>

PUT /api/v1/users/<id>

POST /api/v1/users

Fields:

Name Type Description Optional Readonly
id number the user id yes
first_name string The first name
last_name string The last name
display_name string The display name yes
email string The first name
user_type_id number The role of the user (see below)
billable boolean reserved
hire_date date Date user was hired yes
termination_date date Date user was terminated yes
mobile_phone string A phone number yes
office_phone string A phone number yes
archived boolean The user has been archived
archived_at date-time When the user was archived yes yes
deleted boolean deprecated
deleted_at date-time deprecated yes
account_owner boolean Is this user the account owner yes yes
invitation_pending boolean reserved yes yes
user_settings string reserved yes
guid string Unique id of the user yes
employee_number string The employee number yes
role string The role yes
discipline string The discipline yes
location string The location yes
type string reserved yes
has_login boolean The user has setup a login yes
login_type string reserved yes
license_type string The user’s license type (see below). Defaults to licensed yes
thumbnail string A url to a user profile image yes yes
created_at date-time time of creation yes
updated_at date-time time of last update yes

Deleting vs Archiving

A user cannot be deleted via the API but they may be archived by setting the optional parameter archived to true while updating a user. It can also be unarchived by setting the optional parameter archived to false. You cannot archive the account owner.

User Type

Information about a user’s role is contained in the user_type_id property.

user_type_id Permission level
0 None
1 Administrator
2 Project Manager
3 Team Member
4 Restricted Team Member
5 Contractor
7 Scheduler

Values not described in this list are reserved for internal/future use.

API users may set the user_type_id of a user to any value except 1 (Administrator). Updating a user to be an administrator must be done through the app.

License Type

Information about the user’s license type is contained in the license_type property. Accepted values are currently licensed and managed_resource. Both types count toward the applicable limits on your plan. See Settings > People in 10,000ft for more information.

Sample Response

{
  "id": 1,
  "first_name": "Chris",
  "last_name": "James",
  "display_name": "Chris James",
  "email": "chris@example.com",
  "user_type_id": 1,
  "billable": true,
  "hire_date": null,
  "termination_date": null,
  "mobile_phone": null,
  "office_phone": null,
  "archived": false,
  "archived_at": null,
  "deleted": false,
  "deleted_at": null,
  "account_owner": false,
  "invitation_pending": false,
  "user_settings": 1376392,
  "guid": "96d769c7-1b4e-4b07-8baf-5ed6f2b915aa",
  "employee_number": null,
  "role": "Senior",
  "discipline": "Program Management",
  "location": "Seattle",
  "type": "User",
  "license_type": "licensed",
  "billability_target": 100,
  "billrate": -1,
  "has_login": true,
  "login_type": "saml",
  "thumbnail": "",
  "created_at": "2015-11-13T20:38:10Z",
  "updated_at": "2015-11-13T20:38:10Z"
}

Webhooks

Endpoint: /api/v1/webhooks

Webhooks allow users to register, via the API, a webhook that they can use to receive notifications about key events in their account. Currently, webhooks are supported for the following events.

Event Type Description
project.created fires when a new project is created
project.updated fires when a project is updated
time.entry.created fires when a new time entry is created
time.entry.updated fires when a time entry is updated
user.created fires when a new time entry is created
user.updated fires when a user is updated
assignment.created fires when a new assignment is created
assignment.updated fires when an assignment is updated

List Webhooks

GET /api/v1/webhooks

Lists all the webhooks for your organization.

Example

GET /api/v1/webhooks/

curl 'https://api.rm.smartsheet.com/api/v1/webhooks?&auth=..'

Response

{
  "paging": {
   ...
  },
  "data": [
    {
      "id":1,
      "organization_id":1,
      "url":"https://10000ft.com/process_webhooks",
      "status":"active",
      "event_type":"project.created"
    }
  ]
}

Response Fields

Field Description
id unique identifier for the webhook
organization_id unique identifier for the organization to which the webhook belongs
url url associated with the webhook, to which events are posted
status status of the webhook
event_type type of event associated with the webhook

Webhook Status

Currently, the only valid status for a webhook is ‘active’. This field is reserved for future extensions of the webhooks API.

Creating a webhook

POST /api/v1/webhooks
Required parameters:
Parameter Description
event_type type of event associated with the webhook
url url to which events should be posted

Both parameters are required. The 'event_type’ must be one of the supported types mentioned above. The url must be https with a valid host.

Deleting a webhook

DELETE /api/v1/webhooks/<webhook_id>

Updating a webhook

This is currently not permitted.

Webhook Limits

To prevent repetitive posting of the same webhook payload, no more than 10 webhooks per event type are permitted.

Webhook Payloads

When a webhook is registered for a particular event type with the 10000ft API, every time an event of that type occurs, a POST is made to the webhook URL containing data about the affected object. For example, if a webhook is registered for the project.created event, every time a new project is created, a POST with the details of the created project is made to the webhook’s URL. This POST data is known as the webhook payload. A webhook payload looks like this:

{
    "data": {
      [ data about the object]
    },
    "type": [event type]
}

The “type” field indicates what type of event occurred, and is always one of the event types listed above. The “data” field is exactly the same as what would be returned if the actual object were fetched through the API via a GET call. Refer to the Projects, Users, Time Entries and Assignments documentation for the exact format and return values for the GET output. The data is exactly the same as a simple GET call output, with no additional fields requested. It is not possible to request additional fields in the webhook payload, e.g. to request custom field values or bill rates or other data that can be requested through the 'fields’ parameter in typical API calls. If such additional data is needed when processing a webhook, it is recommended that you make a GET request using the object ID returned in the webhook payload, and specify any additional fields there.

When do Updated Events fire?

Some of our data types, such as projects and users, are fairly complex and have other 'associated’ data types such as bill rates, custom fields, etc. that are not direct properties of the object itself. We explain here what types of changes will cause updated events to trigger. Note that when an updated event fires, the payload is the same as a created event i.e. it contains data describing the object, but no specific information as to what changed. In the future, more information may be added, but currently, it is not supported.

Assignments

For assignments, any permitted change to an assignment (dates, allocation mode, percent, etc.) will trigger an updated event. Note: Changing the assignee will trigger an assignment.deleted followed by an assignment.created event. We handle assignee changes differently than other attributes internally.

Time Entries

For time entries, any permitted change such as (hours, notes, etc.) will trigger an updated event.

Projects

For projects, the following changes will trigger update events.

  • Basic project property changes: name, start date, end date, project type, etc.

The following changes do not trigger updated events.

  • Creating assignments for users on a project (though these are reported as assignment events)
  • Changing or adding project budgets
  • Changing or adding project bill rates
  • Adding/editing tags or custom fields to a project
  • Adding or change project custom fields

Some of these triggers do not exist yet because this is a newer feature. We expect update support to improve. Adding phases to a project does trigger an event, but it is a separate event for phase creation, not a project update event (see the section on phases below).

Phases

While separate webhooks for phase events do not exist, phase create and update events will be reported on project.created and project.updated webhooks.

Users

For users, the following changes will trigger update events.

  • Basic property changes: name, email, etc.
  • Role, discipline and location changes
  • Availability and bill rate changes
  • Tag and custom field changes

The following changes do not trigger updated events.

  • Creating assignments for users on a project (though these are reported as assignment events)

What should you return from your webhook processing code?

10000ft keeps track of return values from webhook processing code, and if a webhook is behaving poorly e.g. consistently unreachable or in error, it may be automatically unsubscribed. Further, returning a 410 code on a webhook will also automatically unsubscribe it.

Can Webhooks be viewed or edited from the application front-end?

At the moment there is no front end support for webhooks, they exist only as an API feature.

10,000ft Zapier Integration

Zapier is a web automation service that lets you integrate 10,000ft with thousands of other apps. You can read more details on the 10,000ft + Zapier integrations page.

Requirements

  • A 10,000ft account
  • A Zapier account
  • Optionally, an account with each service that will be connected with 10,000ft via Zapier

Zapier provides free and paid plans. See the Zapier pricing page for more info.

Connecting 10,000ft with Zapier

  • This step is only required when connecting 10,000ft with your Zapier account for the first time
  • Start by making a new Zap in your Zapier account
  • Find the 10,000ft app and pick any trigger to initiate the setup
  • When prompted, add the 10,000ft API Token into Zapier, test and save your connection

    add API token

Once the connection is setup and tested, you can use it to make new Zap. Lets go through the steps and setup an example Zap.

Configuring a Zap

Configuring a 10,000ft Zap typically involves,

  • Connecting your 10,000ft account with Zapier
  • Selecting a 10,000ft trigger
  • Optionally, configure one or more Search steps to look up additional details
    • 10,000ft Triggers typically return user or assignable IDs
    • We provide find actions so you can get additional details (e.g. a user’s email address) given their ID
    • This allows you to combine attributes you get from the trigger with additional attributes you get via searching to create Zaps that are rich in details and provide higher value.
  • Choosing an app to connect with (e.g. Email)
  • Configure, test and enable your Zap

Example: Send an email when a new assignment is made in 10,000ft

Lets try a specific example. In the steps below we will make a Zap that will send an email to when one of your team members are assigned to a project. When you are done, this is what the outline of your Zap will look like,

overview

And here are the steps in detail,

  • Sign in to your Zapier account
  • Start a Zap
  • Search for the 10,000ft app and select it
  • Select a 10,000ft Trigger (e.g. New Assignment)

new assignment trigger

  • Connect your 10,000ft app if prompted by supplying your 10,000ft API token
  • Add a step to search 10,000ft and lookup details for the user_id in the assignment

find user by id options

  • Add a step and select 10,000ft as the app
  • Search and select the Find User by ID action
  • Configure it to find the user for the user_id from the New Assignment trigger we setup above

    • Add a step to search 10,000ft and lookup details for the assignable_id in the assignment
  • Add a step and select 10,000ft as the app

  • Search and select the Find Assignable by ID action

  • Configure it to find the assignable for the assignable_id from the New Assignment trigger we setup above

    • Add a step to send an email

email template options

  • Select the Email by Zapier app
  • Configure it to send an email to user in the New Assignment
  • When you are done, the email template will look like this,

    • Test and enable your Zap.

Now, when a new assignment is made on the 10,000ft schedule, the person who was assigned will be sent an email with the name of the Project (or Leave) that they were assigned to and the start date of that assignment.

Filters & additional considerations

Zapier Filters are useful when building integrations with 10,000ft. You can use any attribute from a trigger of search action when implementing a filter. The Type attribute available in 10,000ft users and assignabled are particularly useful. For example, in the example above your Zap would typically exclude Placeholder users. This would be implemented by adding a FIlter to you Zap as shown below.

email filter options

Familiarize yourself with the different types of users and assignables available in 10,000ft when designing your 10,000ft Zaps so you can get the result you are trying to achive with your integration. See 10,000ft API documentation for more details on specific attributes.

Triggers

10,000ft provides the following Triggers

  • New Assignment Triggers when a new assignment is created.
  • New User Triggers when a new user is created.
  • New Project Triggers when a new project gets created.
  • New Time Entry Triggers when a new time entry is created.
  • Assignment Updated Triggers when an assignment is updated.
  • User Updated Triggers when a new user is updated.
  • Project Updated Triggers when a project gets updated.
  • Time Entry Updated Triggers when a new time entry is updated.

Actions

10,000ft provides the following actions for creating or updating information in your 10,000ft account via Zapier

  • Create Project Create a new project.
  • Create User Create a new team member.
  • Create Time Entry Create a new time entry.
  • Update Project Updates a project.
  • Update User Updates a team member.
  • Update Time Entry Update a time entry.

Searches

  • Find Assignable by ID Finds an existing assignable by the assignable’s ID. An assignable is anything that can be assigned to a user such as a Project or Leave type.
  • Find Project by ID Finds an existing project using the project’s ID.
  • Find User by ID Finds an existing user by their ID.
  • Find User by Email Finds an existing user by their email.
  • Find User by Name Finds an existing user by their name.
  • Find Assignable by Name Finds an existing assignable by name.
  • Find Project by Name Finds an existing project by name.

More details about the 10,000ft API

Zapier is a convenient and powerful way to consume the 10,000ft API. The triggers, actions and searches listed above allow you to access commonly used API functionality without having to develop custom API integrations or write software code.

The 10,000ft API provides access to a number of advanced features that are not currently supported with our Zapier triggers and actions. See 10,000ft API documentation for more details.

Have a question? Contact us via our Support Page. We are here to help!