# Instock API reference(0.1.0)

This reference is a comprehensive guide to understanding of Instock API and is aimed to help developers to integrate their Host system with Instock Cloud (Incloud).

Instock API is REST-based. It has predictable resource URLs, accepts JSON in the HTTP body, returns JSON-encoded responses, and uses standard HTTP response codes to indicate errors, methods, and authentication. Our API uses `GET`, `POST`, `PUT` methods to perform all operations. `GET` method is both used for retrieval of a single or listing multiple objects at once.

## Overview
### Conventions
- HTTPS is required for all requests. Requests over plain HTTP will fail.
- All requests without authentication will fail.
- Bulk request is supported only to upload articles into Incloud.
- Property names are in `snake_case` (not `camelCase` or `kebab-case`).
- Temporal values (datetimes) are encoded in [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) strings, e.g. `2022-06-06T12:37:00Z`.
- All path parameters are always returned in response body, except for `POST` and `PUT` methods.

### Authentication
Instock API offers authentication in form of Bearer token. Bearer token must be present in each request header. The token provides full access to all resources and methods of Instock API to its client.

**Note**: currently Bearer token is issued by Instock and supplied to API users during onboarding.

For example, if you'd like to retrieve sites available to your organization, your request will look like:

```curl
curl -X GET
  -H 'Content-Type: application/json' \
  -H 'Authorization: {access_token}' \
  https://api.instock.com/v1/sites \
```

### Errors
Instock API always returns errors in a common format. For example:

```json
{
  "code": "bad_request",
  "message": "Request body/path/query params cannot be validated."
}
```

The `code` indicates the general class of error read by your Host system. The `message` is a human-readable explanation of what went wrong.

### Common HTTP error code responses
| **HTTP code** | **Code** | **Description** | **Potential solution** |
| --- | --- | --- | --- |
| 400 | `bad_request` | The request could not be understood. | Ensure that syntax is correct in parameters of request and its body. |
| 400 | `resource_cannot_be_created` | Resource may already exist or has certain creation rules. | Ensure that resource doesn't already exist or it doesn't have any restrictions for creation. For bulk operations, ensure that all objects are valid. |
| 400 | `resource_cannot_be_updated` | Resource has certain update rules. | Ensure that resource doesn't have any restrictions that can yield this error. |
| 401 | `unauthorized` | Requestor is unauthorized. | Ensure that your access token is valid. |
| 403 | `forbidden` | Requestor does not have permissions to perform an operation. | Ensure that your access token has permissions to perform an operation. |
| 404 | `resource_not_found` | Resource doesn't exist. | Ensure that the resource is correctly identified by ID. |
| 500 | `internal_server_error` | Something went wrong on our end. | An unexpected error occurred. Reach out to Instock for support.

### Request IDs
Instock API auto-generates request identifier with each API response. You can find this value in the response headers as `Instock-Request-ID`. Use it to refer to a specific request when debugging or reaching out to Instock for support.

```
Instock-Request-ID: request_id
```

### Correlation IDs
You can optionally extend your request and add `Instock-Correlation-ID` to the header. Use it to analyze incorrect and faulty behavior across your Host system. For example, if you'd like to retrieve sites available to your organization and pass `Instock-Correlation-ID`, your request will look like:

```curl
curl -X GET
  -H 'Content-Type: application/json' \
  -H 'Authorization: your-token' \
  -H 'Instock-Correlation-ID: your-correlation-id' \
  https://api.instock.com/v1/sites \
```

### Pagination
Endpoints that return a list of objects use pagination. Instock API uses cursor-based pagination.
This approach allows the Host system to request a part of the list, receiving results and `next_cursor` in the response.
The latter could be used to access the next part of the list.

**Note**: setting `page_size` lesser than 10 or greater than 1000 will yield an error.

| Parameter | Request/Response | Type | Description |
| --- | --- | --- | --- |
| `start_cursor` | Request | string<br>(optional) | Cursor returned from a previous response, used to request the next page of the results. |
| `page_size` | Request | string<br>(optional) | The number of objects returned in response. <br>Has default and maximum values. |
| `has_more` | Response | bool | If `true`, use `next_cursor` to access the next part of the list. <br>If `false`, response includes the end of the list. |
| `next_cursor` | Response | string | Only available when `has_more` is `true`. <br>Used to retrieve the next page of results by passing the value as the `start_cursor` parameter to the same endpoint. |

### Unique identifiers
Throughout API reference below, you will encounter multiple unique identifiers (UIDs) that are required to perform certain operations. For example, to create a customer order, your Host system must:
- provide `site_id` to specify the exact instance of Instock ASRS installation,
- and supply `order_id`. Usually `order_id` value corresponds to the ID of an order that Host system has.

The table below indicates the source (which system issues UID) and scope (at what level UID must be unique).

| ID | Source | Scope | Description |
| --- | --- | --- | --- |
| `org_id` | Instock | Global | ID assigned to your organization by Instock. |
| `site_id` | Instock | Global | ID assigned to an individual Instock site that belongs to your organization. |
| `article_id` | Host | Organization | ID of a product/SKU uploaded by Host system to Incloud. |
| `order_id` | Host | Organization | ID of an order created by Host system in Incloud. |
| `ordertask_id` | Instock | Organization | ID of an individual chunk of order fulfillment. |

### Additional attributes
Every article and order contain `attributes`, which are reserved for custom and pre-defined parameters that your organization may require for fulfillment-related operations.

#### Custom attributes
Before integration, your IT and Instock teams should agree upon `attributes` that will be configured specifically for your site(s). Incloud will consume these attributes to perform certain operations throughout fulfillment process, e.g. decanting, picking. Attributes can be added or updated in two ways: via API during operations such as customer order creation or through the workstation UI during operation at ASRS, like decanting.

##### Order attributes
For example, `cutoff_time` for a customer order — the time when order fulfillment starts, i.e. change its status from `registered` to `reserved`.

```json
{
  "org_id": "org_id_001",
  "site_id": "1.1.0-1",
  "order_id": "order_id_001",
  "kind": "customer",
  "placed_at": "2022-03-05T07:38:39Z",
  "attributes": {
    "cutoff_time": "2022-03-05T16:00:00Z"
  },
  "lines": [
    { 
      "line_id": "00132455-1",
      "article_id": "1003000031678",
      "qty": 1 
    } 
  ] 
}
```

### Available API methods
The table below contains the summary of available API methods for the Instock API client.

| Resource | Available API methods |
| --- | --- |
| Sites | `GET` - List all sites |
| Articles | `POST` - Upload article(s)<br>`GET` - List all articles<br>`GET` - Retrieve article<br>`PUT` - Update article |
| Orders | `POST` - Create customer order<br>`GET` - List all orders<br>`PUT` - Update customer order<br>`GET` - Retrieve order<br>`GET` - Retrieve order status<br>`POST` - Advance order status (debug)<br>`DELETE` - Cancel registered order |
| Ordertasks | `GET` - Retrieve ordertask |
| Inventory | `GET` - List all articles inventory<br>`POST` - Retrieve multiple articles inventory<br>`PUT` - Adjust article inventory (debug)<br>`GET` - Retrieve article inventory |
| Moves | `GET` - List all articles moves<br>`GET` - Retrieve article moves |

## Sites
Each Instock site (or just site) represents a single instance of Instock ASRS. Such instance can represent either physical installation of ASRS or a simulation in the sandbox environment. Organization may own many sites. A single physical site may have many sandboxes and each sandbox will be characterized by its own `site_id`.

**Note**: `site_id` is required to perform operations with orders, ordertasks, inventory, and moves.

### List all sites
get/sites

https://api.instock.com/v1/sites

Returns a list of sites available to your organization and their properties.

##### Authorizations:

_bearerAuth_

### Responses
**200**
Successful operation

### Request samples
```bash
curl -X GET 'https://api.instock.com/v1/sites' \
-H 'Authorization: Bearer {ACCESS_TOKEN}'
```

### Response samples
- 200
- 400
- 401
- 403
- 500

```json
{
  "sites": [
    {
      "site_id": "1.1.0-1",
      "is_virtual": true
    },
    {
      "site_id": "1.1.0-2",
      "is_virtual": false 
    }
  ]
}
```

### Articles
Instock is using the term `article` to describe unique product or SKU managed by Instock ASRS. Articles resource is mostly managed by you as a client of Instock API. Article data is shared across all sites that belong to your organization.

### Upload article(s)
post/articles

https://api.instock.com/v1/articles

Uploads single or multiple articles to your Instock organization account.

**Note**:
- if a particular article is not uploaded to your organization, warehouse operators won't be able to receive it into Instock ASRS (decant).
- if bulk article upload contains at least one article that cannot be validated, Incloud will yield `400` and the entire request will fail.
- bulk article upload has a limit of maximum 1000 articles per request.

##### Authorizations:

_bearerAuth_

### Request Body schema: application/json
|     |                             |
|-----|-----------------------------|
| articles | Array of objects   |

### Responses
**200**
Successful operation.

### Request samples
```json
{
  "articles": [
    {
      "article_id": "116000487727",
      "name": "Cheerios Original Cereal, 12 Oz",
      "is_serial_numbered": false,
      "dimensions": {
        "x": "7.75",
        "y": "12",
        "z": "2.75",
        "uom": "in"
      },
      "attributes": {
        "product_category_name": "Cereals & Bars",
        "temp_zone": "ambient"
      }
    }
  ]
}
```

### List all articles
get/articles

https://api.instock.com/v1/articles

Returns a paginated list of all articles known within your organization account.

##### Authorizations:

_bearerAuth_

### Request samples
```bash
curl -X GET 'https://api.instock.com/v1/articles' \
-H 'Authorization: Bearer {ACCESS_TOKEN}'
```

### Response samples
- 200
- 400
- 401
- 403
- 500

```json
{
  "has_more": false,
  "next_cursor": "",
  "articles": [
    {
      "article_id": "1003000031678",
      "name": "Quaker Apples and Cinnamon Instant Oatmeal Packets",
      "is_serial_numbered": false,
      "dimensions": {
        "x": "4.9",
        "y": "7.9",
        "z": "3.1",
        "uom": "m"
      },
      "attributes": {
        "product_category_name": "Cereals & Bars",
        "temp_zone": "ambient",
        "promotion_price": "2.99"
      }
    }
  ]
}
```

### Get article
get/articles/{article_id}

https://api.instock.com/v1/articles/{article_id}

Retrieves a single existing article. Supply `article_id` either from article upload or articles list request, and Instock will return the corresponding article data.

##### Authorizations:

_bearerAuth_

### Response samples
- 200
- 400
- 401
- 403
- 404
- 500

```json
{
  "article_id": "116000487727",
  "name": "Cheerios Original Cereal, 12 Oz",
  "is_serial_numbered": false,
  "dimensions": {
    "x": "7.75",
    "y": "12",
    "z": "2.75",
    "uom": "in"
  },
  "attributes": {
    "product_category_name": "Cereals & Bars",
    "temp_zone": "ambient"
  }
}
```

### Update article
put/articles/{article_id}

https://api.instock.com/v1/articles/{article_id}

Updates a single existing article by setting the values of parameters passed.

**Note**:
- article update operation is performed via `PUT` method — when updating an article, a complete order record (all fields) must be passed.
- if `article_id` has inventory moves, Incloud will yield `400` error. In other words, if an article has already been decanted into ASRS, its properties cannot be updated as Incloud already relies on its properties.

##### Authorizations:

_bearerAuth_

### Request Body schema: application/json

|     |        |
|-----|--------|
| article_id | string (articleId)   |
| name | string   |
| is_serial_numbered | boolean   |
| dimensions | object   |
| attributes | object   |

### Responses
**200**
Successful operation.

### Request samples
```json
{
  "article_id": "116000487727",
  "name": "Cheerios Original Cereal, 12 Oz",
  "is_serial_numbered": false,
  "dimensions": {
    "x": "7.75",
    "y": "12",
    "z": "2.75",
    "uom": "in"
  },
  "attributes": {
    "product_category_name": "Cereals & Bars",
    "temp_zone": "ambient",
    "promotion_price": "1.69"
  }
}
```

## Orders
Intentions of users of Instock ASRS are represented by `orders` structure.
Orders resource allows:
- create/update/retrieve records for picking of goods from the ASRS (`customer` orders)
- retrieve-only access to records for induction/adjustment/extraction of inventory (`adjustment`, `reception`, `extraction` orders)

All operations with orders are performed in scope of a particular site and require `site_id` as a path parameter.
The following kinds and statuses of orders are in use:

| Order Kind | Description |
| --- | --- |
| `customer` | order that needs to be fulfilled from ASRS and are placed by you, as client of API. |
| `adjustment` | order to correct current inventory. |
| `reception` | order to receive goods or assets into ASRS, triggered by shipment from supplier, return of goods, etc. |
| `extraction` | order to extract assets from ASRS. |

| Order Status | Description |
| --- | --- |
| `registered` | order registered and awaiting fulfillment in scope of ordertask(s). |
| `reserved` | fulfillment in progress. |
| `done` | order has been fulfilled. |
| `canceled` | order has been canceled. |

## Create customer order
post/{site_id}/orders

https://api.instock.com/v1/{site_id}/orders

Creates a single new customer order within a particular site of your organization.

**Note**: if `lines` object contains a line with an article that is not uploaded, Incloud will yield `404` and request will fail.

### Responses
**200**
Successful operation.

### Request samples
```json
{
  "org_id": "org_id_001",
  "site_id": "1.1.0-1",
  "order_id": "00132455",
  "kind": "customer",
  "placed_at": "2022-03-05T07:38:39Z",
  "attributes": {
    "property1": "string",
    "property2": "string"
  },
  "lines": [{
    "line_id": "00132455-1",
    "article_id": "1003000031678",
    "qty": 1
  }]
}
```

### List all orders
get/{site_id}/orders

https://api.instock.com/v1/{site_id}/orders

Returns a paginated list of all orders within a specific site of an organization.

### Response samples
- 200
- 400
- 401
- 403
- 404
- 500

```json
{
  "has_more": false,
  "next_cursor": "",
  "org_id": "org_id_001",
  "site_id": "1.1.0-1",
  "orders": [
    {
      "order_id": "00132457",
      "site_id": "1.1.0-1",
      "kind": "customer",
      "placed_at": "2022-03-06T12:45:09Z",
      "attributes": {
        "property1": "string",
        "property2": "string"
      },
      "lines": [{
        "line_id": "00132457-1",
        "article_id": "116000275270",
        "qty": 1
      }]
    }
  ]
}
```

### Update customer order
put/{site_id}/orders/{order_id}

https://api.instock.com/v1/{site_id}/orders/{order_id}

Updates a single existing order with kind `customer`. Only `registered` orders can be updated.

### Request samples
```json
{
  "org_id": "org_id_001",
  "site_id": "1.1.0-1",
  "order_id": "00132455",
  "kind": "customer",
  "placed_at": "2022-03-05T07:38:39Z",
  "attributes": {
    "property1": "string",
    "property2": "string"
  },
  "lines": [{
    "line_id": "00132455-1",
    "article_id": "1003000031678",
    "qty": 2
  }]
}
```

### Retrieve order status
get/{site_id}/orders/{order_id}/status

https://api.instock.com/v1/{site_id}/orders/{order_id}/status

Retrieves a single existing order data and its ordertask status.

### Request samples
```bash
curl -X GET 'https://api.instock.com/v1/{site_id}/orders/{order_id}/status' \
-H 'Authorization: Bearer {ACCESS_TOKEN}'
```

### Response samples
- 200
- 400
- 401
- 403
- 404

todo
