Features API Reference

Complete API reference for Features entity type covering GET, POST, and DELETE operations.

Overview

GET Operations

Use GET operations to retrieve Features data from the API.

Note:

Options for working with inner collections If you'd like to get an inner collection there is an option to either include it into the list of retrieved fields, or to query this collection directly:

  • /api/v1/features?include=[Id,Name,UserStories]&take=100&innertake=1000
  • /api/v1/userstories?include=[Id,Name,Feature]&take=1000

We recommend using the second approach.

Here are some popular queries:

  • get Features created last month: /api/v1/features?where=(CreateDate gte '2017-01-01')and(CreateDate lte '2017-01-31')&take=1000
  • get Features closed last months: /api/v1/features?where=(EndDate gte '2017-01-01')and(EndDate lte '2017-01-31')&take=1000
  • get Features in the current release: /api/v1/features?where=(Release.IsCurrent eq 'true')&take=1000
  • get Features created by user ID#1: /api/v1/features?where=(Owner.Id eq 1)&include=[Id,Name,CreateDate,StartDate,EndDate,EntityState]&take=1000","sidebar":true}

C# Example (Token Auth)

using System;
using System.Net;
using System.Net.Http;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //get 5 oldest Features which are not closed yet
            string query = "features?where=(EntityState.IsFinal eq 'false')&take=5&orderby=CreateDate&include=[Id,Name,EntityState]";

            //using a token generated at /api/v1/Authentication
            query += "&token=Njo4OTIyQzkzN0M5NEY3NzNENDIyNTM2RDU3MTMwMTMwOA==";
            Console.WriteLine("Pulling " + query);
            
            HttpResponseMessage response = client.GetAsync(query).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

C# Example (Access Token Auth)

using System;
using System.Net;
using System.Net.Http;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //get Features closed last week
            string lastMonday = DateTime.Now.AddDays(-(int)DateTime.Now.DayOfWeek - 6).ToString("yyyy-MM-dd");
            string query = "features?where=(EndDate gte '" + lastMonday + "')&include=[Id,Name,EndDate,TimeSpent]&take=1000";

            //using access token generated at Personal Details page (Access Tokens tab)
            query += "&access_token=NjplaXdQeTJDOHVITFBta0QyME85QlhEOWpwTGdPM2V6VjIyelZlZ0NKWG1RPQ==";
            Console.WriteLine("Pulling " + query);

            HttpResponseMessage response = client.GetAsync(query).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

C# Example (Basic Auth)

using System;
using System.Net;
using System.Net.Http;
using System.Text;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //get Features for project with ID#192
            string query = "features?where=(Project.Id eq 192)&take=1000&include=[Id,Name,EntityState]";

            //using basic authentication (here 'John' is login and '123' is password)
            string authentication = Convert.ToBase64String(Encoding.ASCII.GetBytes("John:123"));
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authentication);
            Console.WriteLine("Pulling " + query);

            HttpResponseMessage response = client.GetAsync(query).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

C# Example (No Auth)

using System;
using System.Net;
using System.Net.Http;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //get a Feature with ID#206
            string query = "features/206?include=[Id,Name,EntityState]&append=[UserStories-count]";

            //using no authentication will result in 401 Unauthorized response
            Console.WriteLine("Pulling " + query);

            HttpResponseMessage response = client.GetAsync(query).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

POST Operations

Use POST operations to create new Features or update existing ones.

Note: To update a Feature you have to know its ID. To add a new Feature you have to know ID of its Project. If you'd like to connect a Feature to some resources (EntityState, Team, Owner, Release, etc.) you have to know their IDs.

Here are some popular queries:

  • change state for Feature ID#206:
    • GET to /api/v1/features/206?include=[EntityState[NextStates]] (to know ID of the state)

      POST to /api/v1/features/212 payload {\"EntityState\":{\"Id\":107}}

  • set value \"https://en.wikipedia.org/wiki/Wiki\" for custom field \"Wiki link\" for Feature ID#216:
    • POST TO /api/v1/features/216 payload {\"CustomFields\":[{\"Name\":\"Wiki link\",\"Value\":{\"Url\":\"https://en.wikipedia.org/wiki/Wiki\",\"Label\":\"wiki\"}}]}

  • add a new comment for Feature ID#206:
    • POST to /api/v1/comments payload {\"Description\":\"New comment\",\"General\":{\"Id\":206}}

  • create a User Story for Feature ID#206:
    • GET to /api/v1/features/206?include=[Project] (to know ID of the project)

      POST to /api/v1/userstories payload {\"Name\":\"New Story\",\"Project\":{\"Id\":2},\"Feature\":{\"Id\":206}}

  • add a Feature to Project ID#2 and assign User ID#6 as Developer:
    • POST to /api/v1/features payload {\"Name\":\"New Feature\",\"Project\":{\"Id\":2},\"Assignments\":[{\"GeneralUser\":{\"Id\":6},\"Role\":{\"Id\":1}}]}

  • set planned dates for several Feature (ID#60 and ID#70):
    • POST to /api/v1/features/bulk payload [{\"Id\":60,\"PlannedStartDate\":\"2017-03-19\",\"PlannedEndDate\":\"2017-08-29\"},{\"Id\":70,\"PlannedStartDate\":\"2017-03-19\",\"PlannedEndDate\":\"2017-08-29\"}]

  • create several Features in Project ID#2:
    • POST to /api/v1/features/bulk payload [{\"Project\":{\"Id\":2},\"Name\":\"First Feature\"},{\"Project\":{\"Id\":192},\"Name\":\"Second Feature\"}]","sidebar":true}

C# Example (Access Token Auth)

using System;
using System.Net;
using System.Net.Http;
using System.Text;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //create a new Feature in Project ID#2
            string query = "features";
            HttpContent payload = new StringContent("{\"Name\":\"New Feature\",\"Project\":{\"Id\":2}}", Encoding.UTF8, "application/json");

            //using access token generated at Personal Details page (Access Tokens tab)
            query += "?access_token=NjplaXdQeTJDOHVITFBta0QyME85QlhEOWpwTGdPM2V6VjIyelZlZ0NKWG1RPQ==";
            Console.WriteLine("Posting to " + query);

            HttpResponseMessage response = client.PostAsync(query, payload).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

C# Example (Token Auth)

using System;
using System.Net;
using System.Net.Http;
using System.Text;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //create a new Feature in Project ID#2
            string query = "features";
            HttpContent payload = new StringContent("{\"Name\":\"New Feature\",\"Project\":{\"Id\":2}}", Encoding.UTF8, "application/json");

            //using a token generated at /api/v1/Authentication
            query += "?token=Njo4OTIyQzkzN0M5NEY3NzNENDIyNTM2RDU3MTMwMTMwOA==";
            Console.WriteLine("Posting to " + query);

            HttpResponseMessage response = client.PostAsync(query, payload).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

C# Example (Basic Auth)

using System;
using System.Net;
using System.Net.Http;
using System.Text;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //create a new Feature in Project ID#2
            string query = "features";
            HttpContent payload = new StringContent("{\"Name\":\"New Feature\",\"Project\":{\"Id\":2}}", Encoding.UTF8, "application/json");

            //using basic authentication (here 'John' is login and '123' is password)
            string authentication = Convert.ToBase64String(Encoding.ASCII.GetBytes("John:123"));
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authentication);
            Console.WriteLine("Posting to " + query);

            HttpResponseMessage response = client.PostAsync(query, payload).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

C# Example (No Auth)

using System;
using System.Net;
using System.Net.Http;
using System.Text;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //create a new Feature in Project ID#2
            string query = "features";
            HttpContent payload = new StringContent("{\"Name\":\"New Feature\",\"Project\":{\"Id\":2}}", Encoding.UTF8, "application/json");

            //using no authentication will result in 401 Unauthorized response
            Console.WriteLine("Posting to " + query);

            HttpResponseMessage response = client.PostAsync(query, payload).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}
Note: Adding or updating several Features at once You can operate with several Features at once by using /api/v1/features/bulk endpoint.

DELETE Operations

Use DELETE operations to remove Features from the system.

C# Example (Access Token Auth)

using System;
using System.Net;
using System.Net.Http;
using System.Text;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //delete Feature ID#218
            string query = "features/218";

            //using access token generated at Personal Details page (Access Tokens tab)
            query += "?access_token=NjplaXdQeTJDOHVITFBta0QyME85QlhEOWpwTGdPM2V6VjIyelZlZ0NKWG1RPQ==";
            Console.WriteLine("Posting to " + query);

            HttpResponseMessage response = client.DeleteAsync(query).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

C# Example (Token Auth)

using System;
using System.Net;
using System.Net.Http;
using System.Text;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //delete Feature ID#218
            string query = "features/218";

            //using a token generated at /api/v1/Authentication
            query += "?token=Njo4OTIyQzkzN0M5NEY3NzNENDIyNTM2RDU3MTMwMTMwOA==";
            Console.WriteLine("Posting to " + query);

            HttpResponseMessage response = client.DeleteAsync(query).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

C# Example (Basic Auth)

using System;
using System.Net;
using System.Net.Http;
using System.Text;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //delete Feature ID#218
            string query = "features/218";

            //using basic authentication (here 'John' is login and '123' is password)
            string authentication = Convert.ToBase64String(Encoding.ASCII.GetBytes("John:123"));
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authentication);
            Console.WriteLine("Posting to " + query);

            HttpResponseMessage response = client.DeleteAsync(query).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}

C# Example (No Auth)

using System;
using System.Net;
using System.Net.Http;
using System.Text;

namespace REST.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://restapi.tpondemand.com/api/v1/");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

            //delete Feature ID#218
            string query = "features/218";

            //using no authentication will result in 401 Unauthorized response
            Console.WriteLine("Posting to " + query);

            HttpResponseMessage response = client.DeleteAsync(query).Result;
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.Content.ReadAsStringAsync().Result);
            }
            else
            {
                Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            }
        }
    }
}