Content-Type: applicaiton/json
and Accept: application/json
headers.
The API facilitates integration with external systems and allows direct queries to the Lifecycle data.
We have language bindings in Shell, C#, Javascipt, and Python! You can switch the programming language of the examples with the tabs above.
We highly suggest reading over the terminology section to become familiar with concepts like Assets, Attributes, Filter Tokens and more. Once you have a hande of the basics you'll begin to see how expressive the VersionOne APIs can be! Happy coding!
The first step is to find your VersionOne URL. It may look similar to this: https://www7.v1host.com/V1Instance
In this case, www7.v1host.com
is your host and V1Instance
is your instance.
These will be used to build your base URL that all requests to the API will rely on.
Every request to the VersionOne API must have the Authorization HTTP Header set. You can do this using your username and password, but it is reccommended that you use an access token. Access tokens are associated with an application and grant the application certain access to resources. The application can act on behalf of the member who created the access token.
You may use your username and password using Basic authentication by setting the Authorization header.
You'll have to base64 encode username:password
including the :
to accomplish this.
curl "https://V1Host/V1Instance/api_endpoint_here"
-H "Authorization: Basic username:password"
VersionOne uses access tokens to grant access to the API. You can register a new access token by logging into VersionOne and navigating to the Applications page. This is the suggested way to interact with the VersionOne API.
curl "https://V1Host/V1Instance/api_endpoint_here"
-H "Authorization: Bearer <access-token>"
To validate that your access token is working prooperly, you can try an HTTP request like below.
curl 'https://V1Host/V1Instance/rest-1.v1/Data/Member?where=IsSelf="true"&sel=Username'
-H "Authorization:Bearer <access-token>"
-H "Accept:application/json"
You should get back a response similar to this:
{
"_type":"Assets",
"total":1,
"pageSize":2147483647,
"pageStart":0,
"Assets":[
{
"_type":"Asset",
"href":"/V1Instance/rest-1.v1/Data/Member/20",
"id":"Member:20",
"Attributes":{
"Username":{
"_type":"Attribute",
"name":"Username",
"value":"admin"
}
}
}
]
}
curl "https://V1Host/V1Instance/api_endpoint_here"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
For this guide we will only show the VersionOne server accepting and responding with JSON.
The Content-Type
header tells the server what media type we are sending it in the request body.
The Accept
header tells the server what media type to respond to the request with.
Content-Type: applicaiton/json
and Accept: application/json
headers.
The VersionOne API uses the following error codes:
Error Code | Message | Meaning |
---|---|---|
400 | Bad Request | Most common error, resulting from a request that could not be processed by the API. The Error Message will identify the specific problem, and there may be Exception elements that give very detailed information |
401 | Unauthorized | Your access token is invalid |
404 | Not Found | The specified resource could not be found |
405 | Method Not Allowed | The HTTP method used for the request is not valid at the requested URL. This will be returned for any method other than GET and POST, or if POST was sent to a URL that does not support updating. |
500 | Internal Server Error | An unexpected error occurred during the processing of the request. The response payload will contain Exception elements with specific information that will help technical diagnose the cause of the error. |
A System Asset is a core business object in the VersionOne® Lifecycle model. Each asset represents the stories/backlog items, defects, sprints/iterations, and the members who use the system. The diagram below illustrates the relationship of these assets to one another and how they work together to help you manage your workflow.
Asset types describe the "classes" of data available. Each asset type contains a collection of attribute definitions, a collection of operations, and a number of useful attribute definitions for things like sorting. Asset types form an inheritance hierarchy, such that each asset type inherits attribute definitions, operations, and rules from its parent asset type. Those asset types at the leaves of this hierarchy are concrete, whereas asset types with children asset types are abstract. Assets are all instances of concrete asset types. Asset types are identified by unique names.
By way of example, Story and Defect are concrete asset types. On the other hand, Workitem is an abstract asset type, from which Story and Defect ultimately derive.
Most asset types have the same name as found in the application user interface. A Defect in the user interface is also a Defect as an asset type. However, many of the most common asset types have a different name.
System Name | XP | Scrum | AgileUP | DSDM |
---|---|---|---|---|
Scope | Project | Project | Project | Project |
ScopeLabel | Project | Project | Project | Project |
Story | Story | Backlog Item | Requirement | Requirement |
Timebox | Iteration | Sprint | Iteration | Iteration |
Theme | Theme | Feature Group | Use Case | Feature Group |
Asset states represent system-known life-cycle stage of an asset. The UI typically only show assets that are not "Dead".
State | Name | Meaning |
---|---|---|
0 | Future | |
64 | Active | The asset has been assigned to a user-defined workflow status. |
128 | Closed | The asset has been closed or quick-closed. |
200 | Template (Dead) | The asset is only used to create new copies as part of creating from Templates or Quick Add. |
208 | Broken Down (Dead) | The asset was converted to an Epic for further break-down. |
255 | Deleted (Dead) | The asset has been deleted. |
Attribute definitions describe the properties that "make up" each asset type. Each attribute definition describes the type of data it can contain, as well as whether it is required, read only, multi-value, and many other qualities. Attribute definitions are identified by a name that is unique within its asset type. Attribute definitions are defined as either value types or relations to other assets. Furthermore, relation attribute definitions can be either single-value or multi-value.
For example, the Estimate
attribute definition on the Workitem
asset type is a scalar (specifically, a Number). On the other hand, the Workitem
asset type's Scope
attribute definition is a single-value relation (to a Scope asset). The reverse relation, Workitems
on the Scope
asset type, is a multi-value relation (to Workitem
assets).
An Oid is a unique system identifier that is not typically visible in the VersionOne user interface. Oid Tokens are composed of the name of an asset type and an integer ID. For example, Member:20
identifies a Member
asset with ID of 20.
This is not the same as the user visible Number attribute available on many (but not all) assets.
An attribute is a single or multi-value property on an asset. For example, a Story has an attribute called Reference
which contains text, while the Owners
attribute is a multi-value relationship which allows multiple people to own a single Workitem
asset. Attributes can be very simple such as the previously mentioned Reference
attribute or they may be complex including downcasting, filters, and aggregates.
It can be useful to follow a relationship from one asset through another to get another piece of information. For example, if you wanted to know the name of a Category
attribute on a Story
asset you could ask for the attribute Category.Name
and it would return the Name
attribute of the StoryCategory
which the Story
asset relates to.
https://V1Host/V1Instance/rest-1.v1/Data/Story/1000/Category.Name
A Scope
asset has a relation calledWorkitems
which points to all the Workitem
assets that belong to the given Scope
. This includes Story
, Defect
, Task
, and Test
asset types. If you wish to only get Story
assets you can use downcasting to filter to Workitem
assets to a specific type. The following example would return only those Story
assets that are in Scope
with ID 0
.
https://V1Host/V1Instance/rest-1.v1/Data/Scope/0/Workitems:Story
In another example, you may wish to know all the Workitem
assets in a given Scope
that are owned by a specific Member
. A filtered attribute would help solve this problem. You can use Workitems[Owners='Member:20']
to return only those Workitem
assets that are owned by Member
with ID 20
. An example URL would look like the following.
https://V1Host/V1Instance/rest-1.v1/Data/Scope/0/Workitems[Owners='Member:20']
Let's say you wanted to get the total number of Workitem
assets in a particular Scope
. You can use the aggregate portion of an attribute to count the number of Workitem
assets. The following example would return the total number of Workitem
assets that belong to Scope
with ID 0
.
https://V1Host/V1Instance/rest-1.v1/Data/Scope/0/Workitems.@Count
To combine all of this into a more complex example, you may also wish to get the total Estimate
for all Story
assets that have an Owner
and are in a given Scope
. Rather than getting all Workitem
assets and programmatically sorting them into buckets, the API can help you. You can follow a relationship, filter the relationship, and then finally use an aggregate to return the final count all using a single attribute on a Scope asset.
The corresponding attribute would be something like this: Workitems:Story[Owners.@Count!='0'].Estimate.@Sum
In this example, the Scope.Workitems
attribute will be downcast to only include Story
assets, then filtered where the number of Owners
is not zero. Once the filtered list is determined, then Estimate for those Story assets will be pulled and finally a single sum will be returned. This attribute will have a URL like the following.
https://V1Host/V1Instance/rest-1.v1/Data/Scope/0/Workitems:Story[Owners.@Count!='0'].Estimate.@Sum
Meta.v1 can be used to query for the description of all AssetTypes or a specific AssetType like Story
, Defect
, or Member
. This can be useful if you want to know what Attributes are defined for a given Asset.
It also inlcudes details about how Assets are related to one antother, what Attributes are required, and what operations can be executed on any given Asset.
~/meta.v1?xsl=api.xsl
has a more human friendly representation of this information!
This endpoint retrieves a description of all AssetTypes like Story
, Defect
, Member
.
GET http://V1Host/V1Instance/meta.v1
{
"HREF": "/V1Instance/meta.v1/",
"Version": "18.2.5.14",
"AssetTypes": {
"AssetType": {
"_type": "AssetType",
"Name": "AssetType",
"Token": "AssetType",
"DisplayName": "AssetType'AssetType",
"Abstract": false,
"DefaultOrderBy": {
"href": "/V1Instance/meta.v1/AssetType/Order",
"tokenref": "AssetType.Order"
},
"DefaultDisplayBy": {
"href": "/V1Instance/meta.v1/AssetType/Name",
"tokenref": "AssetType.Name"
},
"ShortName": {
"href": "/V1Instance/meta.v1/AssetType/Name",
"tokenref": "AssetType.Name"
},
"Name": {
"href": "/V1Instance/meta.v1/AssetType/Name",
"tokenref": "AssetType.Name"
},
"Attributes": {
"AssetType.ID": {
"_type": "AttributeDefinition",
"Name": "ID",
"Token": "AssetType.ID",
"DisplayName": "AttributeDefinition'ID'AssetType",
"AttributeType": "Relation",
"IsReadOnly": true,
"IsRequired": false,
"IsMultivalue": false,
"IsCanned": true,
"IsCustom": false,
"ReciprocalRelation": {
"href": "/V1Instance/meta.v1/AssetType/ID",
"tokenref": "AssetType.ID"
},
...
}
...
}
}
}
}
curl "https://V1Host/V1Instance/meta.v1/:assetType"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
This endpoint retrieves a description of an AssetType like Story
, Defect
, Member
or any Asset in the system.
GET http://V1Host/V1Instance/meta.v1/:assetType
{
"_type": "AssetType",
"HREF": "/V1Instance/meta.v1/Member",
"Version": "18.2.5.14",
"Name": "Member",
"Token": "Member",
"DisplayName": "AssetType'Member",
"Abstract": false,
"Base": {
"nameref": "BaseAsset",
"href": "/V1Instance/meta.v1/BaseAsset"
},
"DefaultOrderBy": {
"href": "/V1Instance/meta.v1/Member/Name",
"tokenref": "Member.Name"
},
"DefaultDisplayBy": {
"href": "/V1Instance/meta.v1/Member/Name",
"tokenref": "Member.Name"
},
"ShortName": {
"href": "/V1Instance/meta.v1/Member/Nickname",
"tokenref": "Member.Nickname"
},
"Name": {
"href": "/V1Instance/meta.v1/Member/Name",
"tokenref": "Member.Name"
},
...
}
curl "https://V1Host/V1Instance/api/ActivityStream/:OidToken"
-H "Authorization: Bearer <access-token>"
-H "Accept: application/json"
The bulk api can be used to make several operations in a single HTTP request.
http://V1Host/V1Instance/api/asset?previewonly=true
The following request will not modify any asset within the system:
{
"from": "Story",
"where":{
"Number": "S-01004"
},
"update": {
"Name": "Story Name Change"
}
}
Expect a result similar to this:
[
{
"@2b9d4588-4e1b-4bcb-b38b-a08ad59539e7": {
"oid": "Story:1210",
"update": {
"Name": {
"add": [
"Story Name Change"
],
"remove": []
}
}
}
}
]
Aliasing will allow you to assign the output of a bulk operation to a reference. One of the advantages of this feature is that it will allow users to make a reference to previously created assets in a later part of the payload. For example, I want to create a brand new scope and use this scope but reference it later on in the payload.
Create a new scope and then create a new story whose scope is the newly created scope.
POST http://V1Host/V1Instance/api/asset
[
{
"@newScope": {
"AssetType":"Scope",
"Name":"New Scope",
"Super": "Scope:0"
}
},
{
"@newStory": {
"AssetType":"Story",
"Name":"New Story",
"Scope": "@newScope"
}
}
]
{
"requestId": "767f7870-bc12-46d4-a978-e55e6bc405f1",
"createdDate": "2018-08-24T15:06:53.1347214Z",
"completedDate": "2018-08-24T15:06:53.2732206Z",
"duration": "00:00:00.1384992",
"durationSeconds": 0.1384992,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [
"Story:3604",
"Scope:3606"
],
"count": 1
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '[
"@newScope":{
"AssetType":"Scope",
"Name":"New Scope",
"Super": "Scope:0"
},
"@newStory":{
"AssetType":"Story",
"Name":"New Story",
"Scope": "@newScope"
},
]'
Create a single asset.
POST http://V1Host/V1Instance/api/asset
{
"AssetType": "Story",
"Name": "New Story",
"Scope": "Scope:0"
}
{
"requestId": "767f7870-bc12-46d4-a978-e55e6bc405f1",
"createdDate": "2018-08-24T15:06:53.1347214Z",
"completedDate": "2018-08-24T15:06:53.2732206Z",
"duration": "00:00:00.1384992",
"durationSeconds": 0.1384992,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [
"Story:3604"
],
"count": 1
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"AssetType": "Story",
"Name": "New Story",
"Scope": "Scope:0"
}'
Create many assets via a single HTTP request.
POST http://V1Host/V1Instance/api/asset
[
{
"AssetType": "Story",
"Name": "New Story",
"Scope": "Scope:0"
},
{
"AssetType": "Story",
"Name": "Another New Story",
"Scope": "Scope:0"
},
{
"AssetType": "Scope",
"Name": "New Scope",
"Scope": "Scope:0"
}
]
{
"requestId": "767f7870-bc12-46d4-a978-e55e6bc405f1",
"createdDate": "2018-08-24T15:06:53.1347214Z",
"completedDate": "2018-08-24T15:06:53.2732206Z",
"duration": "00:00:00.1384992",
"durationSeconds": 0.1384992,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [
"Story:3604",
"Story:3605"
"Scope:3606"
],
"count": 1
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '[
{
"AssetType": "Story",
"Name": "New Story",
"Scope": "Scope:0"
},
{
"AssetType": "Story",
"Name": "Another New Story",
"Scope": "Scope:0"
},
{
"AssetType": "Scope",
"Name": "New Scope",
"Scope": "Scope:0"
}
]'
Filter query results.
AssetState!=255
)POST http://V1Host/V1Instance/api/asset
{
"from": "Story",
"filter": [
"Children[AssetState!=\"255\"].@Count>\"0\""
]
}
{
"requestId": "f380237e-e1e8-4310-950f-36ce16381e35",
"createdDate": "2018-08-29T02:11:00.4022201Z",
"completedDate": "2018-08-29T02:11:00.6050231Z",
"duration": "00:00:00.2028030",
"durationSeconds": 0.20280299999999998,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"queryResult": {
"results": [
[
{"_oid": "Story:2345"},
{"_oid": "Story:3456"}
]
],
"count": 1
}
}
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from":"Story",
"filter": [
Children[AssetState!="255"].@Count>"0"
]
}'
Execute an operation on a single asset.
Story:1234
POST http://V1Host/V1Instance/api/asset
{
"from": "Story:1234",
"execute": "Delete"
}
{
"requestId": "340626bb-a623-4029-9eaa-e7441ee7fe3c",
"createdDate": "2018-08-29T02:00:50.789788Z",
"completedDate": "2018-08-29T02:00:51.133026Z",
"duration": "00:00:00.3432380",
"durationSeconds": 0.343238,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [
"Story:1234"
],
"count": 1
},
"queryResult": {
"results": [],
"count": -1
}
}
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story:1234",
"execute": "Delete"
}'
Update attributes on a single asset.
Story:1234
to Updated Story
POST http://V1Host/V1Instance/api/asset
{
"from": "Story:1234",
"update": {
"Name": "Updated Story"
}
}
{
"requestId": "a39afdd9-e471-4ecd-9ff5-73fad2b9ef03",
"createdDate": "2018-08-29T01:59:12.5584932Z",
"completedDate": "2018-08-29T01:59:12.5740873Z",
"duration": "00:00:00.0155941",
"durationSeconds": 0.0155941,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [
"Story:1234"
],
"count": 1
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from":"Story:1234",
"update": {
"Name": "Updated Story"
}
}'
Update attributes on multiple assets via a single HTTP request.
Epic:1234
Epic and rename themPOST http://V1Host/V1Instance/api/asset
{
"from": "Story",
"where": {
"Super": "Epic:1234"
},
"update": {
"Name": "Updated Story"
}
}
{
"requestId": "a39afdd9-e471-4ecd-9ff5-73fad2b9ef03",
"createdDate": "2018-08-29T01:59:12.5584932Z",
"completedDate": "2018-08-29T01:59:12.5740873Z",
"duration": "00:00:00.0155941",
"durationSeconds": 0.0155941,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [
"Story:1234",
"Story:1235",
"Story:1242"
],
"count": 3
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from":"Story",
"where": {
"Super": "Epic:1234"
},
"update": {
"Name": "Updated Story"
}
}'
Query for assets with a single query specification and retrieve a single result set.
Scope:0
POST http://V1Host/V1Instance/api/asset
{
"from": "Story",
"where": {
"Scope": "Scope:0"
},
"select": [
"Name"
]
}
{
"requestId": "b71c55f7-8a5a-4465-b87f-73ea428fc92a",
"createdDate": "2019-08-23T18:56:38.5865376Z",
"completedDate": "2019-08-23T18:56:38.6835443Z",
"duration": "00:00:00.0970067",
"durationSeconds": 0.0970067,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"queryResult": {
"results": [
[
{
"_oid": "Story:4014",
"Name": "API Users can Read Error Details"
},
{
"_oid": "Story:1692",
"Name": "Product Managers can specfify priority"
}
]
],
"count": 1
}
}
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"where": {
"Scope": "Scope:0"
},
"select": [
"Name"
]
}'
Query for assets with multiple query specifications and retrieve multiple result sets.
Scope:0
and also query for active members and their OwnedWorkitems.POST http://V1Host/V1Instance/api/asset
[
{
"from": "Story",
"wwhere": {
"Scope": "Scope:0"
},
"select": [
"Name"
]
},
{
"from": "Member",
"where": {
"Inactive": false
},
"select": [
"Name",
"Username",
{
"from": "OwnedWorkitems",
"select": [
"Name"
]
}
]
}
]
{
"requestId": "c722e9e3-1ac5-4d2d-93a6-2c2677d9c9e0",
"createdDate": "2019-08-23T19:57:56.783439Z",
"completedDate": "2019-08-23T19:57:56.955049Z",
"duration": "00:00:00.1716100",
"durationSeconds": 0.17160999999999999,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"queryResult": {
"results": [
[
{
"_oid": "Story:4014",
"Name": "API Users can Read Error Details"
},
{
"_oid": "Story:1692",
"Name": "Product Managers can specfify priority"
}
],
[
{
"_oid": "Member:20",
"Name": "Administrator",
"Username": "admin",
"OwnedWorkitems": [
{
"_oid": "Defect:1758",
"Name": "Dialog box missing title"
},
{
"_oid": "Epic:4123",
"Name": "Error Reporting"
}
]
},
{
"_oid": "Member:1024",
"Name": "Marv Irwin",
"Username": "MarvIrwin",
"OwnedWorkitems": [
{
"_oid": "Defect:4033",
"Name": "API Error message lacks summary information"
},
{
"_oid": "Story:4014",
"Name": "API Users can Read Error Details"
}
]
},
{
"_oid": "Member:1043",
"Name": "Billy Agilisto",
"Username": "bagile",
"OwnedWorkitems": [
{
"_oid": "Story:1692",
"Name": "Product Managers can specfify priority"
},
{
"_oid": "Story:3479",
"Name": "Testers can rank Defect severity"
},
{
"_oid": "Story:2046",
"Name": "Release Managers can schedule Workitems into Releases"
},
]
],
"count": 2
}
}
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '[
{
"from": "Story",
"wwhere": {
"Scope": "Scope:0"
},
"select": [
"Name"
]
},
{
"from": "Member",
"where": {
"Inactive": false
},
"select": [
"Name",
"Username",
{
"from": "OwnedWorkitems",
"select": [
"Name"
]
}
]
}
]'
Demonstrates how to assign a single Member to a Scope along with a Scope-specific role the Member will have for the target Scope.
For the context of this example, the following request will setup the instance with the needed starting conditions:
POST http://V1Host/V1Instance/api/asset
[
{
"from": "Member",
"where": {
"Name": "scopeMember1"
},
"execute": "Delete"
},
{
"AssetType": "Scope",
"Name": "Project for Members",
"Parent": "Scope:0",
"BeginDate": "2019-11-20T20:49:37.733Z"
},
{
"AssetType": "Member",
"Name": "scopeMember1",
"Password": "scopeMember1",
"Nickname": "scopeMember1",
"Username": "scopeMember1",
"DefaultRole": "Role.Name'Observer"
}
]
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"from": "Scope:1065",
"execute": {
"op": "AssignMemberWithRole",
"args": {
"Member": "Member:1066",
"Role": "Role:3",
"IsOwner": true
}
}
}
Expect a result similar to this:
{
"requestId": "fd835822-54f2-475b-91ee-28826be351a9",
"createdDate": "2019-11-20T20:49:37.8654392Z",
"completedDate": "2019-11-20T20:49:37.8784385Z",
"duration": "00:00:00.0129993",
"durationSeconds": 0.0129993,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [
"Scope:1065"
],
"count": 1
},
"commandFailures": {
"commands": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
assetsOperatedOn.oidTokens
array property contains a single scope token. This is because in this example we invoked the Scope.AssignMemberWithRole
operation once on the scope for a single member.Demonstrates how to use a single command to assign multiple Members to a Scope along with Scope-specific roles each Member will have for the target Scope.
For the context of this example, the following request will setup the instance with the needed starting conditions:
POST http://V1Host/V1Instance/api/asset
[
{
"from": "Member",
"filter": [
"Name='scopeListMember1','scopeListMember2'"
],
"execute": "Delete"
},
{
"AssetType": "Scope",
"Name": "Project for List of Members",
"Parent": "Scope:0",
"BeginDate": "2019-11-20T20:50:16.907Z"
},
{
"AssetType": "Member",
"Name": "scopeListMember1",
"Password": "scopeListMember1",
"Nickname": "scopeListMember1",
"Username": "scopeListMember1",
"DefaultRole": "Role.Name'Observer"
},
{
"AssetType": "Member",
"Name": "scopeListMember2",
"Password": "scopeListMember2",
"Nickname": "scopeListMember2",
"Username": "scopeListMember2",
"DefaultRole": "Role.Name'Observer"
}
]
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"from": "Scope:1070",
"execute": {
"op": "AssignMemberWithRole",
"list": [
{
"Member": "Member:1071",
"Role": "Role:3",
"IsOwner": true
},
{
"Member": "Member:1072",
"Role": "Role:7",
"IsOwner": false
}
]
}
}
Expect a result similar to this:
{
"requestId": "fee67e0a-5bc8-4997-a531-c78c875b3029",
"createdDate": "2019-11-20T20:50:17.1563425Z",
"completedDate": "2019-11-20T20:50:17.188342Z",
"duration": "00:00:00.0319995",
"durationSeconds": 0.0319995,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [
"Scope:1070",
"Scope:1070"
],
"count": 2
},
"commandFailures": {
"commands": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
assetsOperatedOn.oidTokens
array property contains the same token twice. This is because in this example we invoked the Scope.AssignMemberWithRole
operation on the same scope, passing different member oids each time.Demonstrates how to use a subquery to assign a single Member to a Scope along with a Scope-specific role the Member will have for the target Scope.
For the context of this example, the following request will setup the instance with the needed starting conditions:
POST http://V1Host/V1Instance/api/asset
[
{
"from": "Member",
"where": {
"Name": "scopeMember1"
},
"execute": "Delete"
},
{
"AssetType": "Scope",
"Name": "Project for Members",
"Parent": "Scope:0",
"BeginDate": "2019-11-21T16:56:22.438Z"
},
{
"AssetType": "Member",
"Name": "scopeMember1",
"Password": "scopeMember1",
"Nickname": "scopeMember1",
"Username": "scopeMember1",
"DefaultRole": "Role.Name'Observer"
}
]
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"from": "Scope:1117",
"execute": {
"op": "AssignMemberWithRole",
"args": {
"Member": {
"from": "Member",
"where": {
"Username": "scopeMember1"
}
},
"Role": {
"from": "Role",
"where": {
"Name": "Role.Name'Project Lead"
}
},
"IsOwner": true
}
}
}
args
property, the values for the Member
and the Role
properties are specified as subqueries. This makes it easier to create scripts which manipulate members and their project roles in the system using commonly shared values instead of having to separately query for oids first and then construct an HTTP request.Note that when using subqueries, only the very first query result will be used as the property value. This means you may need to use sorting to get the correct value if your subquery has a chance of returning more than one asset.
Expect a result similar to this:
{
"requestId": "2d1ac0a5-918d-4332-8d01-ba6607b8b8cd",
"createdDate": "2019-11-21T16:56:22.5630306Z",
"completedDate": "2019-11-21T16:56:22.589028Z",
"duration": "00:00:00.0259974",
"durationSeconds": 0.0259974,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [
"Scope:1117"
],
"count": 1
},
"commandFailures": {
"commands": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
assetsOperatedOn.oidTokens
array property contains a single scope token. This is because in this example we invoked the Scope.AssignMemberWithRole
operation once on the scope for a single member.Demonstrates how to assign a single scope to a member along with a scope-specific role the member will have for assigned scope.
For the context of this example, the following request will setup the instance with the needed starting conditions:
POST http://V1Host/V1Instance/api/asset
[
{
"from": "Member",
"filter": [
"Name='memberForSoloScope'"
],
"execute": "Delete"
},
{
"from": "Scope",
"filter": [
"Name='Solo project for Member.AssignToScopeWithRole'"
],
"execute": "Delete"
},
{
"AssetType": "Scope",
"Name": "Solo project for Member.AssignToScopeWithRole",
"Parent": "Scope:0",
"BeginDate": "2019-11-21T16:25:00.131Z"
},
{
"AssetType": "Member",
"Name": "memberForSoloScope",
"Password": "memberForSoloScope",
"Nickname": "memberForSoloScope",
"Username": "memberForSoloScope",
"DefaultRole": "Role.Name'Observer"
}
]
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"from": "Member:1102",
"execute": {
"op": "AssignToScopeWithRole",
"args": {
"Scope": "Scope:1101",
"Role": "Role:3",
"IsOwner": true
}
}
}
Expect a result similar to this:
{
"requestId": "2a85553c-06ac-4832-a93b-5f65045a416f",
"createdDate": "2019-11-21T16:25:00.5825599Z",
"completedDate": "2019-11-21T16:25:00.67756Z",
"duration": "00:00:00.0950001",
"durationSeconds": 0.09500009999999999,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [
"Member:1102"
],
"count": 1
},
"commandFailures": {
"commands": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
assetsOperatedOn.oidTokens
array property contains a single member token. This is because in this example we invoked the Member.AssignToScopeWithRole
operation once on the member for a single scope.Demonstrates how to assign multiple scopes to a member along with scope-specific roles the member will have for each of the assigned scopes.
For the context of this example, the following request will setup the instance with the needed starting conditions:
POST http://V1Host/V1Instance/api/asset
[
{
"from": "Member",
"filter": [
"Name='memberForScope1'"
],
"execute": "Delete"
},
{
"from": "Scope",
"filter": [
"Name='Project 1 for Member.AssignToScopeWithRole','Project 2 for Member.AssignToScopeWithRole'"
],
"execute": "Delete"
},
{
"AssetType": "Scope",
"Name": "Project 1 for Member.AssignToScopeWithRole",
"Parent": "Scope:0",
"BeginDate": "2019-11-20T20:56:06.561Z"
},
{
"AssetType": "Scope",
"Name": "Project 2 for Member.AssignToScopeWithRole",
"Parent": "Scope:0",
"BeginDate": "2019-11-20T20:56:06.561Z"
},
{
"AssetType": "Member",
"Name": "memberForScope1",
"Password": "memberForScope1",
"Nickname": "memberForScope1",
"Username": "memberForScope1",
"DefaultRole": "Role.Name'Observer"
}
]
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"from": "Member:1088",
"execute": {
"op": "AssignToScopeWithRole",
"list": [
{
"Scope": "Scope:1086",
"Role": "Role:3",
"IsOwner": true
},
{
"Scope": "Scope:1087",
"Role": "Role:7",
"IsOwner": false
}
]
}
}
Expect a result similar to this:
{
"requestId": "e08066c8-31fd-43f0-a313-523252793ff9",
"createdDate": "2019-11-20T20:56:06.8228258Z",
"completedDate": "2019-11-20T20:56:06.8408256Z",
"duration": "00:00:00.0179998",
"durationSeconds": 0.0179998,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [
"Member:1088",
"Member:1088"
],
"count": 2
},
"commandFailures": {
"commands": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
assetsOperatedOn.oidTokens
array property contains the same token twice. This is because in this example we invoked the Member.AssignToScopeWithRole
operation on the same member, passing different scope oids each time.Demonstrates how to use a subquery to assign a single scope to a member along with a scope-specific role the member will have for assigned scope.
For the context of this example, the following request will setup the instance with the needed starting conditions:
POST http://V1Host/V1Instance/api/asset
[
{
"from": "Member",
"filter": [
"Name='memberForSubqueryScope'"
],
"execute": "Delete"
},
{
"from": "Scope",
"filter": [
"Name='Subquery project for Member.AssignToScopeWithRole'"
],
"execute": "Delete"
},
{
"AssetType": "Scope",
"Name": "Subquery project for Member.AssignToScopeWithRole",
"Parent": "Scope:0",
"BeginDate": "2019-11-21T16:45:34.822Z"
},
{
"AssetType": "Member",
"Name": "memberForSubqueryScope",
"Password": "memberForSubqueryScope",
"Nickname": "memberForSubqueryScope",
"Username": "memberForSubqueryScope",
"DefaultRole": "Role.Name'Observer"
}
]
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"from": "Member:1114",
"execute": {
"op": "AssignToScopeWithRole",
"args": {
"Scope": {
"from": "Scope",
"where": {
"Name": "Subquery project for Member.AssignToScopeWithRole"
}
},
"Role": {
"from": "Role",
"where": {
"Name": "Role.Name'Project Lead"
}
},
"IsOwner": true
}
}
}
args
property, the values for the Scope
and the Role
properties are specified as subqueries. This makes it easier to create scripts which manipulate members and their project roles in the system using commonly shared values instead of having to separately query for oids first and then construct an HTTP request.Note that when using subqueries, only the very first query result will be used as the property value. This means you may need to use sorting to get the correct value if your subquery has a chance of returning more than one asset.
Expect a result similar to this:
{
"requestId": "3829e378-db9d-4bd7-b656-3edb195da6c5",
"createdDate": "2019-11-21T16:45:35.0078639Z",
"completedDate": "2019-11-21T16:45:35.0258636Z",
"duration": "00:00:00.0179997",
"durationSeconds": 0.0179997,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [
"Member:1114"
],
"count": 1
},
"commandFailures": {
"commands": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
assetsOperatedOn.oidTokens
array property contains a single member token. This is because in this example we invoked the Member.AssignToScopeWithRole
operation once on the member for a single scope.Demonstrates how the API will return a cascade of failures when an invalid Scope is specified for a top-level Epic that has a collection of Subs. The failure messages can be modified and resubmitted to the API to create the original request's Assets.
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"AssetType": "Epic",
"Scope": "Scope:9999",
"Name": "My Epic on a Scope that DOES NOT EXIST which will produce a cascade of four failures!",
"Subs": [
{
"AssetType": "Story",
"Name": "My Story",
"Children": [
{
"AssetType": "Test",
"Name": "My Test"
},
{
"AssetType": "Task",
"Name": "My Task"
}
]
}
]
}
Expect a result similar to this:
{
"requestId": "adffb44e-f026-4fd2-94e3-d3e6cc8a0f52",
"createdDate": "2019-11-06T20:01:08.0040847Z",
"completedDate": "2019-11-06T20:01:08.0525809Z",
"duration": "00:00:00.0484962",
"durationSeconds": 0.048496199999999996,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"commandFailures": {
"commands": [
{
"@839e420a-f395-48ff-a522-4d7c9c8ce37e": {
"AssetType": "Epic",
"Scope": "Scope:9999",
"Name": "My Epic on a Scope that DOES NOT EXIST which will produce a cascade of four failures!"
},
"error": {
"message": "Violation'Invalid'Epic.Scope",
"sourceCommandIndex": 0
}
},
{
"@bf084e75-1263-476f-af99-fa8153bf7ebd": {
"AssetType": "Story",
"Name": "My Story",
"#ContextOid": "@839e420a-f395-48ff-a522-4d7c9c8ce37e"
},
"error": {
"message": "Invalid OID token: @839e420a-f395-48ff-a522-4d7c9c8ce37e",
"sourceCommandIndex": 0
}
},
{
"@4622a696-c001-414d-8749-fd620fd6a284": {
"AssetType": "Test",
"Name": "My Test",
"#ContextOid": "@bf084e75-1263-476f-af99-fa8153bf7ebd"
},
"error": {
"message": "Invalid OID token: @bf084e75-1263-476f-af99-fa8153bf7ebd",
"sourceCommandIndex": 0
}
},
{
"@b92be85b-5039-4a84-93b7-e602bee7ab4b": {
"AssetType": "Task",
"Name": "My Task",
"#ContextOid": "@bf084e75-1263-476f-af99-fa8153bf7ebd"
},
"error": {
"message": "Invalid OID token: @bf084e75-1263-476f-af99-fa8153bf7ebd",
"sourceCommandIndex": 0
}
}
],
"count": 4
},
"queryResult": {
"results": [],
"count": -1
}
}
commandFailures.commands
property are in the form of complete commands. In this particular example, you would be able to edit the Scope
value to point to an actual scope and resubmit either the original payload that had the nested assets, or simply submit the array of four commands in the failure details. Since the descendant nodes have been auto-aliased by the server and linearized, they will get processed properly by reference when resubmitted. The special #ContextOid
keys that the server generated tell the server how to relate the descendant assets back to original hierarchy from the source command.sourceCommandIndex
property that identifies a zero-based index of the command that generated this error from your original payload. Because our original payload contained nested assets, each of these commands has 0
for this value.Demonstrates how the API will return a failure when you attempt to invoke an unknown attribute definition on an asset.
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"@user-alias": {
"from": "Scope",
"select": [
"MuddleBubble"
]
}
}
Expect a result similar to this:
{
"requestId": "9a4b517a-06a3-407f-9ff1-551e0343e382",
"createdDate": "2019-11-21T15:26:14.0465326Z",
"completedDate": "2019-11-21T15:26:14.0495334Z",
"duration": "00:00:00.0030008",
"durationSeconds": 0.0030007999999999996,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"commandFailures": {
"commands": [
{
"@user-alias": {
"from": "Scope",
"select": [
"MuddleBubble"
]
},
"error": {
"message": "Unknown AttributeDefinition: Scope.MuddleBubble",
"sourceCommandIndex": 0
}
}
],
"count": 1
},
"queryResult": {
"results": [],
"count": -1
}
}
commandFailures.commands
property is in the form of a complete command. In this example, you could correct the selected attribute name to reference a legitimate attribute that exists on the Scope asset type.Demonstrates how the API will return a failure when you attempt to invoke an unknown operation on an asset.
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"from": "Scope:0",
"execute": "NonexistentOperation"
}
Expect a result similar to this:
{
"requestId": "4b982452-b716-44ba-9445-a249b8adfb6c",
"createdDate": "2019-11-19T20:17:57.9370732Z",
"completedDate": "2019-11-19T20:17:57.9430751Z",
"duration": "00:00:00.0060019",
"durationSeconds": 0.0060019,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"commandFailures": {
"commands": [
{
"@a2811f5b-aa87-4ffc-8959-e9d343adfef9": {
"oid": "Scope:0",
"execute": {
"op": "NonexistentOperation",
"args": {}
}
},
"error": {
"message": "Unknown Operation 'Scope.NonexistentOperation'",
"sourceCommandIndex": 0
}
}
],
"count": 1
},
"queryResult": {
"results": [],
"count": -1
}
}
commandFailures.commands
property are in the form of complete commands. In this example, you could correct the operation name to reference a legitimate operation that exists on the Scope asset type.Demonstrates how the API will return a failure when you attempt to query for an unknown asset type.
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"@user-alias": {
"from": "Animal"
}
}
Expect a result similar to this:
{
"requestId": "82a33f29-2a19-496c-979f-8009e3c82983",
"createdDate": "2019-11-19T22:11:31.0308504Z",
"completedDate": "2019-11-19T22:11:31.0318466Z",
"duration": "00:00:00.0009962",
"durationSeconds": 0.0009962,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"commandFailures": {
"commands": [
{
"@user-alias": {
"from": "Animal"
},
"error": {
"message": "Unknown AssetType: Animal",
"sourceCommandIndex": 0
}
}
],
"count": 1
},
"queryResult": {
"results": [],
"count": -1
}
}
commandFailures.commands
property is in the form of a complete command. In this example, you could correct the asset type in the from
clause to referebce a legitimate asset type.Demonstrates how the API will return a failure when you attempt to query using a where clause referencing an attribute that is unknown on the target asset type.
The following request invokes the behavior:
POST http://V1Host/V1Instance/api/asset
{
"@user-alias": {
"from": "Scope",
"where": {
"MuddleBubble": "BubbleMuddle"
},
"select": [
"Name"
]
}
}
Expect a result similar to this:
{
"requestId": "2cc1e623-9dbe-474e-ac49-9774c8ba2c94",
"createdDate": "2019-11-19T22:29:09.2679473Z",
"completedDate": "2019-11-19T22:29:09.2689476Z",
"duration": "00:00:00.0010003",
"durationSeconds": 0.0010003,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [],
"count": 0
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"commandFailures": {
"commands": [
{
"@user-alias": {
"from": "Scope",
"where": {
"MuddleBubble": "BubbleMuddle"
},
"select": [
"Name"
]
},
"error": {
"message": "Invalid QueryFilter2 token MuddleBubble='BubbleMuddle'",
"sourceCommandIndex": 0
}
}
],
"count": 1
},
"queryResult": {
"results": [],
"count": -1
}
}
commandFailures.commands
property is in the form of a complete command. In this example, you could correct the where clause to refer to a legitimate attriute definition for the target asset type.Webhook subscriptions allow you to define which events in VersionOne can fire webhooks.
By supplying a URL to an external system and a list of events that should trigger a webhook, you can inform that external system any time the event occurs in VersionOne.
You are able to create and edit webhooks to be as broad or specific as you'd like. For example, you can use webhooks to receive an HTTP request to the external system any time any Story Status changes, or any time a Story in Project A that is owned by Susan has a Status change.
By configuring the event with from
, filter
, with
, and select
, you can get very specific about which changes you want to be notified about in VersionOne.
The external system can be configured by adding a url
to the webhook subscription.
If the external system requires an authorization token, you can add it as an authorizationHeader
. This field will be sent as the HTTP Authorization Header each time an event triggers the webhook to be sent.
The webhookId
will be helpful for you to query or update this webhook later, so make it meaningful and unique, if possible.
Add a short description
to keep track of what this webhook is used for, such as where this webhook will be sent and why.
VersionOne keeps track of any time an Asset is created, or updated. This allows us to create powerful webhook events modeled around Assets and their Attributes. Each event has a type
from one of the following:
If I want a webhook triggered any time a Story changes, my event would look like:
{
"type": "AssetChanged",
"from": "Story"
}
You can also include an array of attributes
that will allow you to specify which attributes of the asset you'd like to trigger webhooks. Omitting the attributes
field will notify you of any changes to the asset.
If I want a webhook triggered any time a Story Status changes, my event would look like:
{
"type": "AssetChanged",
"from": "Story",
"attributes": ["Status"]
}
We can enhance our event even more by filtering out Stories that don't meet a specified criteria using the filter
and with
fields. If I only want to know about Story Status changes for Stories in my Project, the event would look like:
{
"type": "AssetChanged",
"from": "Story",
"attributes": ["Status"],
"filter": ["Scope=$Scope"],
"with": {
"$Scope": "Scope:0"
},
"userContext": "Memeber:1002"
}
Many assets in VersionOne are secured by their relationship to a Scope (Project) limiting a member's ability to access a resource. We can configure the webhook to query on behalf of a sepcific user using the userContext
field. Without this field, all assets independent of their relationship to Scope can produce webhooks. In the following case, only Status changes to Stories visible to Member 1002 will produce webhook events.
{
"type": "AssetChanged",
"from": "Story",
"attributes": ["Status"],
"userContext": "Memeber:1002"
}
When the webhook is fired, we might want details about the Story whose Status changed. You can use the select
field to pick which of the Story's Attributes will be included in addition to the Asset's Oid. For example, if you want to know the Name of the Story and the Name of each of Owner of the Story, your event would look like:
{
"type": "AssetChanged",
"from": "Story",
"attribute": ["Status"],
"filter": ["Scope=$Scope"],
"with": {
"$Scope": "Scope:0"
},
"select": ["Name", "Owners.Name"]
}
The webhook itself will include many details about the event that has occurred within VersionOne.
In each event object, the webhook will include the webhookId
, which will allow the external system to identify which webhook subscription the response is associated with. It will also include a sequenceId
, which will allow the system to determine the order in which the events occurred, along with the timestamp. This means your external system may receive the events out of order, but you can used the sequence id to guarantee that the order is accurate!
The webhook will also include information about the instigator, or the user who enacted the change in VersionOne that triggered the webhook, such as their name, role, email, and more.
Next, the webhook contains the target asset and changes, which will specify the asset on which the changes were made, as well as what those changes were.
The final section is the snapshot, which includes the information requested in the select
field of the event type definition in your webhook subscription. Say you want webhooks fired when a Story Status changes, but when you receive the webhook you want to know specific details about the Story whose Status changed. By including attributes of the Story in your select
, you can receive that projection of the Story in the webhook snapshot
in the same shape as the results of the ~/api/query.v1
request.
{
"events": [
{
"webhookId": "YYY",
"sequenceId": 1,
"eventType": "AssetChanged",
"timestamp": "UTC timestamp",
"instigator": {
"_oid": "Member:20",
"href": "https://V1Host/V1Instance/assetdetail.v1?oid=Member:20",
"name": "Administrator",
"nickName": "Admin",
"email": "admin@admin.com",
"role": "Role:2",
"avatar": "https://V1Host/V1Instance/Image.mvc/Show?imageOid=Image:192923"
},
"targetAsset": {
"_oid": "Story:123:456",
"assetType": "Story",
"href": "https://V1Host/V1Instance/assetdetail.v1?oid=Story:123"
},
"changes": [
{
"name": "Name",
"old": "Original Name",
"new": "New Name",
"act": "Set"
},
{
"name": "Owners",
"new": "Member:20",
"act": "Added"
}
],
"snapshot": [
{
"_oid": "Story:123",
"Owners.Name": [
"Administrator"
],
"Owners.ID": [
{ "_oid": "Member:20" }
],
"SubsAndMe.Owners.Name": [
"Administrator"
]
}
]
}
]
}
Create a webhook subscription.
POST http://V1Host/V1Instance/api/webhook
{
"url": "https://externalsystem.com",
"authroizationHeader": "Optional HTTP Authorization Header to send with each webhook",
"webhookId": "Webhook identifier",
"enabled": true,
"description": "Short description of the webhook subscription",
"eventTypes": [],
}
{
"id": "336d997f-d9fa-4612-80e8-9f41a4b41352",
"webhookId": "Webhook indentifier",
"url": "https://externalsystem.com",
"description": "Short description of the webhook subscription",
"enabled": true,
"eventTypes": [],
"lastResponseAt": "0001-01-01T00:00:00Z",
"retryCount": 0,
"createdAt": "2018-09-27T20:28:41.3829451Z",
"updatedAt": "2018-09-27T20:28:41.3829451Z",
"createdBy": "Member:20"
}
Update a webhook subscription by id.
POST http://V1Host/V1Instance/api/webhook/:id
{
"url": "https://newurl.com",
"enabled": false,
"description": "Updated description of the webhook subscription",
"eventTypes": [],
}
{
"id": "336d997f-d9fa-4612-80e8-9f41a4b41352",
"webhookId": "Webhook indentifier",
"url": "https://newurl.com",
"description": "Updated description of the webhook subscription",
"enabled": false,
"eventTypes": [],
"lastResponseAt": "0001-01-01T00:00:00Z",
"retryCount": 0,
"createdAt": "2018-09-27T20:28:41.3829451Z",
"updatedAt": "2018-09-27T20:28:41.3829451Z",
"createdBy": "Member:20"
}
Retrieve a paged list of existing webhook subscriptions. By default, a query of existing webhook subscriptions will start with the first subscription and show 25 per page, but that can be changed in the request.
GET http://V1Host/V1Instance/api/webhook?page=pageSize,pageStart
{
"total": 1,
"pageSize": 25,
"pageStart": 0,
"_type": "WebhookSubscription",
"results": [
{
"id": "336d997f-d9fa-4612-80e8-9f41a4b41352",
"webhookId": "Webhook indentifier",
"url": "https://matchedUrl.com",
"description": "Short description of the webhook subscription",
"enabled": true,
"eventTypes": [],
"lastResponseAt": "0001-01-01T00:00:00Z",
"retryCount": 0,
"createdAt": "2018-09-27T20:28:41.3829451Z",
"updatedAt": "2018-09-27T20:28:41.3829451Z",
"createdBy": "Member:20"
}
]
}
Delete a webhook subscription by id.
POST http://V1Host/V1Instance/api/webhook/delete/:id
{
"id": "336d997f-d9fa-4612-80e8-9f41a4b41352",
"webhookId": "Webhook indentifier",
"url": "https://externalsystem.com",
"description": "Short description of the webhook subscription",
"enabled": true,
"eventTypes": [],
"lastResponseAt": "0001-01-01T00:00:00Z",
"retryCount": 0,
"createdAt": "2018-09-27T20:28:41.3829451Z",
"updatedAt": "2018-09-27T20:28:41.3829451Z",
"createdBy": "Member:20"
}
Retrieve a list of the 20 most recent webhook receipts by id.
This is feature is useful for troubleshooting webhooks that don't seem to be working. The receipts will contain useful information to allow you to determine if your webhooks are being sent, if they are received, how the external system is responding, and additional information about the webhook, such as the timestamp, retry count, or if it included an Authorization Header.
GET http://V1Host/V1Instance/api/webhook/status/:id
[
{
"subscriptionId": "b3ff4f99-1436-4989-96a5-cb43341fc9e4",
"hasAuthorizationHeader": true,
"url": "https://externalsystem.com",
"response": "Optional Response Information",
"headers": {
"transfer-Encoding": "chunked",
"connection": "keep-alive",
"x-Request-Id": "837ea952-2c56-4470-aa89-3f996ad1b65c",
"x-Token-Id": "46054f26-412f-4772-a1d6-48648421fbc3",
"x-RateLimit-Limit": "30",
"x-RateLimit-Remaining": "26",
"cache-Control": "no-cache",
"content-Type": "text/plain; charset=UTF-8",
"date": "Fri, 07 Dec 2018 19:54:53 GMT",
"server": "nginx/1.10.3"
},
"status": 500,
"timeStamp": "2018-12-07T19:54:09.59Z",
"retryCount": 3,
"wasReceived": false
}
]
First and foremost Tags are values that exist on most BaseAssets. Tags exist only in the context of the Assets they are added to. This means adding (and removing) tags for an Asset should be done via rest-1.v1/Data.
As of now Tags have been exposed on the following Assets via the AttributeDefinition TaggedWith
This endpoint provides read-only access to the activity streams for assets and entities within VersionOne.
Query Params | Meaning |
---|---|
anchorDate | Datetime to use in selecting the returned activity. Defaults to 'now'. |
direction | 'Forward' or 'Back'. Controls whether activity earlier or later than the anchor date will be returned. Defaults to 'Back'. |
maxCount | Number of activities to return. Defaults to 25. |
verbs | A comma-separated list of verbs to act as a filter on the activity returned. By default, no filter is applied. |
Valid verbs are:
View the activities for asset with the given OidToken
GET http://V1Host/V1Instance/api/ActivityStream/:OidToken
[
{
"body": {
"actor": {
"id": "Member:1065",
"assetType": "Member",
"displayName": "Tammy Coder",
"username": "tammy",
"email": "tammy.coder@company.com",
"avatar": "Image:1936"
},
"verb": "Updated",
"object": {
"id": "Story:1220",
"assetType": "Story",
"displayName": "Delete RMA",
"number": "S-01047",
"assetState": "Active",
"scope": "Scope:1258"
},
"time": "2014-04-22T14:11:01.1175003Z",
"summary": "Tammy Coder Updated Story 'Delete RMA'",
"provider": {
"stream": "MetaStream",
"commitSeq": "237",
"commitId": "01a7b036-01f9-47a1-86b0-17a9c4c25544"
},
"target": [
{
"name": "Timebox",
"newValue": {
"id": "Timebox:1785",
"assetType": "Timebox",
"displayName": "Sprint 6",
"assetState": "Future"
},
"oldValue": "",
"verb": "Set",
"summary": "Timebox was Set to 'Sprint 6'"
},
{
"name": "Estimate",
"newValue": "3.00",
"oldValue": "2.00",
"verb": "Set",
"summary": "Estimate was Set to '3.00'"
},
{
"name": "Priority",
"newValue": "Medium",
"oldValue": "High",
"verb": "Set",
"summary": "Priority was Set to 'Medium'"
},
{
"name": "Risk",
"newValue": "Low",
"oldValue": "High",
"verb": "Set",
"summary": "Risk was Set to 'Low'"
}
]
}
}
]
curl "https://V1Host/V1Instance/api/ActivityStream/<OidToken>"
-H "Authorization: Bearer <access-token>"
-H "Accept: application/json"
USE: ~/api/asset
Read only api that allows retrieval of arbitrarily nested master/detail and hierarchical relationships. (For example, you can retrieve all the Schedules
in a Scope
, all the Iterations
in the Schedules
, and all the Workitems
in the iterations, all in one go.)
An arbitrary number of independent queries can be executed in one HTTP round-trip.
Key | Meaning |
---|---|
from | Every query must have a "from" key with a string value naming the Asset Type to query. All other keys are optional. |
select | In order to retrieve any data, a selection list of the desired attributes is required. These attributes are in the VersionOne Selection Token syntax. Scalar attributes, relations, multivalued attributes, and traversal through a relation to all of the above are suppported. |
filter | the filter key is a sequence of VersionOne filter tokens as strings. Filter tokens name an attribute (possible traversing relations) and give a comparison operator and either a comparison value or a context variable that will be defined in the with clause. |
with | You may define variables in your filter tokens that will be filled via the with mapping. This can allow parameterization and alleviate quoting issues. with is a mapping of variable names to their values, and is applied over the entire query. |
where | the where key takes a value that is also a mapping. The keys of the mapping are taken as selection tokens, and the values of the mapping are taken as the value to compare against in an "equal" comparison. |
sorting | Any selection token can be used to sort the results. include a "sort" key with a value that is a list of selection tokens to sort by. Tokens can be preceded by + or - to indicate ascending or descending sort. |
grouping | You may group a set of assets by a related-to value. For example, stories can be grouped by status. The queried assets are returned in the _children element of the grouped-on asset. |
find | provides basic substring matching |
findin | list of selected attributes to search in |
page | You may limit the number of returned results, or start retrieving results starting from a particular index. Results are returned in ID order if no other sorting is applied, so paging will always be deterministic |
asof | Historical data is kept for all assets, and you may query for the state of assets "as of" a particular point in time. The asof value is a string with a timestamp in ISO format. |
Data is returned as a sequence of result sets. Each result set is a sequence that contains the results from one query mapping. Each result is a JSON object with fields for the selections you defined in the query mapping.
Historical data is kept for all assets, and you may query for the state of assets "as of" a particular point in time. The asof value is a string with a timestamp in ISO format.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name",
"ChangeDateUTC"
],
"asof": "2016-01-01"
}
[
[
{
"_oid": "Story:1234:1265",
"Name": "Name",
"ChangeDateUTC": "2017-09-06T15:06:26.7530000Z",
},
{
"_oid": "Story:1234:1266",
"Name": "Updated Name",
"ChangeDateUTC": "2017-09-06T17:06:26.7530000Z",
}
]
]
curl "https://V1Host/V1Instance/query.v1"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name",
"ChangeDateUTC"
],
"asof": "2016-01-01"
}'
Filter on a collection of filter tokens which apply comparison operators to attributes and values.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name",
"Owners.@Count"
],
"filter": [
"Owners.@Count>'2'"
]
}
[
[
{
"_oid": "Story:1234",
"Name": "Story Two",
"Owners.@Count": "3"
},
{
"_oid": "Story:4567",
"Name": "Story Two",
"Owners.@Count": "1"
}
]
]
curl "https://V1Host/V1Instance/query.v1"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name",
"Owners.@Count"
],
"filter": [
"Owners.@Count>'2'"
]
}'
find
contains a search term and findin
specifies which attributes to locate the term within.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name"
],
"find": "As a user",
"findin": [
"Name"
]
}
[
[
{
"_oid": "Story:1234",
"Name": "As a user I can do X"
},
{
"_oid": "Story:4567",
"Name": "As a user I can do Y"
}
]
]
curl "https://V1Host/V1Instance/query.v1"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name"
],
"find": "As a user",
"findin": [
"Name"
]
}'
You may group a set of assets by a related-to value. For example, stories can be grouped by status. The queried assets are returned in the _children element of the grouped-on asset.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name",
"Number"
],
"group": [
{
"from": "Status",
"select": [
"Name"
]
}
]
}
[
[
{
"_oid": "NULL",
"Name": null,
"_children": [
{
"_oid": "Story:1215",
"Name": "User Interface Story",
"Number": "S-01054"
}
]
},
{
"_oid": "StoryStatus:133",
"Name": "Future",
"_children": [
{
"_oid": "Story:1153",
"Name": "Partnerships",
"Number": "S-01009"
}
]
},
{
"_oid": "StoryStatus:134",
"Name": "In Progress",
"_children": [
{
"_oid": "Story:1194",
"Name": "Enter RMA",
"Number": "S-01038"
},
{
"_oid": "Story:1196",
"Name": "Add Shipping Notes",
"Number": "S-01039"
}
]
}
]
]
curl "https://V1Host/V1Instance/query.v1"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name",
"Number"
],
"group": [
{
"from": "Status",
"select": [
"Name"
]
}
]
}'
You may limit the number of returned results, or start retrieving results starting from a particular index.
Results are returned in ID order if no other sorting is applied, so paging will always be deterministic.
Paging only works for the topmost query. You cannot limit/page the results of subselections.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name"
],
"page": {
"start": "0",
"size": "5"
}
}
[
[
{
"_oid": "Story:1234",
"Name": "Story One"
},
{
"_oid": "Story:2345",
"Name": "Story Two"
},
{
"_oid": "Story:3456",
"Name": "Story Three"
},
{
"_oid": "Story:4567",
"Name": "Story Four"
},
{
"_oid": "Story:5678",
"Name": "No more than page size of 5!"
}
]
]
curl "https://V1Host/V1Instance/query.v1"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name"
],
"page" {
"start": "0",
"size": "5"
}
}'
Retrieve only the attributes you need from an asset.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name",
"Scope.Name"
]
}
[
[
{
"_oid": "Story:1234",
"Name": "Their Story",
"Scope.Name": "Project A"
},
{
"_oid": "Story:5678",
"Name": "My Story",
"Scope.Name": "Project B"
}
]
]
curl "https://V1Host/V1Instance/query.v1"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name",
{
"from": "Owners",
"select": [
"Name",
"Avatar.Content"
]
}
]
}'
Sort by selection tokens with ascending +
or descending -
order.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name",
"Estimate"
],
"sort": [
"+Name",
"-Estimate"
]
}
[
[
{
"_oid": "Story:1234",
"Name": "Story A",
"Estimate": "3"
},
{
"_oid": "Story:1234",
"Name": "Story A",
"Estimate": "1"
},
{
"_oid": "Story:4567",
"Name": "Story B",
"Estimate": "5"
}
]
]
curl "https://V1Host/V1Instance/query.v1"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name",
"Estimate"
],
"sort": [
"+Name",
"-Estimate"
]
}'
Sub select a relation.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name",
"Owners.@Count",
{
"from": "Owners",
"select": [
"Name",
"Avatar.Content"
]
}
]
}
[
[
{
"_oid": "Story:1234",
"Name": "Story Name",
"Owners.@Count": "2",
"Owners": [
{
"_oid": "Member:1234",
"Name": "Andre Agile",
"Avatar.Content": "iVBORw0KGgoAAAANSUh/ORK5CYII="
},
{
"_oid": "Member:2345",
"Name": "Alice Agility",
"Avatar.Content": "/9j/4AAQSkZJRgABAQEAYAjlr2P/2Q=="
}
]
}
]
]
curl "https://V1Host/V1Instance/api/asset"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name",
"Owners.@Count",
{
"from": "Owners",
"select": [
"Name",
"Avatar.Content"
]
}
]
}'
the where key takes a value that is also a mapping. The keys of the mapping are taken as selection tokens, and the values of the mapping are taken as the value to compare against in an "equal" comparison.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name"
],
"where": {
"Scope": "Scope:1234"
}
}
[
[
{
"_oid": "Story:1234",
"Name": "Story Name"
}
]
]
curl "https://V1Host/V1Instance/query.v1"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name"
],
"where": {
"Scope": "Scope:1234"
}
}'
Provide context to where
clauses or filter
with variables.
POST http://V1Host/V1Instance/query.v1
{
"from": "Story",
"select": [
"Name"
],
"filter": [
"Name=$myName"
],
"where": {
"Scope": "$myScope"
},
"with": {
"$myScope": "Scope:1234",
"$myName": "Alice Agility"
}
}
[
[
{
"_oid": "Story:1234",
"Name": "Story Name"
}
]
]
curl "https://V1Host/V1Instance/query.v1"
-H "Authorization: Bearer <access-token>"
-H "Content-Type: application/json"
-H "Accept: application/json"
--request POST
--data '{
"from": "Story",
"select": [
"Name"
],
"filter": [
"Name=$myName"
],
"where": {
"Scope": "$myScope"
},
"with": {
"$myScope": "Scope:1234",
"$myName": "Alice Agility"
}
}'
USE: ~/api/asset
This endpoint provides read, write, and update access to assets. This endpoint queries for simple or complex sets of information, updates information, and executes system-defined operations.
Query Params | Meaning |
---|---|
asOf | Use the asof query parameter to retrieve data as it existed at some point in time. |
filter | The filter parameter filters results to a subset that meet specific criteria. Whenever possible, use where or filter to explicitly choose specific assets, thereby reducing the load put on the application |
findin | Used in conjunction with the find parameter, findin specifies the attributes to check for the find substring. The findin parameter is optional. If omitted, a base set of attributes will be searched. This free text search is relatively expensive for VersionOne, so when the exact contents of a field should be matched, use the where parameter instead. |
from | Used in conjunction with the find parameter, findin specifies the attributes to check for the find substring. The findin parameter is optional. If omitted, a base set of attributes will be searched. This free text search is relatively expensive for VersionOne, so when the exact contents of a field should be matched, use the where parameter instead. |
group | The group parameter organizes results by value within an attribute. For example, stories can be grouped by status. |
op | The Operation op parameter calls an action for a single asset. For example, to delete an asset you must execute the Delete operation on the target asset. When executing an operation, a request must be an HTTP POST. |
page | Since some results from a query may be very large, you may limit the number of returned results or start retrieving results starting from a particular index. Results are returned in ID order if no other sorting is applied, so paging will always be deterministic. The page parameter specifies how many assets you want to retrieve and where to start in the list of assets. The page start represents the number of items from which to start and is zero indexed. It is an item count, not a page count. The page size is the maximum number of items to return on a page. For example if you have 100 assets and want to see the first 10, you would use a page start of 0, and a page size of 10. To retrieve the second page simply ask for a page start of 10 with a page size of 10, and so on. |
select | Without the select parameter, queries return a default set of attributes. The select parameter specifies which attributes to provide in the response. Whenever possible, use select to explicitly choose specific attributes, thereby reducing the load put on the application. |
sort | Any attribute definition can be used to sort the results of a query. Tokens can be preceded by + or - to indicate ascending or descending sort respectively. |
where | Without the where parameter, queries return the entire set of from assets. The where parameter filters the results to a subset that meet specific criteria. Whenever possible, use where or filter to explicitly choose specific assets, thereby reducing the load put on the application. |
with | Without the where parameter, queries return the entire set of from assets. The where parameter filters the results to a subset that meet specific criteria. Whenever possible, use where or filter to explicitly choose specific assets, thereby reducing the load put on the application. |
When requesting more than a single asset, the assets node helps navigate over the set of assets. The attributes total
, pageSize
, and pageStart
can be used to navigate through a large set.
The Asset node has an href
attribute containing the URL path used to retrieve this asset. The asset node has an id
attribute with the OID Token for this asset.
Name
refers to an Attribute Definition.
Name
refers to an Attribute Definition. Contains another asset node with an idref
to the OID Token of the referenced asset.
Both creating and updating assets via rest-1.v1 has a POST body structured with a collection of attributes. When creating, it can contain Attributes that will exist on the new asset, and when updating it can contain Attributes that will modify an existing Asset.
The keys are valid Attribute names for a given Asset. The value of each key is valid based on the following:
Name
:{
"value": "New Name",
"act": "set"
}
Scope
:{
"value": "Scope:0",
"act": "set"
}
ChangeSets
take an array. Each element of the array specifies an asset to add or remove from the relation and have the shape:[
{ "idref": "<OidToken>", "act": "add" }
{ "idref": "<OidToken>", "act": "remove" }
]
Update attributes a specific asset
POST http://V1Host/V1Instance/rest-1.v1/Data/:AssetType
{
"Attributes":{
"Name":{
"value":"New Name",
"act":"set"
},
"Scope":{
"value":"Scope:123",
"act":"set"
},
"ChangeSets": {
"value": [
{
"idref":"ChangeSet:123",
"act":"add"
},
{
"idref":"ChangeSet:789",
"act":"remove"
}
]
}
}
}
{
"_type": "Asset",
"href": "/V1Instance/rest-1.v1/Data/Story/4462/4631",
"id": "Story:4462:4631",
"Attributes": {
"Name": {
"_type": "Attribute",
"name": "Name",
"value": "New Name"
},
"Scope": {
"_type": "Relation",
"name": "Scope",
"value": {
"_type": "Asset",
"href": "/V1Instance/rest-1.v1/Data/Scope/0",
"idref": "Scope:0"
}
},
"ChangeSets": {
"_type": "Relation",
"name": "ChangeSets",
"value": [
{
"_type": "Asset",
"href": "/V1Instance/rest-1.v1/Data/ChangeSet/123",
"idref": "ChangeSet:123"
}
]
}
}
}
curl "http://V1Host/V1Instance/rest-1.v1/Data/Story"
-H "Authorization: Bearer <access-token>"
-H "Accept: application/json"
-H "Content-type: application/json"
--request POST
--data '{
"Attributes":{
"Name":{
"value":"New Name",
"act":"set"
},
"Scope":{
"value":"Scope:123",
"act":"set"
},
"ChangeSets":[
{
"idref":"ChangeSet:123",
"act":"add"
}
]
}
}'
Update attributes of a specific asset
POST http://V1Host/V1Instance/rest-1.v1/Data/:AssetType/:OidToken
{
"Attributes":{
"Name":{
"value":"Updated Name",
"act":"set"
},
"Scope":{
"value":"Scope:123",
"act":"set"
},
"ChangeSets":[
{
"idref":"ChangeSet:123",
"act":"remove"
},
{
"idref":"ChangeSet:987",
"act":"add"
}
]
}
}
{
"_type": "Assets",
"total": 13768,
"pageSize": 5,
"pageStart": 0,
"Assets": [
{
"_type": "Asset",
"href": "/V1Instance/rest-1.v1/Data/Story/1234",
"id": "Story:1432",
"Attributes": {
"Name": {
"_type": "Attribute",
"name": "Name",
"value": "Story Name"
},
"Number": {
"_type": "Attribute",
"name": "Number",
"value": "S-1001"
},
"Super": {
"_type": "Attribute",
"name": "Super",
"value": "Epic:1234"
}
}
}
]
}
curl "http://V1Host/V1Instance/rest-1.v1/Data/Story/123"
-H "Authorization: Bearer <access-token>"
-H "Accept: application/json"
-H "Content-type: application/json"
--request POST
--data '{
"Attributes":{
"Name":{
"value":"Updated Name",
"act":"set"
},
"Scope":{
"value":"Scope:123",
"act":"set"
},
"ChangeSets":[
{
"idref":"ChangeSet:123",
"act":"add"
},
{
"idref":"ChangeSet:987",
"act":"remove"
}
]
}
}'
Query for assets of a specific asset type.
GET http://V1Host/V1Instance/rest-1.v1/Data/:AssetType
{
"_type": "Assets",
"total": 13768,
"pageSize": 5,
"pageStart": 0,
"Assets": [
{
"_type": "Asset",
"href": "/V1Instance/rest-1.v1/Data/Story/1234",
"id": "Story:1432",
"Attributes": {
"Name": {
"_type": "Attribute",
"name": "Name",
"value": "Story Name"
},
"Number": {
"_type": "Attribute",
"name": "Number",
"value": "S-1001"
},
"Super": {
"_type": "Attribute",
"name": "Super",
"value": "Epic:1234"
}
}
}
]
}
curl "https://V1Host/V1Instance/rest-1.v1/Data/<AssetType>"
-H "Authorization: Bearer <access-token>"
-H "Accept: application/json"
Execute an operation on a single asset
POST http://V1Host/V1Instance/rest-1.v1/Data/:AssetType/:OidToken?op=<operationName>
{
"Attributes":{
"Name":{
"value":"Updated Name",
"act":"set"
},
"Scope":{
"value":"Scope:123",
"act":"set"
},
"ChangeSets":[
{
"idref":"ChangeSet:123",
"act":"remove"
},
{
"idref":"ChangeSet:987",
"act":"add"
}
]
}
}
{
"_type": "Assets",
"total": 13768,
"pageSize": 5,
"pageStart": 0,
"Assets": [
{
"_type": "Asset",
"href": "/V1Instance/rest-1.v1/Data/Story/1234",
"id": "Story:1432",
"Attributes": {
"Name": {
"_type": "Attribute",
"name": "Name",
"value": "Story Name"
},
"Number": {
"_type": "Attribute",
"name": "Number",
"value": "S-1001"
},
"Super": {
"_type": "Attribute",
"name": "Super",
"value": "Epic:1234"
}
}
}
]
}
curl "http://V1Host/V1Instance/rest-1.v1/Data/Story/123?op=Close"
-H "Authorization: Bearer <access-token>"
-H "Accept: application/json"
--request POST
This endpoint provides localization and allows a client to retrieve the suggested localization of multiple strings. Often other VersionOne endpoints will return unlocalized strings such as suggested names or error messages. These unlocalized strings may be passed to loc-2.v1 which will attempt to translate the strings into locale specific strings returned as a JSON object with key-value pairs for each translation.
Retrieve the localized names of the <AssetType>
s requested`.
GET http://V1Host/V1Instance/loc-2.v1?[<AssetType>,<AssetType>]
{
"Scope": "Project",
"Timebox": "Sprint"
}
curl "https://V1Host/V1Instance/loc-2.v1?[Scope,Timebox]"
-H "Authorization: Bearer <access-token>"
-H "Accept: application/json"
Retrieve the localized names of the <AttributeDefinition>
s requested`.
GET http://V1Host/V1Instance/loc-2.v1?[<AttributeDefinition>,<AttributeDefinition>]
{
"AttributeDefinition'Name'Story": "Title",
"AttributeDefinition'Description'Story": "Description"
}
curl "https://V1Host/V1Instance/loc-2.v1?[AttributeDefinition'Name'Story,AttributeDefinition'Description'Story]"
-H "Authorization: Bearer <access-token>"
-H "Accept: application/json"