# API specification

In addition to the [core commerce API](https://docs.commercelayer.io/), Commerce Layer exposes a fast **Metrics API** that lets you extract relevant metric data from your organizations.

{% hint style="info" %}
Commerce Layer Metrics API is currently released in **open beta**. It has completed intensive internal testing, as well as being tested by a carefully selected range of external users, so that we feel it is now as bug-free as possible and is therefore ready to be safely used by a broader set of customers. We strongly encourage you to try it out and provide any kind of feedback that could help us fine-tune the API behavior. Based on that and on our constant monitoring of the API usage as it is tested by a larger audience we'll adjust the API features and any other opinionated detail (rate limits, default values, and more).
{% endhint %}

Commerce Layer Metrics API is an **HTTP** API that supports different types of [queries](https://docs.commercelayer.io/metrics/getting-started/queries) and the option to [filter](https://docs.commercelayer.io/metrics/getting-started/filters) the results.

{% hint style="warning" %}
All the **strings** passed to the API must be [UTF-8](https://en.wikipedia.org/wiki/UTF-8) encoded. `date-time` [strings parameters](https://swagger.io/docs/specification/data-models/data-types/#string) must comply with the [ISO 8601](https://www.w3.org/TR/NOTE-datetime) standard (complete date plus hours, minutes, and seconds — more info [here](https://docs.commercelayer.io/metrics/filters#date-formats)).
{% endhint %}

The guide that follows is your reference for all the operations ([breakdown](https://docs.commercelayer.io/metrics/getting-started/queries/breakdown), [date breakdown](https://docs.commercelayer.io/metrics/getting-started/queries/date-breakdown), [stats](https://docs.commercelayer.io/metrics/getting-started/queries/stats), and [search](https://docs.commercelayer.io/metrics/getting-started/queries/search)) that you can perform on the resource available to do statistics on ([orders](https://app.gitbook.com/s/lhTYC557IzGiJNS84RKD/resources/orders), [returns](https://app.gitbook.com/s/lhTYC557IzGiJNS84RKD/resources/returns), and [carts](https://app.gitbook.com/s/lhTYC557IzGiJNS84RKD/resources/carts)) and contains all the information you need to get a comprehensive overview of how it works.

### Base endpoint

All API requests must be made over [HTTPS](http://en.wikipedia.org/wiki/HTTP_Secure) to the following base endpoint:

```http
https://{{your_domain}}.commercelayer.io/metrics
```

Where `{{your_domain}}` is the unique subdomain of your Commerce Layer organization.

### Authorization <a href="#authorization" id="authorization"></a>

You need to [authenticate](https://docs.commercelayer.io/core/authentication) to Commerce Layer core API and get an **integration** or a **webapp** access token. The Metrics API results will be automatically filtered (in terms of organizations and markets) according to the [scopes](https://docs.commercelayer.io/core/authentication#authorization-scopes) included in the token.

### Headers <a href="#http-request-headers" id="http-request-headers"></a>

Include the following HTTP request headers when making calls to the Metrics API endpoint:

<table><thead><tr><th>Header</th><th data-type="checkbox">Required</th><th>Details</th></tr></thead><tbody><tr><td><strong>Accept</strong></td><td>true</td><td>Must be <code>application/vnd.api.v1+json</code> (learn more about <a href="#undefined">versioning</a>)</td></tr><tr><td><strong>Content-Type</strong></td><td>true</td><td>Must be <code>application/vnd.api+json</code></td></tr><tr><td><strong>Authorization</strong></td><td>true</td><td>Must be <code>Bearer {{your_access_token}}</code></td></tr></tbody></table>

Where `{{your_access_token}}` is the access token you get by [authenticating](#authorization) to Commerce Layer core API.

### API versioning

The **Accept** header will be also used to manage future versioning. You'll be able to request a specific version of the Metrics API just by changing it as follows:

```
Accept: application/vnd.api.v{{version}}+json
```

Where `{{version}}` is the unique progressive number that identifies the version you want to use.

{% hint style="info" %}
The latest version of the Metrics API is **v1** — use `application/vnd.api.v1+json` as the **Accept** header to make your calls.
{% endhint %}

### Resources

The Commerce Layer [core resources](https://app.gitbook.com/o/-Lfu_B3DKew-kvoEWzTk/s/RWJeylueWkzLadK710XZ/) you can do statistics on using the Metrics API currently are:

| Resource    | Endpoint   | Description                                                                                                                                                      |
| ----------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Orders**  | `/orders`  | Your organization [orders](https://docs.commercelayer.io/core/v/api-reference/orders) (*draft* and *pending* ones excluded), filtered by the market(s) in scope. |
| **Returns** | `/returns` | Your organization [returns](https://docs.commercelayer.io/core/v/api-reference/returns), filtered by the market(s) in scope.                                     |
| **Carts**   | `/carts`   | Your organization *draft* and *pending* [orders](https://docs.commercelayer.io/core/v/api-reference/orders), filtered by the market(s) in scope.                 |

{% hint style="info" %}
Given the definitions above, *draft* and *pending* orders act as **Carts**, so if you want to do statistics on that kind of orders you need to make requests to the `/carts` endpoint. As soon as an order is *placed* it is moved to the **Orders** collection, so if you want to do statistics on that kind of orders you need to make requests to the `/orders` endpoint. For cross-statistics on the two kinds of orders (e.g. the total number of orders, whether or not they were placed, over a specific date and time range), you need to perform the same query both on the `/carts` and on the `/orders` endpoints and add additional logic based on the specific use case (e.g. summing the values returned by the two queries).
{% endhint %}

### Query types

Commerce Layer Metrics API lets you retrieve metric data through four types of [queries](https://docs.commercelayer.io/metrics/getting-started/queries):

| Query type         | Endpoint          | Description                                                                                                                                                              |
| ------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Breakdown**      | `/breakdown`      | Returns the value of the computation (based on the selected operator) on the selected field, aggregated by another field.                                                |
| **Date breakdown** | `/date_breakdown` | Returns a list by date of the values of the computation (based on the selected operator) on the selected field, over the selected time interval (e.g. day, month, etc.). |
| **Stats**          | `/stats`          | Returns the value of the computation (based on the selected operator) on the selected field.                                                                             |
| **Search**         | `/search`         | Returns the list of the requested fields of the actual records that match the query.                                                                                     |

### Request

{% hint style="info" %}
Metric data requests are submitted to the Metrics API through a **`POST`** request. Any other method will return an error ([see example](https://docs.commercelayer.io/metrics/errors#405-method-not-allowed)).
{% endhint %}

To build the **endpoint** you need to make your requests just add the name of the [resource](#resources) you want to do statistics on and the [type of query](#query-types) you'd like to perform to the [base endpoint](#base-endpoint), like so:

```http
https://{{your_domain}}.commercelayer.io/metrics/{{resource_name}}/{{query_type}}
```

The JSON data **payload** you need to send in the request body is composed of three main blocks:

```json
{
  "{{query_type}}": {
    "...": ...,
    // query keys
    "...": ...
  },
  "filter": {
    "{{field_name}}": {
      "...": ...,
      // filter parameters
      "...": ...
    }
  },
  "meta": {
    "...": ...
    // meta options
    "...": ...
  }
}
```

#### Query

The `query` object is required and specifies the type of query you're going to perform (one of [breakdown](https://docs.commercelayer.io/metrics/queries/breakdown#request), [date breakdown](https://docs.commercelayer.io/metrics/queries/date-breakdown#request), [stats](https://docs.commercelayer.io/metrics/queries/stats#request), or [search](https://docs.commercelayer.io/metrics/queries/search#request)) and the related fields, operators, and limits.

#### Filter

The `filter` object is optional (if missing a [default filter](https://docs.commercelayer.io/metrics/filters#default-filter) will be used) but you'll likely want to use it to narrow the results of the query by date or any other parameter available for filtering the selected resource.

#### Meta

The `meta` object is optional and can be used to customize the information that will be returned in the [corresponding object](#meta-1) of the response. At the moment the only option available for this block is:

<table><thead><tr><th>Key</th><th>Type</th><th data-type="checkbox">Required</th><th>Description</th><th>Value</th></tr></thead><tbody><tr><td><strong><code>payload</code></strong></td><td>Boolean</td><td>false</td><td>If <code>true</code> the actual payload used to perform the query will be returned in the response.</td><td>Default is <code>false</code>.</td></tr></tbody></table>

```json
{
  "{{query_type}}": { ... },
  "filter": { ... },
  "meta": {
    "payload": true
  }
}
```

{% hint style="info" %}
Being their response a plain CSV file, the meta object is **not** returned by [export](https://docs.commercelayer.io/metrics/getting-started/queries/export) queries.
{% endhint %}

### Response

On success, the API responds with a `200 OK` status code, returning a response in the JSON format. The successful response is composed of two main blocks:

```json
{
  "data": ... ,
  "meta": { ... }
}
```

#### Data

`data` contains the actual results of the query, filtered accordingly. Its structure depends on the type of query you're performing. It can be a collection ([date breakdown](https://docs.commercelayer.io/metrics/queries/date-breakdown#response) and [search](https://docs.commercelayer.io/metrics/queries/search#response)) or a single object ([breakdown](https://docs.commercelayer.io/metrics/queries/breakdown#response) and [stats](https://docs.commercelayer.io/metrics/queries/stats#response)). The returned fields will be detailed case by case, with some examples in the related [sections](https://docs.commercelayer.io/metrics/getting-started/queries).

#### Meta

The `meta` object contains useful information about the query itself. It has the same structure for all the queries (except for the `pagination` key, which is present in the [search queries](https://docs.commercelayer.io/metrics/queries/search#pagination) response only):

```json
{
  "data": ... ,
  "meta": {
    "pagination": {
      "record_count": 123,
      "cursor": "LS0tCi0gJzIwMjItMDYtMTNUMTQ6=="
    },
    "type": "{{query_type}}",
    "trace_id": "32ef0bfb-39ff-409b-b98f-6433da2f8e09",
    "mode": "test",
    "organization_id": "xYZkjABcde",
    "market_ids": [ "yzXKjYzaCx", "..." ],
    "payload": {
      "{{query_type}}": { ... },
      "filter": { ... }
    }
  }
}
```

| Field                 | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| --------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`pagination`**      | Object | Contains the total `record_count` and the `cursor` pointing at the next page, useful to navigate through the [search](https://docs.commercelayer.io/metrics/queries/search#pagination) results (not available for [breakdowns](https://docs.commercelayer.io/metrics/getting-started/queries/breakdown), [date breakdowns](https://docs.commercelayer.io/metrics/getting-started/queries/date-breakdown), and [stats](https://docs.commercelayer.io/metrics/getting-started/queries/stats)). |
| **`type`**            | String | The query type (one of `breakdown`, `date_breakdown`, `stats`, or `search`).                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **`trace_id`**        | String | The ID of the user's web request, useful for debugging in case of [errors](https://docs.commercelayer.io/metrics/getting-started/errors).                                                                                                                                                                                                                                                                                                                                                    |
| **`mode`**            | String | The resource environment (one of `test` or `live`), read from the access token used to perform the request.                                                                                                                                                                                                                                                                                                                                                                                  |
| **`organization_id`** | String | Your organization ID, read from the access token used to perform the request.                                                                                                                                                                                                                                                                                                                                                                                                                |
| **`market_ids`**      | Array  | The ID(s) of the market(s) in scope, read from the access token used to perform the request.                                                                                                                                                                                                                                                                                                                                                                                                 |
| **`payload`**         | Object | The payload of the query you performed, filled with any computed and/or default values (returned only if [explicitly requested](#meta) when performing the query).                                                                                                                                                                                                                                                                                                                           |
