Documentation (2024.2 Enterprise)

# Helix TeamHub API v1

This is the home of stable Helix TeamHub RESTful API documentation. There is also another API version documented - the experimental v2.

On these pages you'll find everything you need to know about the Helix TeamHub REST APIs. These give you access to all the data Helix TeamHub stores, and you will be able to build any clients and integrations you need.

This page introduces the general concepts used throughout all Helix TeamHub APIs, from authentication to the calling conventions and the error codes. To get information about specific types of data, use the navigation on the right.

- API version
- API stability
- Authentication
- Authorization
- Data objects
- HTTP verbs
- Parameter nesting
- Attribute types
- Common attributes
- Custom attributes
- Attributes in deactivated objects
- Error responses
- Validation errors
- Limiting results
- Searching
- Sorting results
- Child objects

## API version

By default, all requests to Helix TeamHub APIs use the latest version, however, we recommend you to explicitly request the wanted version via the Accept header.

    Accept: application/vnd.hth.v1

## API stability

Helix TeamHub APIs follow semantic versioning but only the major version number is used. Bug fixes and backwards compatible changes can be added to the same major version. Major Helix TeamHub releases may deprecate older version of APIs and introduce a new version, e.g.

- Helix TeamHub 2.x supports v1.
- Helix TeamHub 3.x may introduce v2 and deprecate v1, or still continue supporting v1.

## Authentication

All requests (except login/logout) require the following set of keys to be present:

- An Account key - representing the user on whose behalf actions are taken.
- A Company key - representing the company into which all actions will be scoped.

If you don't know your Company key and Account key, you can acquire them by authenticating with your company ID, login (email or user ID) and password:

    curl -X POST \
      -H "Content-Type: application/json" \
      -H "Accept: application/vnd.hth.v1" \
      -d '{"company": "acme", "login": "chuck@norris.com", "password": "ChuckN0rr!5" }' \
      https://helixteamhub.cloud/api/account/sessions

You will find the `account_key`, `company_key` and details of the account (that is either User or Collaborator) and company in the response:

    {
      "api_status": 201,
      "api_timestamp": "2014-12-02T12:26:01Z",
      "account_key": "ab187f75aa6322eff512bfe8ef97b292",
      "company_key": "553ae10f609b0a0d8ac9ebcceefb8d21",
      "account": {
        ...
      },
      "company": {
        ...
      }
    }

You can use this same mechanism to implement Helix TeamHub authentication into your own tools and scripts: Prompt the user for their company, login (email or user ID) and password, and then execute the authentication request on their behalf. Then you can execute any other requests for them by using their account key and company key.

Finally, to logout the user permanently, you can invalidate the account_key with:

    curl -X DELETE \
      -H "Accept: application/vnd.hth.v1" \
      https://helixteamhub.cloud/api/account/sessions/ab187f75aa6322eff512bfe8ef97b292

## Authorization

Authorization is always done before you attempt to do anything via our APIs. However, sometimes you end up in a situation where you would like to know beforehand what you or the current user of your application has privileges to do in Helix TeamHub, e.g. to build a better user experience by hiding specific UI components and whatnot.

Luckily, Helix TeamHub has just what you need to accomplish this; we call them privileges. To read the privileges for a collection of objects or for a specific object is trivial and nearly all of our endpoints support the behavior. Basically all you need to do is to append one query parameter, namely `privileges`, to your RESTful requests and you're done.

Please note that the response for a collection of objects and for a specific object slightly differs. This is due to the fact that there isn't a point in asking whether or not one could update or delete a collection of objects, as such operations are always done against a specific object. To clear it up, we've provided you with some examples, you'll find them below.

Can I create and/or read projects in my company?

    curl -X GET \
      -H "Accept: application/vnd.hth.v1" \
      -H "Authorization: hth.company_key='$COMPANY_KEY',account_key='$ACCOUNT_KEY'" \
      https://helixteamhub.cloud/api/projects?privileges

    {
      "api_status": 200,
      "api_timestamp": "2014-01-10T08:05:03Z",
      "create": true,
      "read": true
    }

Can I read, update, and/or delete the "platform" project in my company?

    curl -X GET \
      -H "Accept: application/vnd.hth.v1" \
      -H "Authorization: hth.company_key='$COMPANY_KEY',account_key='$ACCOUNT_KEY'" \
      https://helixteamhub.cloud/api/projects/platform?privileges

    {
      "api_status": 200,
      "api_timestamp": "2014-01-10T08:05:03Z",
      "read": true,
      "update": true,
      "delete": true
    }

## Data objects

Here are the data objects you can access through the Helix TeamHub APIs, and the operations you can execute on them.

Each object, whatever its type, has an id attribute, which is its identifier and unique within the object type. That identifier can be used to refer to the object in other contexts.

Object | Create | Show | List | Update | Destroy
--- | --- | --- | --- | --- | ---
Attachment | ✓ | ✓ | ✓ | ✓ | ✓
Branch | ✓ | ✓ | ✓ | ✓ | ✓
Bookmark |  | ✓ | ✓ |  |
Code Review | ✓ | ✓ | ✓ | ✓ | ✓
Collaborator | ✓ | ✓ | ✓ | ✓ | ✓
Comment | ✓ | ✓ | ✓ | ✓ | ✓
Commit | ✓ | ✓ | ✓ |  |
Company |  | ✓ |  | ✓ | ✓
Event | ✓ | ✓ | ✓ | ✓ |
Group | ✓ | ✓ | ✓ | ✓ | ✓
Group Member | ✓ | ✓ | ✓ | ✓ | ✓
Hook | ✓ | ✓ | ✓ | ✓ | ✓
Hook Service |  | ✓ | ✓ |  |
License | ✓ | ✓ |  |  |
Milestone | ✓ | ✓ | ✓ | ✓ | ✓
Password Recovery | ✓ | ✓ |  | ✓ |
Project | ✓ | ✓ | ✓ | ✓ | ✓
Project Collaborator | ✓ | ✓ | ✓ | ✓ | ✓
Project Group | ✓ | ✓ | ✓ | ✓ | ✓
Project Member |  |  | ✓ |  |
Project User | ✓ | ✓ | ✓ | ✓ | ✓
Repository | ✓ | ✓ | ✓ | ✓ | ✓
Repository Collaborator | ✓ | ✓ | ✓ | ✓ | ✓
Repository Group | ✓ | ✓ | ✓ | ✓ | ✓
Repository User | ✓ | ✓ | ✓ | ✓ | ✓
SSH Key | ✓ | ✓ | ✓ | ✓ | ✓
Tag |  | ✓ | ✓ |  | ✓
Task | ✓ | ✓ | ✓ | ✓ | ✓
User | ✓ | ✓ | ✓ | ✓ | ✓

## HTTP methods

The API endpoints are used with the following HTTP methods:

- GET - Used for retrieving a resource.
- POST - Used for creating a resource.
- PUT - Used for updating or replacing resources.
- DELETE - Used for deleting resources.

## Parameter nesting

All API endpoints support both nested and non-nested request parameters for POST and PUT requests. What this means is that you can do

    curl -X POST \
      -H "Accept: application/vnd.hth.v1" \
      -H "Authorization: hth.company_key='$COMPANY_KEY',account_key='$ACCOUNT_KEY'" \
      -H "Content-Type: application/json" \
      -d '{ "id": "norris", "email": "norris@helixteamhub.com" }' \
      https://helixteamhub.cloud/api/users

instead of

    curl -X POST \
      -H "Accept: application/vnd.hth.v1" \
      -H "Authorization: hth.company_key='$COMPANY_KEY',account_key='$ACCOUNT_KEY'" \
      -H "Content-Type: application/json" \
      -d '{ "user": { "id": "norris", "email": "norris@helixteamhub.com" } }' \
      https://helixteamhub.cloud/api/users

While the latter example still works, consider the non-nested form the official one for v1.

## Attribute types

The data objects may have attributes with the following types:

### boolean

    true

### string

    "Åbo Akademi"

### integer

    11

### timestamp

A timestamp in the ISO-8601 format (always UTC). Milliseconds are not included.

    "2007-11-20-T22:19:17Z"

### array

A list of other values.

    [
      "Chuck Norris",
      "Clark Kent"
    ]

### object

Another, nested API object.

    {
      id: "norris",
      first_name: "Chuck",
      ...
    }

## Common attributes

Every API object has the following attributes:

### api_status

- Type: `integer`

The HTTP status code that describes the response status for this specific object.

When handling only one object, this is always the same as the status code in the HTTP header. However, with multiple objects each one might have a different status code. For instance, there may be a situation where half of a batch of objects could not be created.

    api_status: 422

### api_timestamp

- Type: `timestamp`

The point in time when the response was created. As the state of the API objects can change, this timestamps each request so you know how recent the information is.

Note that with heavy requests, the returned objects might have API timestamps that differ from each other.

    api_timestamp: "2012-01-22T22:11:11Z"

Most of the API objects have the following attributes:

### created_at

- Type: `timestamp`

The point in time when the object was created.

    created_at: "2012-01-22T22:11:11Z"

### updated_at

- Type: `timestamp`

The point in time when the object was last updated.

    updated_at: "2012-01-22T22:11:11Z"

## Custom attributes

Some of the API objects allow storing custom attributes within the object using the `properties` attribute.

- Type: `object`

    "properties": {
      "string": "value",
      "array": [
        1,
        2,
        3
      ],
      "object": {
        "nested": "value"
      }
    }

## Attributes in deactivated objects

When you delete an object in Helix TeamHub, it will usually be a "soft delete", where the object is not actually physically deleted, just deactivated. (Notable exceptions to this rule are project users, project groups, groups, group members, hooks and SSH keys).

When an object has been deactivated, you are still able to access it through the show endpoint, but you may not modify or restore it. When an object is deactivated, its identifier is renamed. For instance, from norris to norris-1234567.

All deactivated objects have two extra attributes:

### deleted_at

- Type: `timestamp`

Time of the deletion.

    deleted_at: "2013-01-18T09:13:55Z"

### old_id

- Type: `string`

Value of the original identifier before deletion.

    old_id: "norris"

## Error responses

Errors caused by API requests are identifiable by the HTTP status codes that are returned along with the responses. In an error situation, the API response includes the following attributes within the (invalid) API object:

### api_status

- Type: `integer`

HTTP status code.

    api_status: 404

### api_message

- Type: `string`

HTTP status message.

    api_message: "Not Found"

### api_errors

- Type: `object`

Related validation errors, grouped by attribute. See the next section for details.

    {
      email: {
        invalid: true,
        conflicts: ["password"]
      },
      password: {
        conflicts: ["email"]
      }
    }

## Validation errors

When you try to create or update one or more objects and some of them are invalid, the API responds with the HTTP status code 422 Unprocessable Entity. The objects in the response have an `api_errors` attribute, which includes all the validation errors grouped by attribute.

Different field types may have different kinds of validation errors (see the object-specific references for details):

### minimum

- Type: `integer`

The given value is too short (strings), too low (int), or doesn't contain enough objects (arrays). The response contains the minimum value required.

    minimum: 10

### maximum

- Type: `integer`

The given value is too long (strings), too high (int), or contains too many objects (arrays). The response contains the maximum value required.

    maximum: 40

### conflicts

- Type: `array`

The given value cannot be used with one or more of the other given values. In this case, these other attributes are also returned as incompatible. The array contains the names of the conflicting attributes.

    conflicts: ["email"]

### empty

- Type: `boolean`

The value for this attribute cannot be an empty string, 0 or false.

    empty: true

### invalid

- Type: `boolean`

The given value contains the characters that are not allowed, is of invalid type/format, or is otherwise illegal.

    invalid: true

### reserved

- Type: `boolean`

The given value is already in use or reserved for something else.

    reserved: true

### not_found

- Type: `boolean`

The referenced object was not found

    not_found: true

### locked

- Type: `locked`

The given value can not be changed. Depending on the object type, some other user with different privileges might be able to change the value.

    locked: true

## Limiting results

The results of all list actions may be limited for purposes of paging or progressive loading. The responses have the following form:

    {
      "metadata": {
        "more_results": true,
        "next_offset": 2,
        "count": 2
      },
      "results": [
        {
         "key": "value"
        },
        {
         "key": "value"
        },
      ]
    }

The result is an object with two keys:

- `metadata` is an object with information about the result counts. Within it, `more_results` defines whether there are more results to fetch or whether the current response has them all. `count` defines how many results there are in the current result set, and `next_offset` defines what the offset of the next request should be if you are paging or grouping the results.
- `results` is the actual array of objects.

To limit the returned results of a request, pass the following arguments as query parameters in the request:

### limit

- Type: `integer`
- Default: `100`
- Maximum: `10000`

Limits the amount of results returned. Use this to speed up the request when you know you don't need more than N results.

#### Example Request

    curl -X GET \
      -H "Accept: application/vnd.hth.v1" \
      -H "Authorization: hth.company_key='$COMPANY_KEY',account_key='$ACCOUNT_KEY'" \
      "https://helixteamhub.cloud/api/users?limit=3000"

### offset

- Type: `integer`

Moves the starting point of the returned array from zero to the given number. Use this together with limit to implement pagination or other index-based result grouping.

### before

- Type: `timestamp`

Limits returned data to include only objects that were updated before the given point in time.

### after

- Type: `timestamp`

Limits returned data to include only objects that were updated after the given point in time.

### active

- Type: `boolean`

By default only active objects are returned from the index endpoint. Use this flag to explicitly request deactivated objects.

## Searching

### search_term

- Type: `string`
- Allowed endpoint: `index`

A search term to look for. Use together with `search_fields`.

### search_fields

- Type: Comma separated `string`
- Allowed endpoint: `index`

Optionally limit the attributes to search, by default all the searchable attributes of the object are used. Use together with `search_term`. Refer to the object specific references to see the supported searchable attributes.

## Sorting results

To sort results, pass the following arguments as query parameters in your request:

### sort

- Type: `string` of attribute name

The results are ordered naturally based on the value of the given attribute.

### order

- Type: `string`
- Allowed values: `asc`, `desc`
- Default: `desc`

Sorts the results from low to high or high to low. Use together with `order`.

## Child objects

When requesting objects that may have child objects related to them (for example, Projects may have Repositories), you can combine the fetching of those child objects to a single request. This can be done on several levels: You can count the child objects, get their IDs, or get them in full.

Refer to object-specific documentation for the possible child objects.

### count

- Type: Comma separated `string`

Count the numbers of child objects the requested object has. Specify the names of the attributes.

- `count=repositories,users` will attach the following attributes to the returned objects:

    repositories: 32,
    users: 15

### list

- Type: Comma separated `string`

List the IDs of child objects the requested object has. Specify the names of the attributes.

- `list=repositories` will attach the following attributes to the returned objects:

    repositories: ["amiraali", "luotsi"]

### include

- Type: Comma separated `string`

Return child objects in full. Specify the names of the attributes.

- `include=repositories` will attach the following attributes to the returned objects:

    repositories: [
      {
        id: "amiraali",
        type: "git",
        ...
      },
      ...
    ]

### expand

- Type: Comma separated `string`

Return linked objects in full. Specify the names of the attributes.

You can use expand in cases where the default behavior of the API is to specify an ID of a linked object, to expand the id to the linked object's full representation.

- `expand=subject` will attach the following attributes to the returned objects:

    subject: {
      id: username,
      email: email@email.com,
      ...
    }

Your search for returned results

Your search for returned results