> For AI agents: the complete documentation index is available at /en/llms.txt, the full documentation bundle is available at /en/llms-full.txt.

# Data Open API

Use an API Key to query visits and installs by **promotion link** or **app** from your own server, either as a total for a date range or broken down by day. This makes it easy to feed ROIBest data into your own BI, reporting or campaign systems.

|                 |                                             |
| :-------------- | :------------------------------------------ |
| Endpoint        | `https://openapi.roibest.com/open/v1/stats` |
| Method          | `GET`                                       |
| Authentication  | `X-Api-Key` request header                  |
| Response format | JSON (UTF-8)                                |
| Time zone       | UTC+0                                       |
| Queryable range | Last 90 days, up to 30 days per request     |

## Quick start

1. Sign in to the ROIBest dashboard with your **main account**, click your avatar in the top-right corner → **Open API** → **Generate API Key**, and complete email verification.
2. The full API Key is shown only once, right after it is generated. Copy or download it immediately and store it securely on your server.
3. Send your first request from your server (replace the ID and Key in the example with your own):

```bash
curl -s 'https://openapi.roibest.com/open/v1/stats?promote_url_id=6347317793&start_date=2026-10-01&end_date=2026-10-07&group_by=day' \
  -H 'X-Api-Key: rbk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
```

## Authentication

Include your API Key in the header of every request:

```
X-Api-Key: rbk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

- The API Key is accepted only in the request header. A Key placed in URL parameters or the request body is treated as missing.
- Only the main account can generate and manage API Keys, and each main account has exactly one active Key at a time.
- After you click **Regenerate** in the dashboard, **the old Key stops working immediately**. Get your server configuration ready to switch before you regenerate.

::: warning Security

Use your API Key on the server side only. Never put it in web pages, mobile apps or public code repositories. If you suspect it has been exposed, regenerate it in the dashboard right away.

:::

## Rate limit

You can send up to **10 requests per minute**. Requests beyond the limit receive HTTP 429; wait a moment before trying again.

::: tip Recommendations

- For daily data, use `group_by=day` to fetch the whole range (up to 30 days) in a single request instead of querying day by day.
- When querying many promotion links or apps, spread the requests out in batches.

:::

## Query statistics

```
GET https://openapi.roibest.com/open/v1/stats
```

### Request parameters

All parameters are passed as URL query parameters.

| Parameter      | Type   | Required       | Example    | Description                                                  |
| :------------- | :----- | :------------- | :--------- | :----------------------------------------------------------- |
| promote_url_id | string | One of the two | 6347317793 | Promotion link ID                                            |
| app_id         | string | One of the two | 1024       | App ID                                                       |
| start_date     | string | No             | 2026-10-01 | Start date in `YYYY-MM-DD` format, inclusive                 |
| end_date       | string | No             | 2026-10-07 | End date in `YYYY-MM-DD` format, inclusive                   |
| group_by       | string | No             | day        | Omit for the range total; set to `day` for a daily breakdown |

Query rules:

- Provide **exactly one** of `promote_url_id` and `app_id`.
- All dates are in UTC+0. For example, `2026-10-01` covers `2026-10-01 00:00:00` to `23:59:59` UTC.
- If both dates are omitted, today is queried. If only one is provided, only that day is queried.
- The end date cannot be later than today (UTC+0).
- A single request can cover at most **30 days** (start and end dates included).
- Only data from the **last 90 days** is available: the start date cannot be more than 90 days before today. For example, if today (UTC+0) is November 6, the earliest date you can query is August 8.
- You can only query promotion links and apps under your own account. Deleted or hidden ones can still be queried and are flagged by the `deleted` and `hidden` fields in the response.

### Response fields

| Field                | Type           | Description                                                                                                            |
| :------------------- | :------------- | :--------------------------------------------------------------------------------------------------------------------- |
| code                 | int            | Business code; `0` means success                                                                                       |
| msg                  | string         | Result message; `success` on success                                                                                   |
| request_id           | string         | Request ID; include it when reporting an issue                                                                         |
| data.promote_url_id  | string \| null | The promotion link ID when querying by promotion link, otherwise `null`                                                |
| data.app_id          | string \| null | The app ID when querying by app, otherwise `null`                                                                      |
| data.deleted         | bool           | Whether it has been deleted                                                                                            |
| data.hidden          | bool           | Whether it has been hidden in the dashboard                                                                            |
| data.metrics         | string\[]      | Metrics returned, currently `["visit", "install"]`                                                                     |
| data.timezone        | string         | Time zone used for the statistics, always `UTC`                                                                        |
| data.start_date      | string         | Start date of this query                                                                                               |
| data.end_date        | string         | End date of this query                                                                                                 |
| data.total           | object         | Returned when `group_by` is omitted: the totals of `visit` and `install` over the range                                |
| data.rows            | array          | Returned when `group_by=day`: one row per day in ascending date order; days without data are included with zero counts |
| data.rows\[].date    | string         | Date in `YYYY-MM-DD`                                                                                                   |
| data.rows\[].visit   | int            | Visits                                                                                                                 |
| data.rows\[].install | int            | Installs                                                                                                               |

### Example: range total

```
GET /open/v1/stats?promote_url_id=6347317793&start_date=2026-10-01&end_date=2026-10-02
```

```json
{
  "code": 0,
  "msg": "success",
  "request_id": "9f1c2e7a4b3d4c6e8a0b1c2d3e4f5a6b",
  "data": {
    "app_id": null,
    "promote_url_id": "6347317793",
    "deleted": false,
    "hidden": false,
    "timezone": "UTC",
    "metrics": ["visit", "install"],
    "start_date": "2026-10-01",
    "end_date": "2026-10-02",
    "total": { "visit": 180, "install": 21 }
  }
}
```

### Example: daily breakdown

```
GET /open/v1/stats?app_id=1024&start_date=2026-10-01&end_date=2026-10-03&group_by=day
```

```json
{
  "code": 0,
  "msg": "success",
  "request_id": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "data": {
    "app_id": "1024",
    "promote_url_id": null,
    "deleted": false,
    "hidden": false,
    "timezone": "UTC",
    "metrics": ["visit", "install"],
    "start_date": "2026-10-01",
    "end_date": "2026-10-03",
    "rows": [
      { "date": "2026-10-01", "visit": 100, "install": 12 },
      { "date": "2026-10-02", "visit": 80, "install": 9 },
      { "date": "2026-10-03", "visit": 0, "install": 0 }
    ]
  }
}
```

## Metrics

| Metric             | Description                                                                                              |
| :----------------- | :------------------------------------------------------------------------------------------------------- |
| Visits (visit)     | Sum of **Total Visits** and **Access via Chrome** under **Promotion Links → Analytics** in the dashboard |
| Installs (install) | **Install** under **Promotion Links → Analytics** in the dashboard                                       |

- Both metrics exclude traffic identified as invalid by the system.
- Days are split by UTC+0. Today's figures are cumulative up to the time of the query.

## Error codes

On failure, both the HTTP status code and a business code are returned (except for HTTP 429). Example response:

```json
{ "code": 40003, "msg": "date range must not exceed 30 days", "request_id": "9f1c2e7a4b3d4c6e8a0b1c2d3e4f5a6b" }
```

| HTTP status | Business code | Description                                                                         | What to do                                                                                 |
| :---------- | :------------ | :---------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------- |
| 400         | 40001         | `promote_url_id` / `app_id` is missing, both are provided, or the format is invalid | Provide exactly one of them, as digits only                                                |
| 400         | 40002         | Invalid date format, start date after end date, or end date later than today        | Check the date parameters                                                                  |
| 400         | 40003         | Date range exceeds 30 days                                                          | Split it into multiple requests                                                            |
| 400         | 40004         | Start date is outside the last 90 days                                              | Move the start date into the last 90 days                                                  |
| 400         | 40005         | Invalid `group_by` value                                                            | Omit it, or set it to `day`                                                                |
| 401         | 40101         | API Key is missing, invalid or has been regenerated                                 | Check the `X-Api-Key` header and make sure you are using the latest Key                    |
| 401         | 40102         | Account not activated or restricted                                                 | Activate your account first if it is not activated; otherwise contact your account manager |
| 404         | 40401         | The promotion link or app does not exist or does not belong to your account         | Check that the ID is correct and belongs to your account                                   |
| 429         | —             | Rate limit exceeded                                                                 | Wait 1 minute before retrying, and reduce your request rate                                |
| 500         | 50001         | Internal server error                                                               | Retry later; if it persists, contact your account manager with the `request_id`            |
| 503         | 50301         | Service busy, temporarily unable to query                                           | Retry later; avoid sending many retries in a short time                                    |

::: tip Retry guidance

- 429: wait 1 minute before retrying.
- 500, 503: retry with increasing intervals (e.g. 2s, 4s, 8s), up to 3 times.
- Other 4xx errors: retrying will not help; fix the request before sending it again.

:::
