# Quests API

> List quests, read one, start it and record views and clicks.

Source: https://dashboard.adquest.batriders.ir/docs/api/quests · Audience: Developers · Section: API reference

## The quest object

Every quest route that returns a quest uses the same object. Format-specific fields (event_rule, profile_rule, referral_rule, streak_rule, custom_rule) are filled only for that format.

> **Each quest has one language.** The feed returns only quests in the participant’s effective language (see effective_locale), and a quest with no language set counts as English. Asking directly for a quest in another language returns 404 QUEST_NOT_FOUND, the same as a quest that does not exist.

**Quest**

```json
{
  "id": 23,
  "name": "Watch our intro video",
  "type": "video",
  "type_name": "Video",
  "visibility": "private",
  "platform_id": 7,
  "token_reward": 10,
  "token_reward_total": 12,
  "reward_unit": null,
  "reward_is_max": true,
  "gift_reward": null,
  "gift_reward_expires_at": null,
  "status": "active",
  "screen": "watch",
  "content": "https://cdn.example.com/intro.mp4",
  "cover": "https://cdn.example.com/cover.jpg",
  "redirect_url": null,
  "display_duration": null,
  "start_date": "2026-01-01",
  "end_date": "2026-03-01",
  "completed": false,
  "completion_condition": {
    "requires_timer": true,
    "requires_question": true,
    "requires_click": false,
    "requires_event": false,
    "requires_profile": false,
    "requires_referral": false,
    "requires_streak": false,
    "requires_custom": false,
    "answer_mode": null
  },
  "event_rule": null,
  "profile_rule": null,
  "referral_rule": null,
  "streak_rule": null,
  "custom_rule": null,
  "media": {
    "type": "video",
    "url": "https://cdn.example.com/intro.mp4",
    "cover": "https://cdn.example.com/cover.jpg"
  },
  "proof": {
    "type": "watch_answer",
    "version": 1,
    "media": "video",
    "timed": true
  }
}
```

| Field | Type | Meaning |
| --- | --- | --- |
| id | integer | Quest ID. Use it in the other quest routes. |
| name | string | Quest title. |
| type | string | Format key: video, banner, survey, quiz, visit, event, profile, referral, streak or custom. |
| type_name | string | Display name of the format. |
| visibility | string | Whether the quest is private to your platform or on the network. |
| token_reward | integer or null | Tokens this participant earns. |
| token_reward_total | integer or null | Total reward before the participant and AdQuest split it. |
| reward_unit | object or absent | White Label publisher quests only: { code, label, icon_url } of the unit the reward is paid in. Absent means AdQuest tokens. |
| reward_is_max | boolean or absent | true when token_reward is the most the quest can pay (video watched fully, every streak day). |
| gift_reward, gift_reward_expires_at | object or null, string or null | Optional gift attached to the quest, and when it expires. |
| status | string | Always active for quests you can see. |
| screen | string | The widget screen that renders this quest. |
| content, cover, redirect_url, media | mixed | Quest text or media URL, cover image, destination link and media details. |
| display_duration | integer or null | Seconds a banner must be shown. Banner quests only. |
| start_date, end_date | string or null | When the quest runs. |
| completed | boolean | Whether this participant already completed it. Needs external_user_id. |
| completion_condition | object | What the participant must do. Flags such as requires_timer and requires_question. |
| proof | object | The evidence this format needs. Present only when the runtime supports the format. |

## List quests

### `GET /platform/quests`

Returns the quests this platform can show, newest first. Pass external_user_id to mark the ones the user has already completed.

**Authentication:** Public API key (X-AdQuest-Platform-Key).

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| external_user_id | query | string | no | Your ID for the user. Sets completed on each quest. |
| X-AdQuest-Participant-Token | header | string | no | The participant token. Optional here. It adds per-user state such as completed. |

```bash
curl "https://api.adquest.batriders.ir/api/v1/platform/quests" \
  -H "X-AdQuest-Platform-Key: YOUR_PUBLIC_API_KEY" \
  -H "X-AdQuest-Participant-Token: PARTICIPANT_TOKEN"
```

**Response 200.** The list of quests. effective_locale is the language the quests were chosen for.

```json
{
  "status": true,
  "code": "OK",
  "message": "Platform quests",
  "effective_locale": "en",
  "data": [
    {
      "id": 23,
      "name": "Watch our intro video",
      "type": "video",
      "type_name": "Video",
      "visibility": "private",
      "platform_id": 7,
      "token_reward": 10,
      "token_reward_total": 12,
      "gift_reward": null,
      "gift_reward_expires_at": null,
      "status": "active",
      "screen": "watch",
      "content": "https://cdn.example.com/intro.mp4",
      "cover": "https://cdn.example.com/cover.jpg",
      "redirect_url": null,
      "display_duration": null,
      "start_date": "2026-01-01",
      "end_date": "2026-03-01",
      "completed": false,
      "completion_condition": {
        "requires_timer": true,
        "requires_question": true,
        "requires_click": false,
        "requires_event": false,
        "requires_profile": false,
        "requires_referral": false,
        "requires_streak": false,
        "requires_custom": false,
        "answer_mode": null
      },
      "event_rule": null,
      "profile_rule": null,
      "referral_rule": null,
      "streak_rule": null,
      "custom_rule": null,
      "media": {
        "type": "video",
        "url": "https://cdn.example.com/intro.mp4",
        "cover": "https://cdn.example.com/cover.jpg"
      },
      "proof": {
        "type": "watch_answer",
        "version": 1,
        "media": "video",
        "timed": true
      }
    }
  ]
}
```

## Get a quest

### `GET /platform/quests/{questId}`

Returns one quest.

**Authentication:** Public API key (X-AdQuest-Platform-Key).

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| questId | path | integer | yes | Quest ID. |
| external_user_id | query | string | no | Your ID for the user. Sets completed. |
| X-AdQuest-Participant-Token | header | string | no | The participant token. Optional here. It adds per-user state such as completed. |

```bash
curl "https://api.adquest.batriders.ir/api/v1/platform/quests/23" \
  -H "X-AdQuest-Platform-Key: YOUR_PUBLIC_API_KEY" \
  -H "X-AdQuest-Participant-Token: PARTICIPANT_TOKEN"
```

**Response 200.** The quest.

```json
{
  "status": true,
  "code": "OK",
  "message": "Quest details",
  "data": {
    "id": 23,
    "name": "Watch our intro video",
    "type": "video",
    "type_name": "Video",
    "visibility": "private",
    "platform_id": 7,
    "token_reward": 10,
    "token_reward_total": 12,
    "reward_unit": null,
    "reward_is_max": true,
    "gift_reward": null,
    "gift_reward_expires_at": null,
    "status": "active",
    "screen": "watch",
    "content": "https://cdn.example.com/intro.mp4",
    "cover": "https://cdn.example.com/cover.jpg",
    "redirect_url": null,
    "display_duration": null,
    "start_date": "2026-01-01",
    "end_date": "2026-03-01",
    "completed": false,
    "completion_condition": {
      "requires_timer": true,
      "requires_question": true,
      "requires_click": false,
      "requires_event": false,
      "requires_profile": false,
      "requires_referral": false,
      "requires_streak": false,
      "requires_custom": false,
      "answer_mode": null
    },
    "event_rule": null,
    "profile_rule": null,
    "referral_rule": null,
    "streak_rule": null,
    "custom_rule": null,
    "media": {
      "type": "video",
      "url": "https://cdn.example.com/intro.mp4",
      "cover": "https://cdn.example.com/cover.jpg"
    },
    "proof": {
      "type": "watch_answer",
      "version": 1,
      "media": "video",
      "timed": true
    }
  }
}
```

**Response 404.** The quest does not exist or is not available to this platform.

```json
{
  "status": false,
  "code": "QUEST_NOT_FOUND",
  "message": "Quest not found",
  "data": null
}
```

## Start a quest

### `POST /platform/quests/{questId}/start`

Starts a quest for a participant. For timed quests (video and banner) the response tells you how long the participant has to watch.

**Authentication:** Public API key (X-AdQuest-Platform-Key) and participant token (X-AdQuest-Participant-Token). Both are required.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| questId | path | integer | yes | Quest ID. |
| X-AdQuest-Participant-Token | header | string | yes | The participant token minted by your backend (POST /platform/participant-sessions). Required: it is the participant's identity. A body external_user_id is optional and must match it (403 PARTICIPANT_MISMATCH); a missing or invalid token is 401 PARTICIPANT_AUTH_REQUIRED. |
| external_user_id | body | string | yes | Your ID for the user. Max 255 characters. |
| watch_duration | body | integer | no | Seconds, 1 to 600. |

```bash
curl -X POST https://api.adquest.batriders.ir/api/v1/platform/quests/23/start \
  -H "Content-Type: application/json" \
  -H "X-AdQuest-Platform-Key: YOUR_PUBLIC_API_KEY" \
  -H "X-AdQuest-Participant-Token: PARTICIPANT_TOKEN" \
  -d '{ "external_user_id": "player-42" }'
```

**Response 200.** The quest was started. display_duration and expires_in (seconds) are included for video and banner quests only. Also returned with this status: the participant already completed this quest. status is false and data.completed is true. Do not grant a reward.

```json
{
  "status": true,
  "code": "OK",
  "message": "Quest started",
  "data": {
    "quest_id": 23,
    "display_duration": 15,
    "expires_in": 15
  }
}
```

**Response 404.** QUEST_NOT_FOUND. The quest does not exist or is not available.

**Response 422.** The quest budget is used up. data.code is QUEST_BUDGET_EXHAUSTED. Other 422 responses are validation errors.

## Record a click

### `POST /platform/quests/{questId}/click`

Records that the participant clicked the quest’s media. Send it only when a real click happens.

**Authentication:** Public API key (X-AdQuest-Platform-Key) and participant token (X-AdQuest-Participant-Token). Both are required.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| questId | path | integer | yes | Quest ID. |
| X-AdQuest-Participant-Token | header | string | yes | The participant token minted by your backend (POST /platform/participant-sessions). Required: it is the participant's identity. A body external_user_id is optional and must match it (403 PARTICIPANT_MISMATCH); a missing or invalid token is 401 PARTICIPANT_AUTH_REQUIRED. |
| external_user_id | body | string | yes | Your ID for the user. Max 255 characters. |

```bash
curl -X POST https://api.adquest.batriders.ir/api/v1/platform/quests/23/click \
  -H "Content-Type: application/json" \
  -H "X-AdQuest-Platform-Key: YOUR_PUBLIC_API_KEY" \
  -H "X-AdQuest-Participant-Token: PARTICIPANT_TOKEN" \
  -d '{ "external_user_id": "player-42" }'
```

**Response 200.** The click was recorded. Also returned with this status: the participant already completed this quest. status is false and data.completed is true.

```json
{
  "status": true,
  "code": "OK",
  "message": "Quest click recorded",
  "data": {
    "quest_id": 23,
    "clicked_at": "2026-01-01T12:00:00.000Z"
  }
}
```

**Response 404.** QUEST_NOT_FOUND.

## Record that a participant saw a quest. First viewed_at sticks.

### `POST /platform/quests/{questId}/view`

Records that the participant saw the quest. The first view is kept. Later calls keep the same viewed_at.

**Authentication:** Public API key (X-AdQuest-Platform-Key) and participant token (X-AdQuest-Participant-Token). Both are required.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| questId | path | integer | yes | Quest ID. |
| X-AdQuest-Participant-Token | header | string | yes | The participant token minted by your backend (POST /platform/participant-sessions). Required: it is the participant's identity. A body external_user_id is optional and must match it (403 PARTICIPANT_MISMATCH); a missing or invalid token is 401 PARTICIPANT_AUTH_REQUIRED. |
| external_user_id | body | string | yes | Your ID for the user. Max 255 characters. |

```bash
curl -X POST https://api.adquest.batriders.ir/api/v1/platform/quests/23/view \
  -H "Content-Type: application/json" \
  -H "X-AdQuest-Platform-Key: YOUR_PUBLIC_API_KEY" \
  -H "X-AdQuest-Participant-Token: PARTICIPANT_TOKEN" \
  -d '{ "external_user_id": "player-42" }'
```

**Response 200.** The view was recorded.

```json
{
  "status": true,
  "code": "OK",
  "message": "Quest view recorded",
  "data": {
    "quest_id": 23
  }
}
```

**Response 404.** QUEST_NOT_FOUND.

**Response 422.** A field failed validation, for example a missing external_user_id.

```json
{
  "status": false,
  "code": "VALIDATION_ERROR",
  "message": "The external user id field is required.",
  "data": {
    "external_user_id": [
      "The external user id field is required."
    ]
  }
}
```

## Evidence and completion

Questions, progress, visits, events, referrals, growth status, completion and stats are on the Quest actions page.

- [Quest actions API](https://dashboard.adquest.batriders.ir/docs/api/quest-actions): Send evidence and complete a quest.
- [Quest evidence](https://dashboard.adquest.batriders.ir/docs/quest-evidence): The proof each quest format needs to complete.
