The Mavenlink v1 API

Mavenlink's API provides access to the majority of Mavenlink's data model. The API authenticates requests using OAuth2 tokens and exists primarily to allow scripts and 3rd-party applications to access and manage Mavenlink data on behalf of Mavenlink users.

Schema

Requests must be sent via HTTPS and can be in either JSON or Rails structured x-www-form-urlencoded format. Responses will always be returned in JSON format. Dates and times are returned as ISO 8601 formatted strings. All requests to the API must have URLs relative to the base API URL:

https://api.mavenlink.com/api/v1/

Authentication

All requests to the Mavenlink API must be authenticated with an OAuth bearer token. See the application workflow for details on how to register an application with Mavenlink and obtain OAuth bearer tokens.

To authenticate using the Authorization header, set the header's value to Bearer <token>. So, if your token was abc123, your HTTP request would include the header Authorization: Bearer abc123.

For example, authenticating a request using curl would mean running a command similar to this one:

curl -H "Authorization: Bearer abc123" \
  "https://api.mavenlink.com/api/v1/workspaces.json"

All requests to the Mavenlink API require an Authorization header. For brevity, future API request examples in this documentation will not include the example Authorization header parameter.

Response Format

Mavenlink API responses come back as JSON. All GET responses will be of a format similar to the following:

{
  "count": 2,
  "results": [{ key: "workspaces", id: "10" }, { key: "workspaces", id: "11" }],
  "workspaces": {
    "10": {
      id: "10",
      title: "some project",
      participant_ids: ["2", "6"],
      primary_counterpart_id: "6"
    },
    "11": {
      id: "11",
      title: "another project",
      participant_ids: ["2", "8"],
      primary_counterpart_id: "8"
    }
  },
  "users": {
    "2": { id: "2", full_name: "bob" },
    "6": { id: "6", full_name: "chaz" },
    "8": { id: "8", full_name: "jane" }
  }
}

As you can see, Mavenlink API responses can return multiple data types simultaneously, transferring objects and their associations in a single response. In this example, the developer has likely requested the /workspaces.json endpoint, asking for inclusion of those workspaces' participants and primary counterparts. These associations have come back in the top-level object called users. The developer should always use the returned results array to retrieve the canonical results from an API request. This is because some objects may have associations of the same type and can thus be mixed together with their associations in the JSON. For example, stories (tasks) have sub_stories which are the same type of object, so looking directly at the returned stories key when stories have been requested to include their sub_stories will be confusing and will include both. Instead, iterate the results key to determine exactly which top-level objects matched your query and in what order.

The follow sections explain how to customize further the Mavenlink API responses to your needs.

Pagination

Large lists of items may be returned in pages. The JSON response will contain a key named count with a value of the number of objects returned by the entire query. If that number is greater than the number of objects returned by the request, additional objects may be requested by setting the parameter page, the parameter per_page, or both.

If you would like to start at a specific offset you may alternatively use limit and offset parameters. If both limit and offset are passed then page and per_page are ignored, otherwise behavior falls back to page and per_page.

-or-

Request by ID

While each API endpoint returns a paginated listing of the data available, it is sometimes more useful to request only one (or only a few) items. The Mavenlink API provides two ways to do this. The first, via the only parameter, allows you to request one or more resources directly by ID. To request the data for a single Workspace with an ID of 5, make an API request to the URL GET /api/v1/workspaces.json?only=5. Multiple IDs can be supplied in a comma separated list, like GET /api/v1/workspaces.json?only=5,6,7. The returned JSON will contain only the objects with those IDs.

Additionally, we support traditional RESTful routes, such as GET /api/v1/workspaces/5.json. These routes also support our standard filters and includes, both detailed below. Unlike only requests to our "index" routes, these "show" routes will generate a 404 response if the requested resource cannot be found. Sometimes this is due to default filters being applied, so be sure to check the filter defaults applied in the specific documentation for the requested resource. More on filters below.

Filters

Many API endpoints also provide an optional set of filters that can be applied to the data that will be returned. Each filter, and the logic behind it, is documented on the individual endpoint pages, but the general form is a URL query parameter or request parameter like filter1=arg1&filter2=arg2, where filter1 and filter2 are the names of two different filters, and arg1 and arg2 are the arguments to each filter, respectively. Additionally, some filters have default values, which indicates that they are automatically applied to your request with their default value. Default values are applied both on "index" (GET /workspaces.json) requests and "show" (GET /workspaces/1.json) requests.

Includes

Some objects returned by the API may have associations that are not included in the JSON response by default. Those associated objects can be requested by adding an include parameter to the request. For example, to request both a list of posts, and the users that created those posts, you could request /posts.json?include=user. The response will consist of a JSON object with an array of result mappings under the "results" key, a "posts" key with a hash of post objects, keyed by id, and a "users" key with a hash of user objects, again keyed by id. To find the user that created a particular post, just use the post object's "user_id" key to find the user object keyed with the same id.

Multiple associations may be fetched simultaneously by adding comma-separated values to the include parameter. For example, to fetch the user and replies associated with post 6, you might request /posts.json?only=6&include=user,attachments, which would supply both the users and the attachments that belong to the posts returned in the response.

Example

curl -H "Authorization: Bearer abc123" "https://api.mavenlink.com/api/v1/posts.json?include=user,attachments"

{
  "count": 1,

  "results": [
    { "key": "posts", "id": "16270634" }
  ],

  "posts": {
    "16270634": {
      "id": "16270634",
      "message": "Hello World",
      "has_attachments": true,
      "user_id": "2",
      "workspace_id": "2249167",
      "attachment_ids": ["6700107"]
    }
  },

  "users": {
    "2": {
      "id": "2",
      "full_name": "John Doe",
      "email_address": "johnny_doe@example.com"
    }
  },

  "attachments": {
    "6700107": {
      "id": "6700107",
      "created_at": "2013-04-15T16:48:48-07:00",
      "filename": "turtle.jpg",
      "filesize": 16225
    }
  }
}

Ordering

Each endpoint in the Mavenlink API allows ordering by various fields. If we're missing a sort field that you need, please ask! See the specific endpoint documentation for endpoint-specific details.

When ordering, supply order with the name of a valid sort field for the endpoint and a direction. For example, order=created_at:desc.

Searching

Some API endpoints support text search, however only some filters can be combined with search, and results will be returned ordered by relevancy to the search query. Search does not apply to only requests. If search is unavailable the response will contain a system error describing the problem.

To make a search request, simply add a search parameter to the request. For example, to search for stories with "estimates" in the title, assignee names, or other fields, request /stories.json?search=estimates

See the specific endpoint documentation for which filters and fields are available when searching.

Errors

If there is an error while processing your request, the response will include an HTTP status code indicating the error. Errors are currently returned as a top-level errors key with an array of error objects. For example, on OAuth failure you will receive a HTTP 401 with the following JSON body:

{
  errors: [
    {
      type: "oauth"
      message: "Invalid OAuth 2 Request"
    }
  ]
}

System errors will look like:

{
  errors: [
    {
      type: "system"
      message: "Your account has been canceled"
    }
  ]
}

And model validation errors look like:

{
  errors: [
    {
      type: "validation",
      message: "Please give your project a title",
      field: "title"
    },
    {
      type: "validation",
      message: "Please select a role for this project",
      field: "creator_role"
    }
  ]
}

Rate limiting

When too many requests are made in a short amount of time, the API may reply with the HTTP code 429 Too Many Requests. In that case, simply retry your request after a small delay. The API rate limits are not yet solidified, and may change soon.

OAuth 2.0

OAuth 2.0 provides an evolving, standardized inter-application authentication workflow for the Web. To build an application that interacts with Mavenlink on behalf of your users, you will need to register your application, and then obtain an OAuth token for each of your users.

Registering your application

Register and manage OAuth2 applications that can connect to Mavenlink at the application management page as a Mavenlink account administrator. You'll need a (free) Mavenlink account in order to register applications with us. Applications have a name and a callback URL for OAuth2.

If you only want to use the Mavenlink API for yourself, or as a backend connector, you must still register an Application, but then you can get an OAuth token for yourself on the Application's page. If you want your application to be able to use the Mavenlink API on behalf of other users, read the next section.

Obtaining tokens for users

Every request to the Mavenlink API must be accompanied by a valid OAuth token, indicating that your application has been authorized by the Mavenlink user in question. When you register an application with us, we'll provide you with a secret key. That key is unique to your application, and shouldn't be shared with anyone else. Treat it like a password. You'll need it to request user tokens.

What follows are the steps to obtain a user token after registering an application. If you are using an OAuth2 library, many of these steps will be handled for you.

To authorize your application for Mavenlink API access, you will need to accomplish the following steps for each Mavenlink user:

  1. Request a short-term code, granted when the Mavenlink user agrees to allow your application access.

    Send your user to /oauth/authorize with the REQUIRED parameters client_id, response_type, and redirect_uri.

    • client_id is the ID assigned to your application by Mavenlink
    • response_type must be set to "code"
    • redirect_uri must be set to a URL where your application can accept codes and then exchange them for access tokens. It should match the redirect_uri specified when you registered your application.

    Here is an example URL that an application located at "myapp.com" might use. (Linebreaks are not included in the URL.)

    https://app.mavenlink.com/oauth/authorize?response_type=code&client_id=abc123&redirect_uri=http%3A%2F%2Fmyapp.com%2Foauth%2Fcallback
    
  2. The user will be asked by Mavenlink if they want to authorize your application to interact with Mavenlink on their behalf.

    If something goes wrong (like the user refused to authorize your application), Mavenlink will redirect to the redirect_uri with query parameters providing information about the error. For example, if authorization is denied, the user will be redirected to:

    $REDIRECT_URI?error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request.
    

    If the user allows your application, then Mavenlink will redirect to the redirect_uri with query parameters providing your application with a time-limited code that your application can exchange for an access token within the next 5 minutes. Here is an example redirection with granted access:

    $REDIRECT_URI?code=abc123
    
  3. Your application exchanges the code for an access token

    Now that your application has a code, it should make a POST request directly to Mavenlink at https://app.mavenlink.com/oauth/token to exchange the code for an access token that will allow continued interaction with the Mavenlink API. The request must include the client_id, client_secret, grant_type, code, and redirect_uri parameters.

    • client_id is the ID assigned to your application by Mavenlink
    • client_secret is the secret token assigned to your application by Mavenlink
    • grant_type must be set to "authorization_code" in order to exchange a code for an access token
    • code is the value that was returned in the code query parameter when Mavenlink redirected back to your redirect_uri
    • redirect_uri is the exact same value that you used in the original request to /oauth/authorize

    If the request is invalid for some reason, an error response like the one described above will be returned. However, the parameters will be returned in the response body, encoded as JSON, instead of in the URL encoded as query parameters.

    If the request is valid, Mavenlink will provide a response body, encoded in JSON, containing access_token and token_type.

    • access_token is the token that your application will use to authenticate requests to the Mavenlink API as this user
    • token_type will be "bearer"
  4. Your application uses the access token to make authenticated requests to the Mavenlink API

    At this point, your application can use the access token to authenticate requests made to the Mavenlink API as described above in the Authentication section.

Security

Mavenlink OAuth access tokens do not expire and must be treated with the same security that you would treat client credentials such as passwords. All requests must be made over SSL and all user security credentials must be stored using industry best practices. If a user revokes your application's access, usage of the token will result in an error.