Overview

API documentation (beta)

Welcome to the Lean Testing API documentation.

This document starts with a general overview about the API, followed by reference information about specific endpoints.

Note: Although this API is in beta phase, you can safely develop applications and integrations. The main resource URLs have been well defined and will not be changed. The same applies for the API output. However you can expect new API endpoints and OAuth scopes to be added in near future.

SSL only

Following with our HTTP Strict Transport Security (HSTS) policy, we require that all requests are done over SSL.

Authentication

In order to interact with the Lean Testing API, you or your application must authenticate. The Lean Testing API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account in full, write and read-only mode.

Developers need to register their application before getting started. A registered OAuth application is assigned a unique Client ID and Client Secret. The Client Secret should not be shared.

Response format

When a request is successful, a response body will typically be sent back in the form of a JSON object. In addition to the main resource root, the response may also contain a meta object. This object contains information about the response itself. The meta object contains a total key that is set to the total number of objects returned by the request. This has implications on the links object.

The meta object will only be displayed when a request is made on a collection (like bugs or projects).

Example:

"bugs": [...],
"meta": {
    "pagination": {
        "total": 12,
        "count": 2,
        "per_page": 2,
        "current_page": 5,
        "total_pages": 6,
        "links": {
            "first": "https://api.leantesting.com/v1/projects/1/bugs?limit=2&page=1",
            "previous": "https://api.leantesting.com/v1/projects/1/bugs?limit=2&page=4",
            "next": "https://api.leantesting.com/v1/projects/1/bugs?limit=2&page=6",
            "last": "https://api.leantesting.com/v1/projects/1/bugs?limit=2&page=6"
        }
    }
}

Links

The links object is returned as part of the response body when pagination is enabled. By default, 10 objects are returned per page. If the response contains 10 objects or fewer, no links object will be returned. If the response contains more than 10 objects, the first 10 will be returned along with the links object.

You can request a different pagination limit or force pagination by appending ?limit= to the request with the number of items you would like per page. For instance, to show only two results per page, you could add ?limit=2 to the end of your query.

The links object contains keys indicating the relationship of additional pages. The values of these are the URLs of the associated pages. The keys will be one of the following:

  • first: The URI of the first page of results.
  • prev: The URI of the previous sequential page of results.
  • next: The URI of the next sequential page of results.
  • last: The URI of the last page of results.

The links object will only include the links that make sense. So for the first page of results, no first or prev links will ever be set. This convention holds true in other situations where a link would not make sense.

Response headers

To keep it simple, any GET, PUT and POST request that is successfully fulfilled will return HTTP 200 OK.

Example:

content-type: application/json
status: 200 OK

Successful DELETE requests will return HTTP 204 No content.

Example:

status: 204 No Content

Errors

Errors are returned using HTTP error code syntax. Any additional info is included in the body of the return call using a standard, JSON-formatted response.

Response attributes

Name Type Description
error boolean Its presence indicates that an error occurred
errors object The list of fields that has errors.
error_message string A brief description of the error.
status integer The HTTP status code

Example response

{
    "error": true,
    "error_message": "Invalid request parameters.",
    "errors": {
        "type_id": [
            "The selected bug type id is invalid."
        ],
        "project_section_id": [
            "The selected project section id is invalid."
        ]
    },
    "status": 400
}

Standard API error codes

Code Description
400 Bad input parameter(s)
401 Bad or expired token. This can happen if the user or Lean Testing revoked or expired an access token. To fix, you should re-authenticate the user.
403 Insufficient permissions to access a resource.
404 Resource not found
5xx Server error. In this case, please contact us.

Related entities

Many resources are related to each other, and on many API endpoints you can request to include those relations in the response.

To do so, add the include query parameter to specify a comma-separated list of related entities that you want to be side-loaded, identifying each of them by name.

Available list of related entities are displayed in a table next to the body response.

Loading related entities example request

GET /v1/bugs/$BUG_ID?include=steps,platform,attachments

Date format

All dates in the API are strings in RFC 2822 format

Example:

Mon, 19 Jan 2015 16:01:53 +000

Base URL

The base URL for all API calls is:

https://api.leantesting.com
SDK
  1. PHP
  2. Python
  3. Ruby

If you've built your own Lean Testing API client or integration, please get in touch and we'll list it in here.

OAuth

Web application flow

This is a description of the OAuth2 flow from 3rd party web sites.

1. Redirect users to request Lean Testing access

GET https://leantesting.com/login/oauth/authorize

Request parameters

Name Type Description Required
client_id string The client ID you received from Lean Testing when you registered the application Required
redirect_uri string The URL in your app where users will be sent after authorization. Required
scope string A comma separated list of scopes. If not provided, scope defaults to read Optional
state string An unguessable random string. It is used to protect against cross-site request forgery attacks. Optional

2. Lean Testing redirects back to your site

If the user accepts your request, Lean Testing redirects back to your site with a temporary code in a code parameter as well as the state you provided in the previous step in a state parameter. If the states don't match, the request has been created by a third party and the process should be aborted.

Exchange this for an access token:

POST https://leantesting.com/login/oauth/access_token

Request parameters

Name Type Description Required
client_id string The client ID you received from Lean Testing when you registered the application Required
client_secret string The client secret you received from Lean Testing when you registered the application. Required
grant_type string Currently only authorization_code is accepted as value. We may accept other grants in the future. Required
code string The code you received as a response to Step 1. Required
redirect_uri string The URL in your app where users will be sent after authorization. Required

Response body

{
    "access_token":"e72e2116c7e4292c6912e7710c838347ae178bza",
    "token_type":"bearer",
    "expires_in": 5184000
}

3. Use the access token to access the API

The access token allows you to make requests to the API on a behalf of a user.

GET https://api.leantesting.com/v1/me?access_token=$TOKEN

You can pass the token in the query params like shown above, but a cleaner approach is to include it in the Authorization header

Authorization: Bearer $TOKEN

Scopes

Scopes let you specify exactly what type of access you need. Scopes limit access for OAuth tokens.

For the web flow, requested scopes will be displayed to the user on the authorize form.

Available scopes

Name Description
admin Fully manage your account. This includes projects, users and your organization.
read Grants read-only access to your projects and your profile information
write Grants read-write access to your projects, and read-only access for your profile information.
We'll be adding more scopes in the future to offer a more granular permissions management.
Users

Get user information Scope required: READ

Retrieves information about the user's account.

Request URL

GET /v1/me

Response body

{
    "id": 1,
    "username": "jonsnow",
    "first_name": "Jon",
    "last_name": "Snow",
    "avatar": "https://www.gravatar.com/avatar/dc8c6cbda45057bee1f843babd74dd1a",
    "email": "jon.snow@thewall.com",
    "created_at": "Fri, 07 Mar 2014 22:28:15 +0000"
}

Get user organizations Scope required: READ

List all the organizations the user belongs to.

Request URL

GET /v1/me/organizations

Response body

{
    "organizations": [
        {
            "id": 1,
            "name": "Crowdsourced Testing",
            "alias": "crowdsourcedtesting",
            "owner_id": 1,
            "url": "https://crowdsourcedtesting.com",
            "logo": "https://damnbugs-assets.s3.amazonaws.com/company/1/cst-logo.png"
        }
    ],
    "meta": {
        "pagination": {
            "total": 6,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 6,
            "links": {
                "next": "https://api.leantesting.com/v1/me/organizations?limit=1&page=2"
            }
        }
    }
}

Retrieve a user organization Scope required: READ

Request URL

GET /v1/me/organizations/$ORGANIZATION_ID

Response body

{
    "id": 1,
    "name": "Crowdsourced Testing",
    "alias": "crowdsourcedtesting",
    "owner_id": 1,
    "url": "https://crowdsourcedtesting.com",
    "logo": "https://damnbugs-assets.s3.amazonaws.com/company/1/cst-logo.png"
}
Projects

List all projects Scope required: READ

Lists all active projects visible for your account. As with any collection returned by the API, the results will be paginated with only 10 on each page by default.

The results will be returned as a JSON object with a projects key.

Request URL

GET /v1/projects

Response body

{
  "projects": [
    {
      "id": 1,
      "name": "My project",
      "owner_id": 1,
      "organization_id": 1,
      "is_archived": false,
      "created_at": "Fri, 07 Mar 2014 22:28:15 +0000"
    }
  ],
  "meta": {
    "pagination": {
      "total": 16,
      "count": 1,
      "per_page": 1,
      "current_page": 1,
      "total_pages": 16,
      "links": {
        "next": "https://api.leantesting.com/v1/projects?limit=50&page=2"
      }
    }
  }
}

Note: you can list archived projects by making a request to the following endpoint:

GET /v1/projects/archived

Create a new project Scope required: WRITE

Request URL

POST /v1/projects

Request parameters

Name Type Description Required
name string Project's name Required
organization_id integer The organization the project belongs to Optional

Response body

{
    "id": 1,
    "name": "My new project",
    "owner_id": 1,
    "organization_id": 1,
    "is_archived": false,
    "created_at": "Fri, 07 Mar 2014 22:28:15 +0000"
}

Retrieve an existing project Scope required: READ

Request URL

GET /v1/projects/$PROJECT_ID

Response body

{
    "id": 1,
    "name": "My project",
    "owner_id": 1,
    "organization_id": 1,
    "is_archived": false,
    "created_at": "Fri, 07 Mar 2014 22:28:15 +0000"
}

List project components Scope required: READ

The results will be returned as a JSON object with a sections key.

Request URL

GET /v1/projects/$PROJECT_ID/sections

Response body

{
    "sections": [
        {
            "id": 1,
            "name": "Home",
            "project_id": 1
        }
    ],
    "meta": {
        "pagination": {
            "total": 11,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 11,
            "links": {
                "next": "https://api.leantesting.com/v1/projects/1/sections?limit=1&page=2"
            }
        }
    }
}

Adding a project component Scope required: WRITE

Request URL

POST /v1/projects/$PROJECT_ID/sections

Request parameters

Name Type Description Required
name string Section name Required

Response body

{
    "id": 1,
    "name": "Home",
    "project_id": 1
}

List project versions Scope required: READ

The results will be returned as a JSON object with a versions key.

Request URL

GET /v1/projects/$PROJECT_ID/versions

Response body

{
    "versions": [
        {
            "id": 1,
            "number": "v1.0",
            "project_id": 1
        }
    ],
    "meta": {
        "pagination": {
            "total": 9,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 9,
            "links": {
                "next": "https://api.leantesting.com/v1/projects/1/versions?limit=1&page=2"
            }
        }
    }
}

Adding a project version Scope required: WRITE

Request URL

POST /v1/projects/$PROJECT_ID/versions

Request parameters

Name Type Description Required
number string Version identifier Required

Response body

{
    "id": 1,
    "number": "v1.1",
    "project_id": 1
}

List project users Scope required: READ

The results will be returned as a JSON object with an users key.

Request URL

GET /v1/projects/$PROJECT_ID/users

Response body

{
    "users": [
        {
            "id": 1,
            "username": "jonsnow",
            "first_name": "Jon",
            "last_name": "Snow",
            "avatar": "https://www.gravatar.com/avatar/dc8c6cbda45057bee1f843babd74dd1a",
            "email": "jon.snow@thewall.com",
            "created_at": "Fri, 07 Mar 2014 22:28:15 +0000"
        }
    ],
    "meta": {
        "pagination": {
            "total": 12,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 12,
            "links": {
                "next": "https://api.leantesting.com/v1/projects/1/users?limit=1&page=2"
            }
        }
    }
}

List bug type scheme Scope required: READ

The results will be returned as a JSON object with a scheme key.

Request URL

GET /v1/projects/$PROJECT_ID/bug-type-scheme

Response body

{
    "scheme": [
        {
            "id": 1,
            "name": "functional"
        },
        {
            "id": 2,
            "name": "usability"
        },
        {
            "id": 3,
            "name": "text"
        },
        {
            "id": 4,
            "name": "visual"
        },
        {
            "id": 5,
            "name": "user_input_data"
        },
        {
            "id": 6,
            "name": "suggestion"
        }
    ],
    "meta": {
        "pagination": {
            "total": 6,
            "count": 6,
            "per_page": 6,
            "current_page": 1,
            "total_pages": 1,
            "links": []
        }
    }
}

List bug status scheme Scope required: READ

The results will be returned as a JSON object with a scheme key.

Request URL

GET /v1/projects/$PROJECT_ID/bug-status-scheme

Response body

{
    "scheme": [
        {
            "id": 1,
            "name": "new"
        },
        {
            "id": 2,
            "name": "confirmed"
        },
        {
            "id": 3,
            "name": "feedback"
        },
        {
            "id": 4,
            "name": "resolved"
        },
        {
            "id": 5,
            "name": "acknowledged"
        },
        {
            "id": 6,
            "name": "closed"
        },
        {
            "id": 7,
            "name": "in_progress"
        }
    ],
    "meta": {
        "pagination": {
            "total": 7,
            "count": 7,
            "per_page": 7,
            "current_page": 1,
            "total_pages": 1,
            "links": []
        }
    }
}

List bug severity scheme Scope required: READ

The results will be returned as a JSON object with a scheme key.

Request URL

GET /v1/projects/$PROJECT_ID/bug-severity-scheme

Response body

{
    "scheme": [
        {
            "id": 1,
            "name": "minor"
        },
        {
            "id": 2,
            "name": "major"
        },
        {
            "id": 3,
            "name": "critical"
        },
        {
            "id": 4,
            "name": "trivial"
        }
    ],
    "meta": {
        "pagination": {
            "total": 4,
            "count": 4,
            "per_page": 4,
            "current_page": 1,
            "total_pages": 1,
            "links": []
        }
    }
}

List bug reproducibility scheme Scope required: READ

The results will be returned as a JSON object with a scheme key.

Request URL

GET /v1/projects/$PROJECT_ID/bug-reproducibility-scheme

Response body

{
    "scheme": [
        {
            "id": 1,
            "name": "always"
        },
        {
            "id": 2,
            "name": "sometimes"
        },
        {
            "id": 3,
            "name": "random"
        },
        {
            "id": 4,
            "name": "once"
        }
    ],
    "meta": {
        "pagination": {
            "total": 4,
            "count": 4,
            "per_page": 4,
            "current_page": 1,
            "total_pages": 1,
            "links": []
        }
    }
}

List bug priority scheme Scope required: READ

The results will be returned as a JSON object with a scheme key.

Request URL

GET /v1/projects/$PROJECT_ID/bug-priority-scheme

Response body

{
    "scheme": [
        {
            "id": 1,
            "name": "low"
        },
        {
            "id": 2,
            "name": "medium"
        },
        {
            "id": 3,
            "name": "high"
        },
        {
            "id": 4,
            "name": "critical"
        }
    ],
    "meta": {
        "pagination": {
            "total": 4,
            "count": 4,
            "per_page": 4,
            "current_page": 1,
            "total_pages": 1,
            "links": []
        }
    }
}
Bugs

List all bugs in a project Scope required: READ

The results will be returned as a JSON object with a bugs key.

Request URL

GET /v1/projects/$PROJECT_ID/bugs

Response body

{
    "bugs": [
        {
            "id": 1,
            "number": 1,
            "title": "Bug details closes when error is displayed",
            "is_private": false,
            "type_id": 1,
            "severity_id": 2,
            "status_id": 6,
            "reproducibility_id": 1,
            "priority_id": 1,
            "created_at": "Mon, 19 Jan 2015 16:01:53 +0000",
            "owner_id": 556,
            "assigned_user_id": null,
            "project_id": 1,
            "project_version_id": 1,
            "project_section_id": 1,
            "description": "Bug description text...",
            "expected_results": "Expected results here..."
        }
    ],
    "meta": {
        "pagination": {
            "total": 2496,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 2496,
            "links": {
                "next": "https://api.leantesting.com/v1/projects/1/bugs?limit=1&page=2"
            }
        }
    }
}

Create a new bug Scope required: write

Request URL

POST /v1/projects/$PROJECT_ID/bugs

Request parameters

Name Type Description Required
title string Bug title Required
status_id integer Required
severity_id integer Required
project_version string The project version where the bug occurred. e.g. v1.1 or beta Required
project_version_id integer The project version ID where the bug occurred. This parameter has precedence over project_version. Required
project_section_id integer Optional
is_private boolean Optional
type_id integer Optional
reproducibility_id integer Optional
priority_id integer Optional
assigned_user_id integer The user ID that will be assigned to this bug Optional
description string Optional
expected_results string Optional
steps array A list with the steps to reproduce the bug Optional
platform object The platform details were the bug occurred (with the options shown below). Optional
Show child parameters

Request body example

{
    "title": "Reporting a bug from the API",
    "severity_id": 2,
    "is_private": false,
    "type_id": 1,
    "reproducibility_id": 1,
    "priority_id": 1,
    "description": "Hello from the API :smile:",
    "expected_results": "Should work smoothly",
    "project_section_id": 1,
    "project_version_id": 1,
    "steps": [
        "Step 1",
        "Step 2"
    ],
    "platform": {
        "device_model_id": 3044,
        "browser_version_id": 46
    }
}

Response body

{
    "id": 1,
    "number": 1,
    "title": "Bug details closes when error is displayed",
    "is_private": false,
    "type_id": 1,
    "severity_id": 2,
    "status_id": 6,
    "reproducibility_id": 1,
    "priority_id": 1,
    "created_at": "Mon, 19 Jan 2015 16:01:53 +0000",
    "owner_id": 556,
    "assigned_user_id": null,
    "project_id": 1,
    "project_version_id": 1,
    "project_section_id": 1,
    "description": "Bug description text...",
    "expected_results": "Expected results here..."
}

Retrieve existing bug Scope required: READ

Retrieves an existing bug with it's basic fields.

Request URL

GET /v1/bugs/$BUG_ID

Response body

{
    "id": 1,
    "number": 1,
    "title": "Bug details closes when error is displayed",
    "type_id": 1,
    "severity_id": 2,
    "status_id": 6,
    "reproducibility_id": 1,
    "priority_id": 1,
    "created_at": "Mon, 19 Jan 2015 16:01:53 +0000",
    "owner_id": 556,
    "assigned_user_id": null,
    "project_id": 1,
    "project_version_id": 1,
    "project_section_id": 1,
    "description": "Bug description text...",
    "expected_results": "Expected results here..."
}

Related entities available

Name Type Collection resource URL
steps collection None
platform object None
attachments collection See List bug attachments
comments collection See List bug comments
tags collection None

Update a bug Scope required: write

You can update a single or many attributes with one request.

Request URL

PUT /v1/bugs/$BUG_ID

Request parameters

Name Type Description Required
title string Bug title Optional
assigned_user_id integer The user ID that will be assigned to this bug Optional
description string Optional
expected_results string Optional
project_version_id integer The project version ID were the bug ocurred. Optional
project_section_id integer Optional
status_id integer Optional
severity_id integer Optional
steps array A list with the steps to reproduce the bug Optional
is_private boolean Optional
type_id integer Optional
platform object The platform details were the bug occurred (with the options shown below). Optional
Show child parameters

Request body example

{
    "title": "New bug title",
    "severity_id": 2,
    "is_private": false,
    "type_id": 1,
    "reproducibility_id": 1,
    "priority_id": 1,
    "description": "Updating bug description",
    "expected_results": "Should work smoothly",
    "project_section_id": 1,
    "project_version_id": 1,
    "steps": [
        "Step 1",
        "Step 2",
        "Step 3",
        "Step 4"
    ],
    "platform": {
        "device_model_id": 3044,
        "browser_version_id": 46
    }
}

Response body

{
    "id": 1,
    "number": 1,
    "title": "New bug title",
    "is_private": false,
    "type_id": 1,
    "severity_id": 2,
    "status_id": 6,
    "reproducibility_id": 1,
    "priority_id": 1,
    "created_at": "Mon, 19 Jan 2015 16:01:53 +0000",
    "owner_id": 556,
    "assigned_user_id": null,
    "project_id": 1,
    "project_version_id": 1,
    "project_section_id": 1,
    "description": "Updating bug description",
    "expected_results": "Should work smoothly"
}

Delete a bug Scope required: write

Request URL

DELETE /v1/bugs/$BUG_ID

The bug will be removed from the project and a response status of 204 will be returned. This indicates a successful request with no response body.

Response headers

status: 204 No Content
Comments

List bug comments Scope required: read

The results will be returned as a JSON object with a comments key.

Request URL

GET /v1/bugs/$BUG_ID/comments

Response body

{
    "comments": [
        {
            "id": 1,
            "text": "Archived projects now appear in the Archived Projects list.",
            "owner_id": 556,
            "created_at": "Tue, 20 Jan 2015 15:59:49 +0000"
        },
        {
            "id": 2,
            "text": "Fixed and verified on 26/01/2015. Closing the issue.",
            "owner_id": 40,
            "created_at": "Mon, 26 Jan 2015 14:34:59 +0000"
        }
    ],
    "meta": {
        "pagination": {
            "total": 2,
            "count": 2,
            "per_page": 10,
            "current_page": 1,
            "total_pages": 1,
            "links": []
        }
    }
}
Attachments

List bug attachments Scope required: read

The results will be returned as a JSON object with an attachments key.

Request URL

GET /v1/bugs/$BUG_ID/attachments

Response body

{
    "attachments": [
        {
            "id": 1,
            "owner_id": 40,
            "url": "https://damnbugs-assets.s3.amazonaws.com/project-assets/1/grumpy-cat.png",
            "created_at": "Mon, 19 Jan 2015 17:57:09 +0000"
        }
    ],
    "meta": {
        "pagination": {
            "total": 1,
            "count": 1,
            "per_page": 10,
            "current_page": 1,
            "total_pages": 1,
            "links": []
        }
    }
}

Upload an attachment Scope required: write

This resource expects a multipart post.

Request URL

POST /v1/bugs/$BUG_ID/attachments

Request parameters

The name of the multipart/form-data parameter that contains attachments must be file

The attachment must not be greater than 25MB.

Response body

{
    "id": 1,
    "owner_id": 481,
    "url": "https://damnbugs-assets.s3.amazonaws.com/project-assets/1/grumpy-cat.png",
    "created_at": "Mon, 16 Nov 2015 21:14:20 +0000"
}

Retrieve an existing attachment Scope required: READ

Request URL

GET /v1/attachments/$ATTACHMENT_ID

Response body

{
    "id": 1,
    "owner_id": 40,
    "bug_id": 1,
    "url": "https://damnbugs-assets.s3.amazonaws.com/project-assets/1/grumpy-cat.png",
    "created_at": "Mon, 19 Jan 2015 17:57:09 +0000"
}

Delete an attachment Scope required: write

Request URL

DELETE /v1/attachments/$ATTACHMENT_ID

The attachment will be removed from the bug and a response status of 204 will be returned. This indicates a successful request with no response body.

Response headers

status: 204 No Content
Platforms

List platform types Scope required: read

The results will be returned as a JSON object with an types key.

Request URL

GET /v1/platform/types

Response body

{
    "types": [
        {
            "id": 1,
            "name": "Android Phone"
        }
    ],
    "meta": {
        "pagination": {
            "total": 9,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 9,
            "links": {
                "next": "https://api.leantesting.com/v1/platform/types?limit=1&page=2"
            }
        }
    }
}

Retrieve platform type Scope required: read

Request URL

GET /v1/platform/types/$TYPE_ID

Response body

{
    "id": 1,
    "name": "Android Phone"
}

List platform devices Scope required: read

The results will be returned as a JSON object with a devices key.

Request URL

GET /v1/platform/types/$TYPE_ID/devices

Response body

{
    "devices": [
        {
            "id": 8,
            "name": "Raider 4G",
            "brand": {
                "id": 3,
                "name": "HTC"
            },
            "os": [
                {
                    "id": 1,
                    "name": "Android"
                }
            ]
        }
    ],
    "meta": {
        "pagination": {
            "total": 1167,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 1167,
            "links": {
                "next": "https://api.leantesting.com/v1/platform/1/devices?limit=1&page=2"
            }
        }
    }
}

Retrieve existing device Scope required: read

Request URL

GET /v1/platform/devices/$DEVICE_ID

Response body

{
    "id": 8,
    "name": "Raider 4G"
}

List OS Scope required: read

The results will be returned as a JSON object with an os key.

Request URL

GET /v1/platform/os

Response body

{
    "os": [
        {
            "id": 1,
            "name": "Android"
        }
    ],
    "meta": {
        "pagination": {
            "total": 6,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 6,
            "links": {
                "next": "https://api.leantesting.com/v1/platform/os?limit=1&page=2"
            }
        }
    }
}

Related entities available

Name Type Collection resource URL
versions collection See List OS versions

Retrieve existing OS Scope required: read

Request URL

GET /v1/platform/os/$OS_ID

Response body

{
    "id": 8,
    "name": "Raider 4G"
}

Related entities available

Name Type Collection resource URL
versions collection See List OS versions

List OS versions Scope required: read

The results will be returned as a JSON object with an versions key.

Request URL

GET /v1/platform/os/$OS_ID/versions

Response body

{
    "versions": [
        {
            "id": 8,
            "number": "5.0"
        }
    ],
    "meta": {
        "pagination": {
            "total": 34,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 34,
            "links": {
                "next": "https://api.leantesting.com/v1/platform/os/3/versions?limit=1&page=2"
            }
        }
    }
}

List browsers Scope required: read

The results will be returned as a JSON object with an browsers key.

Request URL

GET /v1/platform/browsers

Response body

{
    "browsers": [
        {
            "id": 1,
            "name": "Firefox"
        }
    ],
    "meta": {
        "pagination": {
            "total": 34,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 34,
            "links": {
                "next": "https://api.leantesting.com/v1/platform/browsers?limit=1&page=2"
            }
        }
    }
}

Related entities available

Name Type Collection resource URL
versions collection See List browser versions

List browser versions Scope required: read

The results will be returned as a JSON object with a versions key.

Request URL

GET /v1/platform/browsers/$BROWSER_ID/versions

Response body

{
    "versions": [
        {
            "id": 40,
            "name": "Mobile"
        }
    ],
    "meta": {
        "pagination": {
            "total": 1,
            "count": 1,
            "per_page": 10,
            "current_page": 1,
            "total_pages": 1,
            "links": []
        }
    }
}
Integrations

Webhooks Scope required: READ

Webhooks will allow you to build or set up integrations which subscribe to certain events on leantesting.com. When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL. Webhooks can be used to update an external issue tracker, deliver notifications to a system not supported by us, or trigger some crazy Zapier task. You will be only limited by your imagination.

Payload structure

All events share a common structure, detailed below:

  • type: Tells you what kind of thing happened
  • created_at: Tells when it happened
  • actor: Tells who initiated the event
  • data: Contains the specifics of what happened

Example:

{
    "type": "_TYPE_OF_EVENT_",
    "created_at": "Fri, 07 Mar 2014 22:28:15 +0000",
    "actor": {User Schema},
    "data": {
        "object": {...},
        }
}

Note: The only property that will differ is the data property. In each case, the data dictionary will have an attribute called object and its value will be the same as retrieving the same object directly from the API. For example, a bug.created event will have the same information as retrieving the relevant bug would.

Type of events

This is a list of all the types of events we will send for this first version. You'll notice that these events follow a pattern: entity.event. Our goal is to design a consistent system that makes things easier to anticipate and code against

  • webhook.created: Occurs when a webhook is created
  • bug.created: Occurs when a bug is reported
  • bug.createdSeverityCritical: Occurs when a critical severity bug is reported
  • bug.createdSeverityMajor: Occurs when a major severity bug is reported
  • bug.createdPriorityCritical: Occurs when a critical priority bug is reported
  • bug.createdPriorityHigh: Occurs when a high priority bug is reported
  • bug.updated: Occurs when a bug status or property is changed
  • bug.statusChanged: Occurs when a bug status is changed
  • bug.resolved: Occurs when a bug is marked as resolved
  • bug.assigned: Occurs when a bug is assigned to a user
  • bug.moved: Occurs when a bug is moved to another project
  • bug.deleted: Occurs when a bug is deleted
  • comment.created: Occurs when a comment is posted on a bug
  • comment.edited: Occurs when a comment is edited on a bug
  • attachment.created: Occurs when a file is attached to a bug
  • message.created: Occurs when a message is posted on the project
  • message.edited: Occurs when a message is edited on the project
  • run.started: Occurs when a test run is started
  • run.finished: Occurs when a test run is finished

Handling failures

Since no system is perfect and server outages are common, we must be prepared to handle errors and failures generated in both sides of the line. Any failed call should be retried hourly for at least 24h until a 200 status code is received.