Batch Resource

Batching allows you to combine instructions for several operations in a single HTTP request. You can also specify dependencies between related operations in your request.

Use the following POST request to perform multiple operations:

POST/batch

Batched operations are performed one by one, independently from each other’s results. Even if an operation in the middle fails, the previous ones are not cancelled, and the next operations are still performed.

Structure of Request and Response

To make a batched request, you need to build a JSON object that describes each individual operation you’d like to perform, and POST this JSON to the actiTIME API endpoint. JSON format is following:

[
  {
    "method": "POST",
    "relativeUrl": "/customers",
    "body": {"name": "New Customer"}
  },
  {...}
]

where:

  • method – HTTP method (GET, PATCH, POST, DELETE). Method must be written in capital letters;
  • relativeUrl – the part of the URL after ‘<actiTIME URL>/api/v1/’ of a regular API request;
  • body – mandatory for POST and PATCH requests, not supported for GET and DELETE requests.

The Batch API returns an array of responses where the n-th element corresponds to the n-th element in batch request array. The response has the following format:

[
  {
    "status": 200,
    "body": {
      "id": 39,
      "name": "New Customer",
      "archived": false,
      "created": 1554220372034,
      "allowedActions": {
        "canModify": true,
        "canDelete": true
      },
      "description": null
    }
  },
  {...}
]

where:

  • status – status code of the sub-request;
  • body – body of the sub-request’s response (equivalent to the response returned after executing a single operation).

Also you can specify the ‘includeResponseBody’ parameter that defines whether the response body should be returned for sub-requests.

For POST/batch request possible values are: ‘always’, ‘never’, ‘get’ (‘get’ value means that only response bodies for GET sub-requests will be returned). For sub-requests possible values are: ‘true’ and ‘false’.
The parameter specified for sub-request always has higher priority than the parameter specified for POST/batch request.

The following request creates 3 new projects in a customer with ID = 7.

Request Body:

[
  {
    "method": "POST",
    "relativeUrl": "/projects",
    "body": {"name": "Project 1", "customerId": 7}
  },
  {
    "method": "POST",
    "relativeUrl": "/projects",
    "body": {"name": "Project 2", "customerId": 7}
  },
  {
    "method": "POST",
    "relativeUrl": "/projects",
    "body": {"name": "Project 3", "customerId": 7}
  }
]

Request:

curl -X POST "<actiTIME URL>/api/v1/batch?includeResponseBody=always" -H "accept: application/json" -H "Content-Type: application/json" -u "username:password" -d "[ { \"method\": \"POST\", \"relativeUrl\": \"/projects\", \"body\": {\"name\": \"Project 1\", \"customerId\": 7} }, { \"method\": \"POST\", \"relativeUrl\": \"/projects\", \"body\": {\"name\": \"Project 2\", \"customerId\": 7} }, { \"method\": \"POST\", \"relativeUrl\": \"/projects\", \"body\": {\"name\": \"Project 3\", \"customerId\": 7} }]"

Response:

[
  {
    "status": 200,
    "body": {
      "id": 32,
      "customerId": 7,
      "name": "Project 1",
      "archived": false,
      "created": 1554221535890,
      "allowedActions": {
        "canModify": true,
        "canDelete": true
      },
      "description": null
    }
  },
  {
    "status": 200,
    "body": {
      "id": 33,
      "customerId": 7,
      "name": "Project 2",
      "archived": false,
      "created": 1554221536008,
      "allowedActions": {
        "canModify": true,
        "canDelete": true
      },
      "description": null
    }
  },
  {
    "status": 200,
    "body": {
      "id": 34,
      "customerId": 7,
      "name": "Project 3",
      "archived": false,
      "created": 1554221536109,
      "allowedActions": {
        "canModify": true,
        "canDelete": true
      },
      "description": null
    }
  }
]

Dependencies Between Operations in the Request

Sometimes operations in a batch request should be dependent – the output of one operation needs to be used as input data for the next operation. To reference the results of the previous operation in the next one, set an ID to the parent operation, and then reference its results in the body of the child operation. Parent operation should be executed earlier than its child operations.

Please note that described referencing is only supported for POST and PATCH requests.

The following request creates a new customer and then creates a new project in that customer.

Request Body:

[
  {
    "id": "one",
    "method": "POST",
    "relativeUrl": "/customers",
    "body": {"name": "First Customer"}
  },
  {
    "method": "POST",
    "relativeUrl": "/projects",
    "body": {"name": "First Project", "customerId": "$one.id"}
  }
]

where:

  • id – identifier of the batch sub-request;
  • $one.id – ‘$one’ is the reference to the parent sub-request with id=’one’, ‘id’ – is the field from the response of the parent sub-request, this field’s value is to be used in the child request.

Request:

curl -X POST "<actiTIME URL>/api/v1/batch?includeResponseBody=always" -H "accept: application/json" -H "Content-Type: application/json" -u "username:password" -d "[ { \"id\": \"one\", \"method\": \"POST\", \"relativeUrl\": \"/customers\", \"body\": {\"name\": \"First Customer\"} }, { \"method\": \"POST\", \"relativeUrl\": \"/projects\", \"body\": {\"name\": \"First Project\", \"customerId\": \"$one.id\"} }]"

Response:

[
  {
    "id": "one",
    "status": 200,
    "body": {
      "id": 40,
      "name": "First Customer",
      "archived": false,
      "created": 1554222181963,
      "allowedActions": {
        "canModify": true,
        "canDelete": true
      },
      "description": null
    }
  },
  {
    "status": 200,
    "body": {
      "id": 35,
      "customerId": 40,
      "name": "First Project",
      "archived": false,
      "created": 1554222182325,
      "allowedActions": {
        "canModify": true,
        "canDelete": true
      },
      "description": null
    }
  }
]

More info on using this request is available available in Swagger at the following URL:
<your actiTIME URL>/api/v1/swagger

Errors Processing

The POST/batch request returns standard status codes but note that if the POST/batch request has returned 200 (OK) code, it does not mean that all of enclosed sub-requests have been successful.

If a sub-request fails (for example, you don’t have the permission to perform the operation), its error code is returned in its response body but the POST/batch request can still return 200 (OK) status code.

Rate Limiting

General rate limiting is applied to POST/batch requests (see more details in the Overview/Rate Limiting section).

Sub-requests are limited to 100 requests per batch, and each sub-request within the batch is counted as a single request for rate limiting purposes.

Rate limit headers of the response define the limits at the time of executing the last sub-request. If the limit is exceeded, POST/batch will return status code 200 (OK), but all sub-requests will have status code 429 (Too Many Requests).