# How to Use the AdFlex API

The AdFlex API allows users to explore, filter, and retrieve ad data across multiple advertising platforms including Facebook, Meta, Native, Display, Pinterest, Reddit, X, YouTube, and TikTok. This guide provides a complete walkthrough of how to interact with the API, including authentication, filters, request structure, and result handling.

## 🔗 Base URL

All AdFlex API requests are made to the following base URL:

```text
https://api.adflex.io/api/
```

All endpoints in this guide are relative to this base URL.

For example, the filters endpoint:

```http
GET https://api.adflex.io/api/v2/ads/{platform}/filters
```

Replace `{platform}` with the advertising platform you want to query, such as `facebook`, `meta`, `native`, `display`, etc.

### Example

To retrieve the available filters for Facebook ads:

```http
GET https://api.adflex.io/api/v2/ads/facebook/filters
```

The same base URL is used for all API endpoints described in this guide.

## 🌐 Available Advertising Platforms

The `{platform}` parameter is used in AdFlex API routes to specify the advertising platform you want to query.

The following platform names are currently supported:

| Platform | Value |
|  --- | --- |
| Facebook | `facebook` |
| Meta | `meta` |
| Native | `native` |
| Display | `display` |
| Pinterest | `pinterest` |
| Reddit | `reddit` |
| X | `x` |
| YouTube | `youtube` |
| TikTok | `tiktok` |


Use the platform **value** shown in the table when calling API routes.

### Example

To retrieve filters for YouTube:

```http
GET /v2/ads/youtube/filters
```

To search ads on TikTok:

```http
POST /v2/ads/tiktok/search
```

To retrieve details for a Reddit ad:

```http
GET /v2/ads/reddit/{ad}
```

> **Note:** Platform values are case-sensitive. Use the values exactly as shown in the table.


## 🔄 Mega Search

`mega` is a special platform value that acts as an aggregated search across all supported advertising platforms.

Unlike the other platform values, `mega` does not represent an individual advertising platform. Instead, it searches across the available platforms and returns aggregated ad data.

### Supported Endpoints

The `mega` platform supports the following endpoints:

```http
GET /v2/ads/mega/filters
```

Use this endpoint to retrieve the filters available for aggregated searches.

```http
POST /v2/ads/mega/search
```

Use this endpoint to search across all supported platforms. The results may contain ads from different platforms, along with their corresponding platform information.

### Ad Details

❌ The `mega` platform does **not** have its own ad detail endpoint.  For example, the following route is not supported:

```http
GET /v2/ads/mega/{ad}
```

When a search result contains an ad from a specific platform, use the corresponding platform's ad detail endpoint if you need to retrieve additional details.

For example, an ad returned from Facebook with `"platform": "facebook"` and `"id": 123` can be accessed through:

```http
GET /v2/ads/facebook/123
```

## 🔐 Authentication

The API supports two types of authentication methods:

1. **Header-Based Authentication** – Provide your API key in the headers using:

```
x-api-key: YOUR_API_KEY
```
2. **Body-Based Authentication** – Authentication details may be passed in the request body or query string using:

```
api_key: YOUR_API_KEY
```


Make sure to include authentication with all requests.

## 📦 Base Response Structure

Every API response from AdFlex follows a standardized structure:

```json
{
  "status": "ok",
  "meta": {
    "code": 1000,
    "message": null
  },
  "data": []
}
```

- `status`: Indicates if the request was successful (`ok`) or not (`failed`).
- `meta.code`: A numeric code representing the result.
- `meta.message`: A human-readable message. It may be `null` for successful requests.


Failure response example:

```json
{
  "status": "failed",
  "meta": {
    "code": 1009,
    "message": "Server Error"
  },
  "data": []
}
```

Refer to the [API Response Codes Documentation](https://doc.adflex.io/response_codes) for a full list of possible codes and messages.

## 🔍 Step 1: Retrieve Dynamic Filters

Use the following endpoint to retrieve platform-specific filters:

**Endpoint:**

```http
GET /v2/ads/{platform}/filters
```

Replace `{platform}` with the desired platform (e.g., `facebook`, `meta`, `native`, `display`, `pinterest`).

Each filter object includes:

- `key`: The parameter to use in the search request body.
- `component`: The filter type, such as:
  - `StringMultiApi`: Fetches options dynamically using an `api_url`.
  - `StringMulti`: Options are listed directly in `items`.
  - `NumberMultiRange`, `SearchBox`, and others for more specific types.
- `api_url`: A URL pointing to an API route (e.g., `v2/ads/facebook/filters/interests`) to retrieve filter items. You must send a request with `search` in the query parameter to this endpoint to fetch the available options.
- `sub_keys`: If present, the filter expects a more complex structure. For example:


### 🧩 Example: Complex Filter with `sub_keys`

For array-based filters such as `search_field`, each array item follows the `sub_keys` mapping. For object-based filters such as `advanced_order`, the object itself follows that mapping.

The `search_field` filter includes:

```json
{
  "sub_keys": {
    "type": "type",
    "main": "text"
  }
}
```

This means that the request body should include:

```json
{
  "search_field": [
    {
      "type": "text",
      "text": "Club"
    },
    {
      "type": "without_owner",
      "text": "Runners"
    }
  ]
}
```

Or the `advanced_order` filter includes:

```json
{
  "sub_keys": {
    "type": "order",
    "main": "orderby"
  }
}
```

This means that the request body should include:

```json
{
  "advanced_order": {
    "orderby": "web_traffic",
    "order": "desc"
  }
}
```

Each object, including each object within an array follows the structure defined by `sub_keys`.

## 📤 Step 2: Search Ads Using Filters

Once you have the filters, you can use them to send a search request:

**Endpoint:**

```http
POST /v2/ads/{platform}/search
```

Use the `key` field from each filter to construct the body. Refer to `sub_keys` if applicable.

Example request body:

```json
{
  "page": 1,
  "advanced_order": {
    "orderby": "web_traffic",
    "order": "desc"
  },
  "behaviors": [50, 61],
  "interests": [198],
  "search_field": [
    { "type": "text", "text": "Club" },
    { "type": "without_owner", "text": "Runners" }
  ]
}
```

Each search request returns up to 18 ads. The page size is fixed and cannot be changed.

For page 1, set `page` to `1` and omit `last_hit`. The response returns `data.last_hit`. For page 2 and later, increment `page` and resend the exact `data.last_hit` value returned by page 1. Use the same filters and sorting options throughout the pagination sequence. Do not generate or modify `last_hit`.

`last_hit` does not expire, and there is no API-imposed maximum page depth. Continue requesting pages while `data.has_next_page` is `true`.

If you change any filter or sorting option, restart from page 1 and omit the previous `last_hit` so the server can create a new snapshot.

Example request body:

```json
{
  "page": 2,
  "last_hit": 1786180640,
  "advanced_order": {
    "orderby": "web_traffic",
    "order": "desc"
  },
  "behaviors": [50, 61],
  "interests": [198],
  "search_field": [
    { "type": "text", "text": "Club" },
    { "type": "without_owner", "text": "Runners" }
  ]
}
```

## 📄 Step 3: View Ad Details

To get detailed data on an individual ad, use its ID from the search result.

**Endpoint:**

```http
GET /v2/ads/{platform}/{ad}
```

Replace `{platform}` with the correct platform and `{ad}` with the ad ID.

## 💳 Credits Usage

API requests consume credits from your account. For non-free endpoints, each request costs **100 credits**, regardless of the platform being queried.

### Credit Costs

| Endpoint | Credit Cost |
|  --- | --- |
| Search endpoints | 100 credits |
| Ad detail endpoints | 100 credits |
| Get filters | Free |
| Get filter items | Free |


The following endpoints do not consume credits:

```http
GET /v2/ads/{platform}/filters
```

```http
GET /v2/ads/{platform}/filters/{filter}
```

All other API endpoints consume **100 credits per request**.

> **Note:** Credits are charged per API request. The number of results returned by a request does not affect the credit cost.


## ⏱️ Rate Limits and Retry Policy

The AdFlex API has **no rate limits**. You can make API requests without a predefined limit on the number of requests per second or minute. Therefore, clients do not need to handle rate-limit windows, `429 Too Many Requests` responses, or `Retry-After` headers.

Retry only transient failures, such as connection errors, timeouts, or temporary server failures. Use exponential backoff with jitter and limit retries to three attempts. Do not retry validation, authentication, permission, or not-found errors.

Because all API responses return HTTP `200 OK`, always inspect the internal `code` field before deciding whether a request should be retried.

## 🔁 Summary

1. Authenticate via `x-api-key` header or `api_key` request parameter.
2. Call `GET /v2/ads/{platform}/filters` to get filters.
3. Use those filters to build your `POST /v2/ads/{platform}/search` request.
4. Use the ad `id` and its source platform to call `GET /v2/ads/{platform}/{ad}` for detailed information. The detail endpoint is available for all individual platforms, but not for `mega`. For Mega search results, use the platform specified in each result instead of `mega`.


## 📘 See Also

- [API Response Codes](https://doc.adflex.io/response_codes)
- [OpenAPI Documentation](https://doc.adflex.io/openapi)