Resource Management by Smartsheet API (Pro, Enterprise, and Business plans)
The Resource Management by Smartsheet 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 Resource Management by Smartsheet. 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
- General information (read first)
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.
- Users
- Placeholder Resources
- Assignables
- Custom Fields
- Project Budgets
- Assignments
- Subtasks
- Time Entries
- Expense Etems
- Bill Rates
- Statuses (deprecated)
- Time & Expense Approvals
- Holidays
- Reports
- Status Options
- API Token Management
Webhook Support
The Resource Management by Smartsheet API supports webhooks for certain events. See the webhooks section for details.
Zapier Integration
Our Zapier integration helps you integrating with the Resource Management by Smartsheet 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 Resource Management by Smartsheet API easier. Depending on your scenario, you may benefit from adopting and improving on them. Here are a couple of references,
- Revelry Labs /
ruby
/ https://github.com/revelrylabs/tenk - Spindance /
ruby
/ https://github.com/spindance/ten_thousand_feet
Questions?
Questions or feedback about our API, please submit a support ticket at our Support Page
Sections
Before starting to use the Resource Management by Smartsheet API
This documentation assumes that you have either signed up for a Resource Management by Smartsheet 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 Resource Management by Smartsheet 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
per_page should not exceed 1000 rows.
Filtering
Some resources in the Resource Management by Smartsheet API respect certain filtering parameters. Those optional parameters are as follows:
filter_field
- The property to filter on.filter_list
- The value offilter_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"'}'
API Token Management
Resource Management by Smartsheet API Tokens are used to authenticate requests to Resource Management by Smartsheet APIs. Organizations can manage up to 20 API tokens. Contact us via our Support Page if API Token Management is not enabled for your organization. The first generated token for an organization will have a set “primary” title.
Get tokens
Returns list of tokens for your organization.
Endpoint
GET /api/api_tokens
Sample Response
[
{
"id": 1,
"title": "primary",
"token": <token_string>
},
{
"id": 2,
"title": "secondary",
"token": <token_string>
},
{
"id": 3,
"title": null,
"token": <token_string>
}
]
Create token
Create additional tokens for your organization.
Endpoint
POST /api/api_tokens
Optional Query Parameter
Name | Description |
---|---|
title | an identifier for a token, cannot be “primary” |
Delete token
Deletes the given token.
Endpoint
DELETE /api/api_tokens/<id>
Renew token
Deletes the given token and creates a new token.
Endpoint
POST /api/api_tokens/renew/<id>
Update token title
Update the title of the given token.
Endpoint
PUT /api/api_tokens/<id>
Query Parameter
Name | Description |
---|---|
title | an identifier for a token, cannot be “primary” |
Approvals
Endpoint: /api/v1/approvals
In Resource Management by Smartsheet, 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 portfolio editors 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 Resource Management by Smartsheet 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 Resource Management by Smartsheet 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 ). per_page should not exceed 1000. |
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 ). per_page should not exceed 1000. |
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=...'
Update an Assignment
Typical parameters: starts_at
, ends_at
, allocation_mode (percent, hours_per_day, fixed)
, percent
, hours_per_day
, fixed_hours
, status_option_id
, description
, note
curl -XPUT -d 'description=<description>&percent=<DECIMAL>&starts_at=<YEAR-MO-DAY>' \
'https//api.rm.smartsheet.com/api/v1/assignments/<assignment_id>?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 Resource Management by Smartsheet 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>
POST /api/v1/projects/<project_id>/bill_rates
Optional Query Parameters
Name | Description |
---|---|
rebuild_assignments | rebuild ongoing and future 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
: 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
: 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 thedefault_value
, thedefault_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:
- Respects filtering 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 of1
.
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 ). per_page should not exceed 1000. |
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": 100,
"page": 1,
"previous": null,
"self": "/api/v1/users/2/expense_items?per_page=100&user_id=2&page=1",
"next": null
}
}
Holidays
Holidays are dates that your organization treats as non-working days, and entered into Resource Management by Smartsheet 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 ). per_page should not exceed 1000. |
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 ). per_page should not exceed 1000. |
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 ). per_page should not exceed 1000. |
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"
}
}
Project Membership
Endpoint: /api/v1/users/:id/project_memberships
Endpoint: /api/v1/projects/:id/project_members
The first endpoint will return a set of project_id
s given a user_id
. The second endpoint will return a set of user_id
s given a single project_id
.
Project Memberships
List
GET /api/v1/users/:id/project_memberships?membership=level
GET|POST /api/v1/relationships/project_memberships?user_ids=id,id,id&membership=level
Both will get a list of Project
s which the user or users are a member of, at the provided level.
In the case where no membership level is given, the GET defaults to member
ie. any level. Valid membership levels include: member, viewer, reporter, scheduler, and editor.
Result: Paginated API result, data
field will consist of tuples that look similar to the following:
{"id": 1234, uid: "Project-1234", name: "Project Name"}
Set
POST /api/v1/users/:id/project_memberships
This API call replaces the user’s project memberships. JSON body should include a relationships
field with [project_id, membership_level]
tuples.
NOTE: This replaces the membership list. If you leave off a project, the user will be REMOVED from that project. If the user was already a member of a project, their membership will be changed to the level specified. If the user was not previously a member of a project, they will be added with the level specified.
PUT /api/v1/users/:id/project_memberships
This API call updates the user’s project memberships. JSON body should include a relationships
field with [project_id, membership_level]
tuples.
NOTE: This updates the membership list. If you leave off a project, the user’s relationship to that project will be unchanged. If the user was already a member of a project, their membership will be changed to the level specified. If the user was not previously a member of a project, they will be added with the level specified.
Remove
DELETE /api/v1/users/:id/project_memberships
This API call removes the single user from the project’s membership list. JSON body should include a project_ids
field, which is an array of [project_id, project_id, ...]
.
Project Members
This section contains endpoints pertaining to the members of a particular project.
List
GET /api/v1/projects/:id/project_members?membership=level
GET|POST /api/v1/relationships/project_members?project_ids=id,id,id&membership=level
Both will get a list of User
s who are members of the project or projects, at the provided level.
In the case where no membership level is given, the GET defaults to member
ie. any level. Valid membership levels include: member, viewer, reporter, scheduler, and editor.
Result: Paginated API result, data
field will consist of tuples that look similar to the following:
{"id": 1234, uid: "User-1234", name: "User's Name"}
Set
POST /api/v1/projects/:id/project_members
This API call replaces the project’s membership list. JSON body should include a relationships
field with [user_id, membership_level]
tuples.
NOTE: This replaces the membership list. If you leave off a project, the user will be REMOVED from that project. If the user was already a member of a project, their membership will be changed to the level specified. If the user was not previously a member of a project, they will be added with the level specified.
PUT /api/v1/projects/:id/project_members
This API call updates the project’s membership list. JSON body should include a relationships
field with [user_id, membership_level]
tuples.
NOTE: This updates the membership list. If you leave off a project, the user’s relationship to that project will be unchanged. If the user was already a member of a project, their membership will be changed to the level specified. If the user was not previously a member of a project, they will be added with the level specified.
Remove
DELETE /api/v1/projects/:id/project_members
This API call removes users from the project’s membership list. JSON body should include a user_ids
field, which is an array of [user_id, user_id, ...]
.
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 ). per_page should not exceed 1000. |
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 ). per_page should not exceed 1000. |
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=100&auth=<token>
{
"id":821065,
"archived":false,
"archived_at":null,
"description":"",
"guid": "xxxx-xxxx-xxxx-xxxx-xxxx-xxxx",
"name":"Resource Management by Smartsheet 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=100&page=1",
"next":null,
"previous":null,
"page":1,
"per_page":100
},
"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
GET /api/v1/roles
will return a paginated list of Roles.
Optional parameters:
- Respects filtering 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 of1
.
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 Resource Management by Smartsheet 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 Resource Management by Smartsheet 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, Resource Management by Smartsheet 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 Resource Management by Smartsheet'
}
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 Resource Management by Smartsheet 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, Resource Management by Smartsheet 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 ). per_page should not exceed 1000. |
fields | A comma separated list of additional fields to include in the response, optional values [ “tags”, “assignments”, “availabilities”, “custom_field_values”, “approvers” ] |
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 |
approver_user_ids |
array of numbers | A list of other users who approve this user’s timesheets | yes | |
approvee_user_ids |
array of numbers | A list of other users whose timesheets this user approves | yes | |
last_login_time |
date-time | Last time the user logged in | 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 | Resourcing Administrator |
2 | Portfolio Editor |
3 | Portfolio Reporter |
4 | Portfolio Viewer |
5 | Contractor |
7 | People Scheduler |
8 | Project Editor |
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 Resource Management by Smartsheet 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": "",
"approver_user_ids": [123, 456, 789],
"approvee_user_ids": [222, 333, 444],
"last_login_time": "2022-02-17T19:12:36Z",
"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://hooks.example.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 Resource Management by Smartsheet 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?
Resource Management by Smartsheet 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.
Resource Management by Smartsheet Zapier Integration
Zapier is a web automation service that lets you integrate Resource Management by Smartsheet with thousands of other apps. You can read more details on the Resource Management by Smartsheet + Zapier integrations page.
Requirements
- A Resource Management by Smartsheet account
- A Zapier account
- Optionally, an account with each service that will be connected with Resource Management by Smartsheet via Zapier
Zapier provides free and paid plans. See the Zapier pricing page for more info.
Connecting Resource Management by Smartsheet with Zapier
- This step is only required when connecting Resource Management by Smartsheet with your Zapier account for the first time
- Start by making a new Zap in your Zapier account
- Find the Resource Management by Smartsheet app and pick any trigger to initiate the setup
When prompted, add the Resource Management by Smartsheet API Token into Zapier, test and save your connection
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 Resource Management by Smartsheet Zap typically involves,
- Connecting your Resource Management by Smartsheet account with Zapier
- Selecting a Resource Management by Smartsheet trigger
- Optionally, configure one or more Search steps to look up additional details
- Resource Management by Smartsheet 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 Resource Management by Smartsheet
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,
And here are the steps in detail,
- Sign in to your Zapier account
- Start a Zap
- Search for the Resource Management by Smartsheet app and select it
- Select a Resource Management by Smartsheet Trigger (e.g. New Assignment)
- Connect your Resource Management by Smartsheet app if prompted by supplying your Resource Management by Smartsheet API token
- Add a step to search Resource Management by Smartsheet and lookup details for the user_id in the assignment
- Add a step and select Resource Management by Smartsheet 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 Resource Management by Smartsheet and lookup details for the assignable_id in the assignment
Add a step and select Resource Management by Smartsheet as the app
Search and select the
Find Assignable by ID
actionConfigure it to find the assignable for the
assignable_id
from the New Assignment trigger we setup above- Add a step to send an email
- 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 Resource Management by Smartsheet 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 Resource Management by Smartsheet. You can use any attribute from a trigger of search action when implementing a filter. The Type
attribute available in Resource Management by Smartsheet 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.
Familiarize yourself with the different types of users and assignables available in Resource Management by Smartsheet when designing your Resource Management by Smartsheet Zaps so you can get the result you are trying to achive with your integration. See Resource Management by Smartsheet API documentation for more details on specific attributes.
Triggers
Resource Management by Smartsheet 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
Resource Management by Smartsheet provides the following actions for creating or updating information in your Resource Management by Smartsheet 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 Resource Management by Smartsheet API
Zapier is a convenient and powerful way to consume the Resource Management by Smartsheet 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 Resource Management by Smartsheet API provides access to a number of advanced features that are not currently supported with our Zapier triggers and actions.
Have a question? Contact us via our Support Page. We are here to help!