API Documentation

Authentication

To use the API, please generate an API key for your organization from within the application, under Settings > General Settings.

Use basic HTTP authentication with the API key as user and 'x' as password.

Security

It is strongly advised to only use https when connecting to www.bugherd.com.

Rate limiting

You are only allowed to make an API call every 3 seconds. We therefore recommend to "sleep" your app for 3 seconds in between API calls to BugHerd to be safe. If you make more frequent API calls, a 429 error will be returned instead of the expected result.

The limit may be lifted for approved applications which have been tested and use webhooks where possible in favour of periodic polling.

Feedback

Our API is being continuously improved based on your feedback. If you are missing a feature, please email support@bugherd.com.

Examples

All API calls below include an example call using the 'curl' command. To try the command, please replace 'api_key' with the API key for your account, and also replace the IDs with relevant IDs.

Show organization

Get more detail of your account.

GET /api_v2/organization.json

List users

See all the people in your account.

GET /api_v2/users.json

GET /api_v2/users/members.json

GET /api_v2/users/guests.json

List projects

Get a list of all projects within your account.

GET /api_v2/projects.json

GET /api_v2/projects/active.json

The response will include the list of projects and a "count" of all projects in the organization:

{
  "projects":[...],
  "meta":{
    "count":12
  }
}

Note: only the first 100 records are returned by this API. If the "count" is greater than 100 you need to get each page separately, by passing a "page" GET parameter. Example:

Show project

Show details for a specific project. Note: if you'd like to see the tasks in the project, refer to section 'List tasks'.

GET /api_v2/projects/#{project_id}.json

Create project

Create a new project. The project will initially have no members.

POST /api_v2/projects.json

Example request data:

{"project":{
  "name":"My Website",
  "devurl":"http://www.example.com",
  "is_active":true,
  "is_public":false
}}

Add member

Add a member to a project.

POST /api_v2/projects/#{project_id}/add_member.json

Request data:

{"user_id":123}

Add guest

Add an existing guest to a project, or invite someone by email address.

POST /api_v2/projects/#{project_id}/add_guest.json

Request data:

{"user_id":123}
{"email":"someone@example.com"}

Update project

Update settings for an existing project under your control (ie: only the ones you own).

PUT /api_v2/projects/#{project_id}.json

Example request data:

{"project":{
  "is_public":true
}}

Delete project

Delete a project and all associated data. Use with care, deleted projects cannot be recovered.

DELETE /api_v2/projects/#{project_id}.json

List tasks

Get a full list of tasks for a project, including archived tasks.

GET /api_v2/projects/#{project_id}/tasks.json

You can filter tasks using the following GET parameters: updated_since, created_since, status, priority, tag, assigned_to_id and external_id. Examples on how to use filters are below:

Each response will include the list of tasks and a "count" of all projects in the organization:

{
  "tasks":[...],
  "meta":{
    "count":12
  }
}

Note: only the first 100 records are returned by this API. If the "count" is greater than 100 you need to get each page separately, by passing a "page" GET parameter. Example:

Show task

List details of a task in a given project, includes all data including comments, attachments, etc.

GET /api_v2/projects/#{project_id}/tasks/#{task_id}.json

Below is an explanation of the output:

id: globally unique ID
local_task_id: ID within the project
project_id: ID of the containing project
created_at: timestamp in the form YYYY-MM-DDThh:mm:ssZ
updated_at: timestamp in the form YYYY-MM-DDThh:mm:ssZ
closed_at: timestamp in the form YYYY-MM-DDThh:mm:ssZ or null
deleted_at: timestamp in the form YYYY-MM-DDThh:mm:ssZ or null
description: the user-entered text to describe the problem
status: backlog, todo, doing, done or closed
status_id: integer for status or null, 0 = backlog, 1 = todo, 2 = doing, 4 = done, 5 = closed
priority: not set, critical, important, normal or minor
priority_id: integer for severity 0 = N/A, 1 = critical, 2 = important, 3 = normal, 4 = minor
site: website this task was logged on
url: location of web page
tag_names: list of tags
external_id: value as set from api
requester_email: email address of the requester, if present
attachments: list of urls to the bug attachments
screenshot_url: url to the screenshot image for the bug
secret_link: unguessable url to the bug (does not require login)
admin_link: link to the bug in the task board (does require login)
assigned_to: user information on assignee
requester: user information on requester

Add a new task in a project.

POST /api_v2/projects/#{project_id}/tasks.json

Example request data:

{"task":{
  "description":"Example task",
  "priority":"normal",
  "status":"backlog",
  "requester_id":123,
  "tag_names":["ui","feature"],
  "assigned_to_id":123,
  "external_id":"ABC123"
}}

or:

{"task":{
  "description":"Example task",
  "requester_email":"user@example.com",
  "assigned_to_email":"someone@company.com",
}}

"requester_email" can be any email address while "assigned_to_email" needs to be of a current project member.

Values for "priority" are not set, critical, important, normal, and minor.

Values for "status" are backlog, todo, doing, done, and closed. Omit this field or set as "null" to send tasks to the Feedback panel.

External ID is an API-only field. It cannot be set from the BugHerd application, only using the API. An external ID can be used to track originating IDs from other systems in BugHerd bugs.

Update task

Update one of the tasks in a project.

PUT /api_v2/projects/#{project_id}/tasks/#{task_id}.json

Request data:

{"task":{
  "priority":"normal",
  "status":"backlog",
  "assigned_to_id":123,
}}

If you'd like the update to happen on behalf of a specific user in the project (note that those user's permissions do not apply when making an update via the API, this is only for audit logging purposes)

{"task":{
  "status":"todo",
  "updater_email":"someone@company.com",
}}

Below are examples for unsettings values (only allowed for status and assigned_to_id)

Unassigning a task:

{"task":{"assigned_to_id":null}}

Moving a task back to feedback:

{"task":{"status_id":null}}

List comments

Get a paginated list of comments for a task.

GET /api_v2/projects/#{project_id}/tasks/#{task_id}/comments.json

Create comment

Adds a new comment to the specified task.

POST /api_v2/projects/#{project_id}/tasks/#{task_id}/comments.json

Request data:

{"comment":{
  "text":"comment here",
  "user_id":123
}}

or:

{"comment":{
  "text":"comment here",
  "email":"user@example.com"
}}

List attachments

Get a paginated list of attachments for a task.

GET /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments.json

Show attachment

Get detail for specific attachment.

GET /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments/#{id}.json

Create attachment

Adds a new attachment to the specified task using an existing URL.

POST /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments.json

Request data:

{"comment":{
  "file_name":"resolution.gif",
  "url":"http://i.imgur.com/U9h3jZI.gif"
}}

Upload attachment

Upload a new attachment and add it to the specified task. The file contents need to be specified as the POST data on this request.

Note that your upload needs to be reasonable in size as the maximum time the request may take is around 30 seconds. If you have larger uploads please create arrange your own file upload and create the attachment from a URL instead.

POST /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments/upload

Note in the sample below please specify an existing file name.

Delete attachment

Delete an attachment from a task. Note that this action is permanent and cannot be undone.

DELETE /api_v2/projects/#{project_id}/tasks/#{task_id}/attachments/#{id}.json

Webhooks

Webhooks are great for creating applications with synchronisation in two directions. That is, rather than just being able to read and write to and from BugHerd when there is activity in your application, allow your application to hook into BugHerd activity as well.

To test webhooks, it is recommended to use a service such as RequestBin.

Note: when a webhook is returned a 4xx HTTP error code, it is interpreted as an explicit instruction that the webhook is pointing to an incorrect target and will result in the webhook being removed automatically. Examples of codes are: 403 forbidden, 404 not found, 410 gone.

List webhooks

Get a list of currently installed webhooks.

GET /api_v2/webhooks.json

Create webhook

POST /api_v2/webhooks.json

When installing a webhook, specify an event you wish to hook into. Choose from: "task_create", "task_update", "comment" or "task_destroy". To get activity for all 3 events, create an entry for each event.

"project_id" is optional; it only needs to be specified if you'd only like events on a specific project. Omitting "project_id" results in notifications of activity on all your projects.

Request data:

{
  "project_id":1,
  "target_url":"https://app.example.com/api/bugherd_sync/project/1/task_create",
  "event":"task_create"
}

Delete webhook

DELETE /api_v2/webhooks/#{id}.json

Community libraries

bugherd_client ruby gem by faucett from testCloud.

PHP Bugherd API by Thibault S├ębastien.

Other languages?

If you have integrated with BugHerd using your favorite language (Go, Python, etc) we and other fellow web folks would be super impressed if you shared some sample code with us so we can publish it here!