The new DoneDone: More about the new API

As mentioned in an earlier blog post, the DoneDone API is changing. We’ve just released the new implementation to everyone who has opted in to preview the new version; if you haven’t yet and would like a sneak peek at the new system and especially the new API, contact us at accounts[at]mydonedone.com, noting your current account’s subdomain and your account owner’s email address if you’d like us to set you up with an account.

Though the new API is mostly complete and has been tested internally, we’re still ironing out all of the kinks so things may not quite work perfectly for the next few days; please bear with us until we get everything finalized. With that said, this should give those that need to rewrite any of their applications that integrated with the old API the head start that they’ll need.

We’ll also be releasing a .NET client library soon for those of you on that platform.

Without further ado, here are the implementation details you need to get started.

Enable the API

You’ll need to enable the API for any projects you’d like to use with the API.
Enable the API

Security

To make any calls to the API, you’ll have to provide your username and API Token (or password) via an HTTP Basic authentication header. This will look something like this:

 Authorization: Basic {XXXXXX} 

Where {XXXXXX} is your Base64 encoded username:api token or username:password. Since all traffic goes over SSL, your credentials are safe.

All requests are made to: https://{youraccountdomain}.mydonedone.com/IssueTracker/API/{MethodName}/{parameters}

Methods

> Method: Get all Projects you have access to with the API enabled

URL: [GET] /Projects/{load_with_issues}

Note:  The parameter load_with_issues is optional. If provided, it must be ‘true’ or ‘false’ (without single quotes). Passing true will deep load all of the projects as well as all of their active issues. It is a potentially heavy call, so be careful using it. 


Example Response:  

[
   {
      "ID":123,
      "Name":"First Project",
      "Issues": null
   },
   {
      "ID":456,
      "Name":"Proj 2",
      "Issues": null
   }
]

> Method: Get all Priority Levels

URL: [GET] /PriorityLevels

Example Response:

[
   {
      "ID":1,
      "Value":"Low"
   },
   {
      "ID":2,
      "Value":"Medium"
   },
   {
      "ID":3,
      "Value":"High"
   },
   {
      "ID":4,
      "Value":"Critical"
   }
]

> Method: Get all People in a Project

URL: [GET] /PeopleInProject/{project_id}

Example Response:

[
   {
      "ID":1,
      "Value":"Ka Wai Cheung"
   },
   {
      "ID":2,
      "Value":"Mustafa Shabib"
   }
]

> Method: Get all Issues in a Project

URL: [GET] /IssuesInProject/{project_id}

Example Response:

[
   {
      "PriorityLevel":"Low",
      "State":"Open",
      "LastUpdatedDate":"/Date(1314996892513)/",
      "LastViewedDate":null,
      "CreateDate":"/Date(1314996892513)/",
      "Title":"Test for API",
      "OrderNumber":536,
      "ProjectID":26,
      "Tester":{
         "ID":157,
         "Value":"Tester's Name"
      },
      "Resolver":{
         "ID":63,
         "Value":"Resolver's Name"
      },
      "Creator":{
         "ID":26,
         "Value":"Ka Wai Cheung"
      }
   }
]

> Method: Does an Issue Exist?

URL: [GET] /DoesIssueExist/{project_id}/{issue_id}

Example Response:

{
   "IssueExists": true
}

> Method: List of Allowed Statuses An Issue Can Transition To

URL:  [GET] /PotentialStatusesForIssue/{project_id}/{issue_id}

Note:  If you are an admin, you’ll get both all allowed statuses as well as ALL statuses back from the server

Example Response:

{
   "PotentiallyAllowedStatusesForIssue":[
      {
         "ID":13,
         "Value":"In progress"
      },
      {
         "ID":14,
         "Value":"Not an issue"
      },
      {
         "ID":15,
         "Value":"Not reproducible"
      },
      {
         "ID":16,
         "Value":"Missing information"
      },
      {
         "ID":19,
         "Value":"Ready for retest"
      },
      {
         "ID":21,
         "Value":"Closed"
      }
   ],
   "AllStatusesSinceYouAreAnAdmin":[
      {
         "ID":12,
         "Value":"Open"
      },
      {
         "ID":13,
         "Value":"In progress"
      },
      {
         "ID":14,
         "Value":"Not an issue"
      },
      {
         "ID":15,
         "Value":"Not reproducible"
      },
      {
         "ID":16,
         "Value":"Missing information"
      },
      {
         "ID":17,
         "Value":"Pushed back"
      },
      {
         "ID":18,
         "Value":"Ready for next release"
      },
      {
         "ID":19,
         "Value":"Ready for retest"
      },
      {
         "ID":20,
         "Value":"Fix not confirmed"
      },
      {
         "ID":21,
         "Value":"Closed"
      }
   ]
}

> Method: Issue Details

URL: [GET] /Issue/{project_id}/{issue_id}

Note: You can use this to check if an issue exists as well, since it will return a 404 if the issue does not exist.

Example Response:

{
   "Title":"Test for API",
   "ProjectTitle":"First Project",
   "ProjectID":123,
   "OrderNumber":456,
   "Description":"This is a description in MARKDOWN format.",
   "PriorityLevel":"Low",
   "PriorityLevelID":1,
   "IssueState":"Open",
   "IssueStateID":12,
   "Resolver":{
      "ID":3,
      "Value":"Ka Wai Cheung"
   },
   "Tester":{
      "ID":2,
      "Value":"Mustafa Shabib"
   },
   "Creator":{
      "ID":1,
      "Value":"Craig Bryant"
   },
   "Watchers":[
      {
         "ID":4,
         "Value":"Michael Sanders"
      },
      {
         "ID":26,
         "Value":"Ka Wai Cheung"
      }
   ],
   "Tags":[
      {
         "ID": 122,
         "Value": "api"
      }
   ],
   "UserRoleIDs":[
      3,
      4,
      5
   ],
   "CompaniesAndPeopleOnIssue":[
      {
         "ID":1,
         "Name":"We Are Mammoth",
         "People":[
            {
               "ID":1,
               "FirstName":"Mustafa",
               "LastName":"Shabib",
               "AccountRoleID":1,
               "EmailAddress":"mustafa.shabib@wearemammoth.com"
            }
         ]
      },
      {
         "ID":102,
         "Name":"Chicago Cubs",
         "People":[
            {
               "ID":162,
               "FirstName":"Andre",
               "LastName":"Dawson",
               "AccountRoleID":1,
               "EmailAddress":null
            }
         ]
      }
   ],
   "TesterResolverAndWatcherIDs":[
      2,
      3,
      4,
      26
   ],
   "Attachments":[
      {
         "ID":0,
         "FileUpload":"http://c3362733.r33.cf0.rackcdn.com/7a72328a-00f2-4985-80a8-6f9da3043f31_smalla.jpg",
         "Bytes":162597.00,
         "RelatedActionableItemHistoryID":58036,
         "RelatedActionableItemHistory":null
      }
   ],
   "Histories":[
      {
         "ID":57406,
         "AvatarURL":"http://c3363003.r3.cf0.rackcdn.com/e48bd3f6-d9be-457c-8cf3-901e99a8b8cf_kc.jpg",
         "CreateDate":"/Date(1314996892513)/",
         "Action":"Craig Bryant created the issue.",
         "Description":"Assigned to *Ka Wai Cheung* as the resolver, and to *Mustafa Shabib* as the tester. This issue is marked as *Low*.",
         "HistoryType":11,
         "Attachments":[
         ]
      }
   ]
}

> Method: People that this issue can be reassigned to

URL: [GET] /PeopleForIssueAssignment/{project_id}/{issue_id}

Example Response:

[
   {
      "ID":162,
      "Value":"Andre Dawson"
   },
   {
      "ID":22,
      "Value":"Anthony Bruno"
   }
]

> Method: Create an Issue

URL: [POST] /Issue/{project_id}

Post Data (parameter name, type, required or optional):

title: string, required.
description: string,  optional.
tags: comma-delimited string,  optional.
priority_level_id: short, required. Get a list of valid priority levels from the method documented above.
resolver_id: int, required. Get a list of people on this project from the method documented above.
tester_id: int, required. Get a list of people on this project from the method documented above.
watcher_ids: comma delimited string of people’s ids. Optional.

Files can be attached by posting the form with the content-type multipart/form-data. 

Example Response:

{
   "IssueID":128,
   "IssueURL":"http://wearemammoth.mydonedone.com/issuetracker/projects/77/issues/128",
   "SuccesfullyAttachedFiles": "true"
}

> Method: Create a Comment

URL: [POST] /Comment/{project_id}/{issue_id}

Post Data (parameter name, type, required or optional):

comment: string, required.
people_to_cc_ids:  comma delimited string of people’s ids. Optional.

Files can be attached by posting the form with the content-type multipart/form-data. 

Example Response:

{
   "CommentURL":"http://wearemammoth.mydonedone.com/issuetracker/projects/77/issues/129#history-58182",
   "SuccesfullyAttachedFiles": "true"
}

> Method: Updating an Issue

URL: [PUT] /issue/{project_id}/{issue_id}

Using this method you can update the tags, title, description, priority level, state (open, in progress, etc.), resolver, or tester of an issue. |

If you provide any parameters then the value you pass will be used to update the issue. If you wish to keep the value that’s already on an issue, then do not provide the parameter in your PUT data. Any value you provide, including tags, will overwrite the existing values on the issue. If you wish to retain the tags for an issue and update it by adding one new tag, then you’ll have to provide all of the existing tags as well as the new tag in your tags_list parameter, for example.

Put Data (parameter name, type):

title: string, optional.
description: string,  optional.
tags: comma-delimited string,  optional.
priority_level_id: short, optional. Get a list of valid priority levels from the method documented above.
state_id: short, Optional. Get a list of valid states that this issue can transition to from the method documented above.
resolver_id: int. Get a list of people on this project from the method documented above.
tester_id: int. Get a list of people on this project from the method documented above.

Example Response:

{
   "IssueURL":"http://wearemammoth.mydonedone.local:64800/issuetracker/projects/77/issues/129"
}

Responses

All responses will contain JSON encoded data, with the response Content-Type set to applciation/json.

Successes

200 – OK – the requested data or a success message with relevant details on POST and PUT requests will be provided as JSON encoded data described above.

Errors

Any request may respond with the following errors, each of which also provides some additional details (if any) as a simple JSON object with a message.
400 – Invalid – you are missing a required parameter or sending an invalid value for a parameter (an integer where a short was expected, for example). Check what you’re sending to the API compared to what’s expected in the documentation.
401 – Unauthorized – you need to provide correct credentials via the basic authentication header
403 – Forbidden – you’re authenticated, but you aren’t authorized to perform the request
404 – Not Found – We can’t find whatever you asked for (bad method, no issue found, no project found, etc).
409 – Conflict –  You’ve made too many requests to the same resource. You can only make 1000 requests from the same IP address per hour. We may adjust this rate limit in the future. When you receive this response, check the `Retry-After` header for how many seconds you have to wait until you are permitted to make requests again.
500 – Internal error – we did something wrong!

Example Error Response

Here’s an example 404 response when attempting to update an issue that does not exist.

< HTTP/1.1 404 Not Found
< Server: ASP.NET Development Server/9.0.0.0
< Date: Mon, 26 Sep 2011 18:38:14 GMT
< Cache-Control: private
< Content-Type: application/json; charset=utf-8
< Content-Length: 26
< Connection: Close
<
{ "Message": "Not found."}

Wrap up

Let us know if you’ve run into any issues or have any additional ideas for useful methods. Now that we’ve made the switch to the new API system, adding and modifying the API will be much easier and so we can continue to improve it as everyone contributes ideas. Additionally, if you run into any issues trying to use this beta release of the API, please let us know by writing to me directly at mustafa.shabib[at]wearemammoth.com.

 

You'll love these too

You'll love these too

Plane