This is the official API documentation for Busy's REST API. The goal of the API is to allow for creating integrations with other software
If you have any requests or need support, contact us via our chat at https://busy.no/ or send us a mail at apisupport@busy.no.
To get started with the API, go to our 1-click API demo workspace. This will generate a demo workspace for you – complete with dummy data and an API key.
With your API key you can then start making requests to the API endpoints defined in this reference (using https://api.demo.busy.no/ as the base URL). Note: Remember to include the X-Api-Key header with your key as value.
See the Authentication section for more information about auth and production access.
We don't have any official client libraries at the moment, but there are plenty of code generators which can generate code from our OpenAPI 3.0 spec. Here's a one-liner (using oazapfts!) to generate a library in a TypeScript project:
npm install oazapfts && oazapfts https://api.busy.no/openapi.json busyApi.ts
Be nice to our API – avoid sending unnecessary large requests or unnecessary many requests. If the API gets abused, we reserve the right to revoke access for that user or workspace.
The API is currently in early stages, and while we strive to keep 100% backwards compatibility, the API might still get smaller breaking changes.
We recommend that you use the demo environment to develop and test your integrations. All use of the API in the production environment is at your own risk – wrongly composed API calls may have severe consequences, and you don't want to unintentionally delete or corrupt your workspace's data.
Normally, the API endpoints return a 200 OK response. For specific response codes and data, see each endpoint.
In addition to the responses defined for each endpoint, there are a set of error responses that might be returned for
any requests. The response will follow the RFC 7807 Problem Details
format, which has the content type application/problem+json
.
HTTP code | Description |
---|---|
400 | Invalid input data. The response object contains details on the expected values. |
401 | The request was not authenticated correctly. This is most likely because of a missing or invalid API key. |
403 | The request was authenticated, but the user does not have access to the requested resource. Note that the API key only have access to the resources that its user has. |
404 | The requested endpoint or resource was not found. |
429 | The rate limiter was triggered – see the Retry-After , X-RateLimit-Reset , X-RateLimit-Limit , and X-RateLimit-Remaining headers. |
500 | An error has occurred on our end. This should normally not happen, and we log and fix these issues; contact us if this error persists. |
The data types are specified for each endpoint – here is a list of commonly used formats:
/query?array=1&array=2&array=3
for an
array array = [1, 2, 3]
.To avoid fetching of unneeded amounts of data, all the endpoints returning lists of data implements pagination. The API
uses limit
and offset
to control how much and which data to return, similar to most database systems.
The API currently supports personal API keys for authentication. The API key is connected to one user, which means that you will get the exact same privileges as the user whose API key it is. If you generate an API key as an admin, you will have full access to the workspace. If you generate one as a regular user, it will only have access to what that user has access to.
The fastest method for testing out the APi is by navigating to the 1-click API demo workspace. This will generate a demo workspace for you – complete with dummy data and an API key – without any registration needed.
To use the API in production, simply log in to your user on https://app.busy.no and generate an API key for your user in "Settings" → "Integrations" → "API access".
Remember to use https://api.busy.no as the base URL for API calls.
Use the X-Api-Key header to authenticate your requests. The value of the header should be the API key you have already generated.
Security Scheme Type | API Key |
---|---|
Header parameter name: | X-API-Key |
{- "id": "string",
- "email": "string",
- "lastActiveUserId": "string",
- "firstName": "string",
- "lastName": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
Gets hour entries based on set of filters. The following hour entries are accessible:
offset | integer <int32> [ 0 .. 2147483647 ] Default: 0 The offset of the result set to start at. |
limit | integer <int32> [ 1 .. 100 ] Default: 10 The maximum amount of results to return. |
orderBy | string Default: "startTime" Enum: "startTime" "createdAt" "updatedAt" The field to order by. |
orderByDirection | string Default: "asc" Enum: "asc" "desc" The direction to order by. |
createdAtMin | string <date-time> Filters entries that were created at the given point in time or later (inclusive min). |
startTimeMin | string <date-time> Filters entries that starts at the given point in time or later (inclusive min). |
startTimeMax | string <date-time> Filters entries that starts at the given point in time or earlier (inclusive max). |
userIdIn | Array of numbers <double> [ items <double > ] Filters entries that belongs to one of the specified user IDs. |
{- "data": [
- {
- "id": "1552",
- "userId": "6532",
- "projectId": "335",
- "tagId": "12",
- "startTime": "2021-11-12T13:00:00.000Z",
- "stopTime": "2021-11-12T15:00:00.000Z",
- "billableMinutes": 60,
- "createdAt": "2021-11-05T09:15:30.369Z",
- "updatedAt": "2021-11-05T09:15:30.369Z",
- "description": "Very productive work session",
- "flagged": false,
- "approved": false,
- "locked": false
}
]
}
Creates an hour entry.
startTime required | string <date-time> The start time of the entry. |
stopTime required | string <date-time> The stop time of the entry. Must be same or later than startTime. |
billableMinutes | integer <int32> >= 0 Specifies how many minutes of the entry which is billable – used for calculating prices in reports and invoice orders. |
projectId required | string The ID of the project to use. |
tagId required | string The ID of the tag to use. |
description | string A description of the entry. |
userId | string The ID of the user to log time for. If not specified, the authenticated user is used. |
flagged | boolean Specifies if the entry has been marked with a flag. The flag is only used by Busy to visually show a flag on the entry. |
approved | boolean Specifies if the entry has been approved by a group leader, project manager, or admin. |
locked | boolean Specifies if the entry is locked for edits and has to be unlocked to be edited again. |
{- "startTime": "2019-08-24T14:15:22Z",
- "stopTime": "2019-08-24T14:15:22Z",
- "billableMinutes": 0,
- "projectId": "string",
- "tagId": "string",
- "description": "string",
- "userId": "string",
- "flagged": true,
- "approved": true,
- "locked": true
}
{- "id": "1552",
- "userId": "6532",
- "projectId": "335",
- "tagId": "12",
- "startTime": "2021-11-12T13:00:00.000Z",
- "stopTime": "2021-11-12T15:00:00.000Z",
- "billableMinutes": 60,
- "createdAt": "2021-11-05T09:15:30.369Z",
- "updatedAt": "2021-11-05T09:15:30.369Z",
- "description": "Very productive work session",
- "flagged": false,
- "approved": false,
- "locked": false
}
Updates an hour entry.
hourEntryId required | integer <int32> The ID of the hour entry to edit. |
startTime | string <date-time> The start time of the entry. |
stopTime | string <date-time> The stop time of the entry. Must be same or later than startTime. |
billableMinutes | integer <int32> >= 0 Specifies how many minutes of the entry which is billable – used for calculating prices in reports and invoice orders. |
projectId | string The ID of the project to use. |
tagId | string The ID of the tag to use. |
description | string A description of the entry. |
flagged | boolean Specifies if the entry has been marked with a flag. The flag is only used by Busy to visually show a flag on the entry. |
approved | boolean Specifies if the entry has been approved by a group leader, project manager, or admin. |
locked | boolean Specifies if the entry is locked for edits and has to be unlocked to be edited again. |
{- "startTime": "2019-08-24T14:15:22Z",
- "stopTime": "2019-08-24T14:15:22Z",
- "billableMinutes": 0,
- "projectId": "string",
- "tagId": "string",
- "description": "string",
- "flagged": true,
- "approved": true,
- "locked": true
}
{- "id": "1552",
- "userId": "6532",
- "projectId": "335",
- "tagId": "12",
- "startTime": "2021-11-12T13:00:00.000Z",
- "stopTime": "2021-11-12T15:00:00.000Z",
- "billableMinutes": 60,
- "createdAt": "2021-11-05T09:15:30.369Z",
- "updatedAt": "2021-11-05T09:15:30.369Z",
- "description": "Very productive work session",
- "flagged": false,
- "approved": false,
- "locked": false
}
{- "id": "string",
- "email": "string",
- "displayName": "string",
- "accountId": "string",
- "workspaceId": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
Get users based on a set of filters.
offset | integer <int32> [ 0 .. 2147483647 ] Default: 0 The offset of the result set to start at. |
limit | integer <int32> [ 1 .. 100 ] Default: 10 The maximum amount of results to return. |
orderBy | string Default: "createdAt" Enum: "createdAt" "updatedAt" The field to order by. |
orderByDirection | string Default: "asc" Enum: "asc" "desc" The direction to order by. |
{- "data": [
- {
- "id": "521",
- "email": "marie@example.com",
- "displayName": "Marie Curie",
- "workspaceId": "157",
- "accountId": "523",
- "createdAt": "2021-11-05T09:15:30.369Z",
- "updatedAt": "2021-11-05T09:15:30.369Z"
}
]
}
Gets projects based on a set of filters.
offset | integer <int32> [ 0 .. 2147483647 ] Default: 0 The offset of the result set to start at. |
limit | integer <int32> [ 1 .. 100 ] Default: 10 The maximum amount of results to return. |
orderBy | string Default: "name" Enum: "name" "createdAt" "updatedAt" The field to order by. |
orderByDirection | string Default: "asc" Enum: "asc" "desc" The direction to order by. |
include | Array of strings Items Enum: "users" "tags" Values that can be included on a project.
|
{- "data": [
- {
- "id": "1552",
- "name": "Internal time",
- "createdAt": "2021-11-05T09:15:30.369Z",
- "updatedAt": "2021-11-05T09:15:30.369Z"
}
]
}
Gets project tasks based on set of filters.
offset | integer <int32> [ 0 .. 2147483647 ] Default: 0 The offset of the result set to start at. |
limit | integer <int32> [ 1 .. 100 ] Default: 10 The maximum amount of results to return. |
orderBy | string Default: "createdAt" Enum: "name" "createdAt" "updatedAt" The field to order by. |
orderByDirection | string Default: "asc" Enum: "asc" "desc" The direction to order by. |
createdAtMin | string <date-time> Filters entries that were created at the given point in time or later (inclusive min). |
updatedAtMin | string <date-time> Filters entries that were updated at the given point in time or later (inclusive min). |
{- "data": [
- {
- "id": "1552",
- "projectId": "335",
- "name": "Designing new website for Busy",
- "description": "Busy needed a cool new website.",
- "participantUserIds": [
- "1"
], - "defaultTagId": null,
- "durationEstimate": 360,
- "startDate": "2022-01-05T00:00:00.000Z",
- "stopDate": "2022-01-08T00:00:00.000Z",
- "externalId": null,
- "createdAt": "2021-11-05T09:15:30.369Z",
- "updatedAt": "2021-11-05T09:15:30.369Z"
}
]
}
Creates a project task.
projectId required | string The ID of the project that the project task belongs to. |
name required | string A short description of the task. |
description | string A longer description of the task. |
participantUserIds | Array of strings <= 20 items A list of the IDs of the users that participate in this task. |
startDate | string or null <date> An estimate on when the task should be started worked at. |
stopDate | string or null <date> An estimate on when the task should be finished. |
durationEstimate | integer or null <int32> >= 0 An estimate of how many minutes completing the task will take. |
defaultTagId | string or null The default tag to use when logging time on the task. |
externalId | string or null An ID for the task in another system. This value can be set by integrations to easier keep a link between a task in Busy and in an external system. |
{- "projectId": "string",
- "name": "string",
- "description": "string",
- "participantUserIds": [
- "string"
], - "startDate": "2019-08-24",
- "stopDate": "2019-08-24",
- "durationEstimate": 0,
- "defaultTagId": "string",
- "externalId": "string"
}
{- "id": "string",
- "projectId": "string",
- "name": "string",
- "description": "string",
- "participantUserIds": [
- "string"
], - "startDate": "2019-08-24T14:15:22Z",
- "stopDate": "2019-08-24T14:15:22Z",
- "durationEstimate": 0,
- "defaultTagId": "string",
- "externalId": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
Get tags based on a set of filters.
offset | integer <int32> [ 0 .. 2147483647 ] Default: 0 The offset of the result set to start at. |
limit | integer <int32> [ 1 .. 100 ] Default: 10 The maximum amount of results to return. |
orderBy | string Default: "name" Enum: "name" "createdAt" "updatedAt" The field to order by. |
orderByDirection | string Default: "asc" Enum: "asc" "desc" The direction to order by. |
{- "data": [
- {
- "id": "521",
- "name": "Meeting",
- "createdAt": "2021-11-05T09:15:30.369Z",
- "updatedAt": "2021-11-05T09:15:30.369Z",
- "type": "work"
}
]
}