HQ API Documentation


Hi, nice to see you!

This is the documentation of the HQ API, which allows developers access to a wide range of entities and business logic of HQ.

Before you get started, you need to register your client application in the HQ administration panel.


The HQ API allows access to your data in HQ. The API follows the OData 4.0 standard for retrieving, creating, updating and deleting entities through RESTful HTTP requests.

Base URL: https://api.hqlabs.de/

The HQ API uses OAuth 2.0 for authentication.

Getting started

OAuth 2.0 is an authentication framework used for secure user authentication. With the typical OAuth 2.0 authentication flows, third-party applications do not receive the user's password but only a token which is valid for a limited time.

To uniquely identify the client, each client application needs to be registered first. The client receives an App Id and App Secret which they use to authenticate against the API.

When a user wants to use the client application, the user is directed to our Login page, where the user provides the name and password. After the user logged in, the client application receives an Access Token and Refresh Token, which are then used to authenticate against the API. From now on, the user is no longer involved.

Try it out

In the API Explorer, you can try out the OAuth 2.0 Implicit Grant Flow by activating the switch next to each API action. You will be asked to provide your App Id and App Secret. Visit the administration panel in your HQ to add a new client application if you didn't do so already.

Client Application

A client application needs to be registered in your HQ. To do so, go to the administration panel and add a new client application. You will be asked to provide a unique name and a display name for your client.

App Id

The App Id used for OAuth 2.0 consists of your HQ customer id and the id of the client application you created in HQ in the form {customer-id}-{client-id}. For example, 12345-clientapp, where 12345 is your customer id and clientapp is the id of the client. After you registered a client application in your HQ, you can find the App Id in the list.

App Secret

The App Secret is generated in the administration section in your HQ. You can find it next to the App Id in the list. It is used to authenticate your client application when requesting a token.

Scopes

The OAuth2.0 authentication flow uses scopes to define the rights the user grants to the application. The HQ API currently allows the following scopes:

  • read_all: read access to all resources
  • write_all: write access to all resources

Tokens

Access Token
The Access Token is used to authenticate against the API resources. It needs to be included in every request to the API. Each user needs their own Access Token, since they are only valid for one particular user. It is usually valid for a few days only.

Refresh Token
The Refresh Token is used to get a new Access Token after it has expired. A Refresh Token only expires when the user manually revokes access for your client application.

OAuth Endpoints

The OAuth Endpoints are required to get an Access Token and exchange a Refresh Token for a new Access Token.

/Account/Authorize
The Authorize Endpoint is used to initially retrieve an authorization code.

/Token
The Token Endpoint is used to retrieve an authorization code for an Access Token or to get a new Access Token with the Refresh Token.

Authorization Flow

The OAuth 2.0 Authorization Code Grant is the default authorization flow and mainly used by client applications. It is described here in detail.

The client constructs the request URI by adding the following parameters to the query component of the authorization endpoint URI using the "application/x-www-form-urlencoded" format. Then, the client directs the user to the constructed URI using a browser window. The user is asked to log in, provides their username and password and grants the permissions to your client application.

Parameter:

  • ClientId: the client id of the authentication client
  • State: an arbitrary state string
  • RedirectUri: the url to redirect the browser to after the user granted the access, url encoded
  • Scope: a space-separated list of API scopes

Example:
GET https://api.hqlabs.de/Account/Authorize?response_type=code&client_id=1234-testapp&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&scope=read_all%20write_all

The user logs in and grants or revokes the access request.

If the user grants the access request, the authorization server issues an authorization code and delivers it to the client by adding the following parameters to the query component of the redirection URI using the "application/x-www-form-urlencoded" format.

Parameter:

  • RedirectUri: the previously specified redirect uri
  • AuthenticationCode: the code that can be exchanged for a token
  • State: an arbitrary state string

Example:
302 Found
https://client.example.com/cb?code=MWG5HTnFn9n8HJ?state=xyz

The client makes a request to the token endpoint by sending the following parameters using the "application/x-www-form-urlencoded" format with a character encoding of UTF-8 in the HTTP request entity-body.

Parameter:

  • AuthenticationCode: the code that was sent in the previous response
  • RedirectUri: the previously specified redirect uri

Authorization: This request requires the HTTP Basic Authentication header. You need to encode your {appId}:{appSecret} using the Base64 method and add it to the Authorization header, like this: Authorization: Basic Base64({AppId}:{AppSecret})

Example:
POST https://api.hqlabs.de/Token
Body: redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&grant_type=authorization_code&code=MWG5HTnFn9n8HJ

If the access token request is valid and authorized, the authorization server issues an Access Token and Refresh Token. If the request failed or is invalid, the authorization server returns an error response.

Parameter:

  • AuthenticationCode: the code that was sent in the previous response
  • RedirectUri: the previously specified redirect uri

Example:
{
   "access_token": "FGDoJBgK96Z...", // the Access Token for authorization
   "token_type": "bearer", // the token type, usually bearer
   "expires_in": 1199, // the expiration timespan, in seconds
   "refresh_token": "K8vma4VohMb...", // the Refresh Token to request a new Access Token
   "user_id": 12, // the Id of the user these tokens are valid for
   "user_name": "test.user" // the username of the user these tokens are valid for
}

After receiving the Access Token, you can use it to request resources from the API.

To retrieve resources from the API, add the Access Token to the Authorization header in the following form: Bearer {AccessToken}

Example:
Authorization: Bearer FGDoJBgK96Z...

Access Tokens expire and need to be refreshed with the Refresh Token.

Every Access Token expires after a time, usually after 30 days. You can use the Refresh Token to retrieve a new Access Token. The Refresh Token only expires when the user revokes the token.

Parameter:

  • GrantType: the grant type needs to be set to refresh_token
  • RefreshToken: the previously received Refresh Token

Authorization: This request requires the HTTP Basic Authentication header. You need to encode your {appId}:{appSecret} using the Base64 method and add it to the Authorization header, like this: Authorization: Basic Base64({AppId}:{AppSecret})

Example:
POST https://api.hqlabs.de/Token
Body: grant_type=refresh_token&refresh_token=K8vma4VohMb...

Example:
{
   "access_token": "ADFoJBgK96c...", // the new Access Token for authorization
   "token_type": "bearer", // the token type, usually bearer
   "expires_in": 1199, // the expiration timespan, in seconds
   "refresh_token": "Gtv6a4VohaB...", // the new Refresh Token to request a new Access Token
   "user_id": 12, // the Id of the user these tokens are valid for
   "user_name": "test.user" // the username of the user these tokens are valid for
}

For further questions, please contact us at support@helloHQ.io.

Filter are useful to construct queries against our API. This way, you don't need to retrieve all data and filter on the client.

In the URL, add the following to the $filter= parameter. In the API Explorer, just write the filter command into the $filter textbox.

Here, some filter examples are shown.

Filter by CompanyType

Find all companies of a specific type, where 4002 is the Id of the CompanyType 'Customer':
CompanyTypes/any(companyType: companyType/Id eq 4002)

Find all companies of a specific type, where 'Lieferant' is the name of the CompanyType:
CompanyTypes/any(companyType: companyType/Name eq 'Lieferant')

Filter by date and time

Get all entities updated since January 26th 2016:
UpdatedOn ge 2016-01-26

Get all entities updated since January 26th 2016, 6:15pm:
UpdatedOn gt 2016-01-26T18:15:00+01:00

Get all invoices within one month:
InvoiceDate ge 2016-03-01 and InvoiceDate lt 2016-04-01

For further questions, please contact us at support@helloHQ.io.

Expands can be used to retrieve more data in one query. They allow to get related entities and navigation properties from an entity.

In the URL, add the following to the $expand= parameter. In the API Explorer, just write the expand command into the $expand textbox.

Here, some expand examples are shown.

Expand one property

On a company, expand the default address of the company:
DefaultAddress

Expand multiple properties

On a company, expand the default address and the company types of the company:
DefaultAddress,CompanyTypes

Expand multiple levels

On an invoice, expand the company and the types of the company:
Company($expand=CompanyTypes)

For further questions, please contact us at support@helloHQ.io.

Generally, all API responses, as well as the POST and PUT bodies, are in JSON and follow the OData 4 definition.

The OData response wraps the actual data in the data field and adds additional metadata.

However, there are some cases where the API provides access to binary data, like PDFs and images.

Document File (PDF)

Every document, for example invoices and quotations, can be retrieved as a generated PDF file. The PDF is generated on the fly when the document is in a draft state. After the document was sent, the PDF is archived and the archived PDF is returned in the API.

You can access the metadata of the document file like this:
v1/Invoices(id)/

You can access the binary stream (PDF) of the document file like this:
v1/Invoices(id)/DocumentFile/$value

For further questions, please contact us at support@helloHQ.io.

Each response to an API request indicates the success with its status code.

Success Status Codes
Method Status Code Remarks
GET 200 (OK)  
POST 201 (Created)  
PUT 200 (OK)  
DELETE 240 (No content)  
do.Action() 200 (OK) If base entity was changed
do.Action() 201 (Created) If new entity was created

The body of the reponse with status code 200 and 201 contain the changed/created object. Responses with code 204 always return an empty body.

Failure Status Codes
Method(s) Status Code Reason
GET / PUT / DELETE / do.Action() 404 (Not Found) No object found / Invalid Id
POST / PUT / do.Action() 400 (Bad request) Missing request body
POST / PUT / do.Action() 400 (Bad request) Missing request argument
POST / PUT / do.Action() 400 (Bad request) Validation failed

The date and time information is generally in UTC. The client is responsible for converting the date and time information to user time. The user object contains the selected timezone of the user. Date and time properties in UTC end on ...On, for example StartOn or CreatedOn.

There are, however, a few exceptions, where only the date is relevant. In these cases, the date information is represented without a timezone and should not be converted. Date properties end on ...Date, for example StartDate or ShownDate.

Actions are POST operations performed on specific API objects. Sometimes actions need specific parameters for the performed operation but this is not necessary every one of them. An action is mostly a more complex operations handled on the server which usually perform different data manipulations and object creations. Remember that an action should not be invoked too frequently on the same object because of the data manipulation. One call is sufficient to get the certain outcome.

When new objects are created during an action, in most cases the newly generated action is beeing returned. The return value can be seen in the action description iteself.

For further questions, please contact us at support@helloHQ.io.

An SDK is available on GitHub.

The HQ API follows the semver versioning scheme Major.Minor.Patch. This means that breaking changes are introduced only in major versions, new features increment the minor version number and patches are performance improvements and fixes. Read more: http://semver.org/

Different major versions can be accessed by appending the version number in the URL, for example /v1. We plan to support two major versions before the current version. So if we release major version 3, it will still include support for version 1 and 2.

February 2017 - v1.3

Bug Fixes
  • Quotations and Invoices GET and Actions do not operate on archived Quotations and Invoices anymore
Added

Main Routes

  • Articles
  • ArticleStorages
  • ContactHistories
  • Files
  • LeadStatuses

POST/PUT/DELETE for existing entities

  • ContactPersons
  • Invoices
  • Quotations
  • Positions
  • ProjectTasks
  • Reportings

Sub Routes

The following main routes now support sub routes:
  • Companies/Addresses
  • ProjectTasks/Assignments
  • Users/Assignments
  • Users/Absences
  • Users/Reportings
  • Projects/Reportings
  • Articles/SalesPrices
  • Articles/Stocks
  • Articles/Stocks/StockTransactions
  • Invoice/Positions
  • Quotation/Positions

Sub routes for CustomFields below the following routes:
  • Leads
  • Projects
  • Companies
  • Users
  • ContactPersons
  • Articles
  • Invoices/Positions
  • Quotations/Positions
Breaking Changes
  • Main route 'ProjectStatus' was renamed to 'ProjectStatuses'
Removed
  • The following main routes are deprecated:
    • CompanyAddresses → use su broute Companies/CompanyAddresses instead
    • TaskAssignments → use sub route ProjectTasks/Assignments and Users/Assignments instead
    • UserAbsences → use sub route Users/Absences instead
    • TaskDependencies→ use sub route ProjectTasks/Dependencies instead

September 2016

  • Base URL: The Base URL of the API was changed. The Base URL is now always api.hqlabs.de
  • Authentication: The HTTP Basic Authentication was replaced by OAuth 2.0. Read more in the Authentication section.

Roadmap:

  • Entities: There might be slight modifications to the entities before the final release. Even after release, we might include more properties at any time.

Please refer to the following pages and guides to learn how to use our API.

HQ API Explorer


The API Explorer allows you to browse the available entities, their properties and the actions your application can perform. Before trying it out, make sure to read the Authentication section above.