Getting started
Requests
Our API is a collection of 'RESTful' web services. You interact with our resources by sending an HTTP message to a URL. The URL determines the resource and the HTTP method defines the type of action.
Authentication
All requests must include an Authorization header with a valid access_token. See Security for more details on access_tokens.
HTTP Methods
These are the methods our apis support. Not all methods are implemented for all resources.
We prefere the use of PATCH over PUT, so the PUT is rarely used in our endpoints. |
Method | Description |
---|---|
GET |
Get a resource |
PUT |
Replace a resource |
POST |
Add a resource |
DELETE |
Delete a resource |
PATCH |
Update properties on a resource |
Request structure
Requests to our APIs have the following structure:
https://<host>/<api-version>/<domain>/(<resource/\{id\})*>?(query-parameters)
POST https://<host>/v1/surveys/p1231234/respondents HTTP/1.1
Accept: application/json
Authorization: Bearer <access_token>
Content-Type: application/json
{
"email": "test@forsta.com",
"city": "oslo",
"country": "norway"
}
Request Headers
Name | Syntax | Description | Example |
---|---|---|---|
Accept |
Accept: <MIME-type>/* |
Indicates which MIME types the client is capable of understanding. During content negotiation, the server should select which of the MIME types for the response. That choice is communicated back to the client using the Content-Type response header. |
Accept: application/json |
Authorization |
Authorization: <type> <credentials> |
Specifies the credentials of the client to authenticate with a service. All services must support the Authorization header. |
Authorization: Bearer c1das334aff |
If-Match |
If-Match: <etag_value> |
Specifies a conditional request to only return the resource when it does match one of the included ETag values. All services must support the If-Match header provided they support the ETag response header. |
If-Match: ID-123123 |
If-None-Match |
If-None-Match: <etag_value> |
Specifies a conditional request to only return the resource when it doesn’t match one of the included ETag values. All services must support the If-None-Match header provided they support the ETag response header. |
If-None-Match: ID-123123 |
Paging
You can control the number of items returned when requesting a resource collection by using the query parameters below. We call the collection of items returned a "page".
Parameter | Type | Description | Example |
---|---|---|---|
pageSize |
Integer |
The number of items per "page". If not specified, 100 items will be returned. |
GET https://...?pageSize=50 |
page |
Integer |
The index of the "page" to return. If not specifed, the first "page" will be returned. |
GET https://...?page=2 Returns the second page of 100 items, numbered 101-200. GET https://...?pageSize=30&page=1 Returns the first page of 30 items, numbered 1-30. GET https://...?pageSize=30&page=4 Returns the fourth page of 30 items, numbered 91-120. |
Responses
An HTTP Response is what you get when you make an HTTP Request.
There are two important properties of a response that you should care about:
-
HTTP Status Code - this tells you at a protocol level what the status of the response is
-
Response Payload - this is the body of the response. It is in a standard format that will give you the application level status, the results, and if applicable, any errors.
Response Formats
All responses are returned using JSON. JSON is a lightweight serialization language that is compatible with many different languages. JSON is syntactically correct JavaScript code, meaning you can use the Javascript eval() function to parse it.
Response Payload
We comply with HATEOAS, or Hypermedia As The Engine Of Application State. This means that our Rest APIs are accessible through the use of hypermedia links, and that all resources returned by our APIs contains a "links" property.
{
"id": 15,
"name": "John Doe",
"links": {
"self": "/resource/15",
"sub-resource": "/resource/15/sub-resource"
}
}
{
"itemCount": 100,
"totalCount": 23533,
"items": [
{
"id": 14,
"name": "test1"},
{
"id": 16,
"name": "test2"}
],
"links": {
"item": "/resource/{id}", (1)
"self": "/resource?pageSize=100&page=1",
"next": "/resource?pageSize=100&page=2",
}
}
1 | The item-link is used to get the link to an individual item in the collection. The {id} parameter is replaced with the "id"-property on the item itself. |
HTTP Status Codes
Our REST APIs use standard HTTP status codes to indicate success or failure of API calls. Below are the most common codes our APIs support. To learn more about Status Codes, see Wikipedia.
HTTP Status Code | Message | Description |
---|---|---|
200 |
OK |
The request was processed and returned successfully. Nothing was changed. |
201 |
Created |
The new resource was created successfully |
400 |
Bad Request |
Problem with the request, such as a missing, invalid or type mismatched parameter |
401 |
Unauthorized |
The request did not have valid authorization credentials |
403 |
Forbidden |
Private data you are not allowed to access, or you’ve hit a rate limit. |
404 |
Not Found |
Your URL is wrong, or the requested resource doesn’t exist |
500 |
Server Error |
Internal server error. If this persists, please contact support. |
503 |
Service Unavailable |
Our API is down. Please try again later. |
Dates and Times
We support the ISO 8601 format for passing in dates and times. This allows for a very flexible array of options, allowing you to pass in the level of detail you need to.
The full representation of a date and time is of the format:
yyyy-MM-ddTHH:mm:ss.SSSZ
Date and time values generated by our APIs will be relative to the location of the API Web Server.
If the server is located in Paris, France, a resource with a "CreatedDate" property populated by the server would be returned by the server as the example below.
The +01:00 suffix to the "CreateDate" property indicates that the time is one hour ahead of Greenwich Mean Time (GMT), as Paris is in Central European Standard Time (CEST).
See ISO 8601 for more details.
{
"id": 15,
"createdDate": "2018-10-10T12:30:10.123+01:00",
}
Security
Access tokens
All requests to our APIs need to be authenticated. This authentication is done using access_tokens (Oauth 2.0). To get an access_token you must call our token end-point and supply your ClientId and ClientSecret. Access_tokens remain valid for a limited time.
ClientIds and ClientSecrets are provided by our support organization. Please contact forstasupport@forsta.com to obtain them.
The token should ideally be cached and re-used for all requests made within the time the token is valid. |
POST https://<host>/identity/connect/token HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded
client_id=<ClientId>&client_secret=<ClientSecret>&grant_type=api-user&scope=(1)
1 | The scope indicates which API you can access. You get this when receiving your client_id and client_secret. Ex. scope=pub.surveys will indicate that you ask for a token that has access to the public survey api. |
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: ~
{
"access_token":"4cb63760cb19552fc5cde5f37b649b7c",
"expires_in":3600,
"token_type":"Bearer"
}
API Versions
Our APIs are versioned in the url to the API.
Ex. http://<host>/v1/<domain> indicates that you are using version 1 of the API
Currently, our APIs are on version 1 only.
API Limits
Our public APIs have the following limits per client:
-
maximum 20 requests per second
-
maximum 1000 requests within 15 minutes
-
maximum 10000 requests within 12 hours
The number of requests are counted towards each API individually.
Exceeding the above limits will result in a 429 response from the API.
SurveyData Limits
The SurveyData endpoints '/responses/data' and 'respondents/data' habe a max PageSize of 10000 records for paged responses. PageSize larger than 10000 will result in a BadRequest (400) response. Our streaming response is not affected by this limit. See "Interact with Response Data" for more info.