> For the complete documentation index, see [llms.txt](https://onestore-dev.gitbook.io/dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://onestore-dev.gitbook.io/dev/cht/tools/onequest-development-guide.md).

# ONEquest Development Guide

ONEquest is a marketing tool that lets developers set up goal-based quests at any time they choose to drive ONE store users to engage with their games. To offer in-game action quests, the developer needs to do development work so that ONEquest can be told whether an in-game action has been completed.

## 1. Overview

When a quest participant completes a specific in-game action (quest) and claims the reward, the ONEquest server calls the game company's API to verify completion in real time. The game company must build and provide **two APIs** that follow the specifications in this document.

<table><thead><tr><th width="175.46875">API</th><th width="159.8515625">When it's called</th><th>Role</th></tr></thead><tbody><tr><td><a href="#id-5.-user-validation-api">User Validation API</a></td><td>first links their account</td><td>Checks that the <code>game_user_id</code> exists on your game server</td></tr><tr><td><a href="#id-v1.0-6.-api">Quest Verification API</a></td><td>claims a reward</td><td>Checks in real time whether the player finished the quest</td></tr></tbody></table>

{% hint style="info" %}
Both APIs are server-to-server calls from the **ONEquest server to the developer**. No extra development is needed in the game client (app). There is no API for the game company to call ONEquest.
{% endhint %}

{% hint style="danger" %}
**Important**

* The user identifier `game_user_id` must be a **UUID**. If you use a value that can be guessed from outside, such as a sequential number or an email address, someone could guess other users' `game_user_id` values and claim rewards they didn't earn.
* API responses must complete **within 500 ms.**
* The verification API must be **read-only**. Repeating the same request must never change any state.
  {% endhint %}

## 2. Integration Process

To make reward payouts reliable and keep things easy for users, the integration runs in two phases: **① initial account linking** and **② in-game action verification.**

**Phase 1. Initial account linking** (per user)

<table><thead><tr><th width="86">#</th><th width="158">Who</th><th>Actions</th></tr></thead><tbody><tr><td>1</td><td>User</td><td>Enters their game ID (<code>game_user_id</code>) and taps <strong>Link</strong></td></tr><tr><td>2</td><td>ONEquest</td><td>Calls your <strong>User Validation API</strong></td></tr><tr><td>3</td><td>Game Server</td><td>Checks that the player exists and returns <code>success</code></td></tr><tr><td>4</td><td>ONEquest</td><td>If the player is valid, saves the <code>game_user_id</code> and reuses it for every quest in the same quest group</td></tr></tbody></table>

**Phase 2. In-game action verification** (each time a reward is claimed)

<table><thead><tr><th width="86">#</th><th width="158">Who</th><th>Actions</th></tr></thead><tbody><tr><td>1</td><td>User</td><td>Finishes the quest and taps <strong>Claim Reward</strong>, with no ID needed</td></tr><tr><td>2</td><td>ONEquest</td><td>Calls your Quest Verification API with the saved <code>game_user_id</code></td></tr><tr><td>3</td><td>Game Server</td><td>Looks up the player's progress and returns the result</td></tr><tr><td>4</td><td>ONEquest</td><td>Grants the reward based on the result</td></tr></tbody></table>

{% hint style="info" %}
Each `game_user_id` can be linked to only one ONE store account, so one player can't take part twice.
{% endhint %}

## 3. Prerequisites

#### 3.1 Development Requirements

<table><thead><tr><th width="171">Item</th><th>Requirement</th></tr></thead><tbody><tr><td>Protocol</td><td><strong>HTTPS recommended</strong> (HTTP needs our approval). Use a <strong>domain name as the host,</strong> not an IP address.</td></tr><tr><td>Response time (SLA)</td><td>Respond within <strong>500 ms</strong>.</td></tr><tr><td>Data format</td><td>JSON for request and response bodies (<code>Content-Type: application/json</code>).</td></tr><tr><td>User ID</td><td>Receive <code>game_user_id</code> as a query parameter, whatever the HTTP method. It's the only required parameter.</td></tr><tr><td>Endpoint</td><td>Use any path and host you like, but the request and response formats must follow this spec.</td></tr><tr><td>Redirects</td><td>The registered URL must be final. ONEquest doesn't follow 3xx redirects.</td></tr></tbody></table>

#### 3.2 Firewall Allow list IPs <a href="#id-v1.0-3.2-ip" id="id-v1.0-3.2-ip"></a>

Because the ONEquest server calls the game company's APIs, the game company's server (firewall) must **allow inbound access from the ONEquest source IPs below**.

<table><thead><tr><th width="232">Environment</th><th>Source IP to allow</th></tr></thead><tbody><tr><td>Dev (QA)</td><td><code>211.188.207.190</code></td></tr><tr><td>Prod</td><td><code>211.188.201.250</code></td></tr></tbody></table>

{% hint style="danger" %}
To keep the APIs secure, the game company's server must reject requests from unregistered IPs with a **401 or 403**. Additional IPs can be requested for development environments. If our IPs change, we will let you know in advance.
{% endhint %}

#### 3.3 Console Registration <a href="#id-v1.0-3.2-ip" id="id-v1.0-3.2-ip"></a>

Developers register their APIs themselves in the Developer Center under **ONEconsole > Quest**. ONEquest calls the registered URL with only the `game_user_id` query parameter added.

<table><thead><tr><th width="179">Registered for</th><th width="208">Items</th><th>Details</th></tr></thead><tbody><tr><td>Quest group</td><td><a href="#id-5.-user-validation-api">User Validation API URL</a></td><td>One per group</td></tr><tr><td>Quest (in-game action)</td><td><a href="#id-v1.0-6.-api">Quest Verification API URL</a></td><td>One per quest. We recommend putting your own quest ID in the path.</td></tr></tbody></table>

{% hint style="info" %}
**The registration screen includes a connectivity test:**

* It sends a real request to the URL you entered to check that the URL can be reached and that the response follows the spec. **You must pass this test before you can register a quest.**
* The test only checks that the endpoint can be reached and returns JSON in the correct format, so it passes whether the result is "completed" or "not completed."
* If you change the URL or the HTTP method, you must run the test again.
  {% endhint %}

## 4. game\_user\_id

Both APIs take a single required user identifier parameter: `game_user_id`.

<table><thead><tr><th width="150">Item</th><th>Spec</th></tr></thead><tbody><tr><td>Type</td><td>String</td></tr><tr><td>Format</td><td>Standard 36-character <strong>UUID</strong> (8-4-4-4-12)</td></tr><tr><td>Max length</td><td>255 characters</td></tr><tr><td>Sent as</td><td>Query parameter, whatever the HTTP method</td></tr><tr><td>Example</td><td><code>13f664fc-3d8a-f011-94e3-e0451a3b66b3</code></td></tr></tbody></table>

{% hint style="warning" %}
Values that can be guessed from outside, such as sequential numbers or **email addresses,** are not allowed. They would let someone guess other users' `game_user_id` values and claim rewards they didn't earn.
{% endhint %}

## 5. User Validation API

When a ONEquest user links their game account for the first time, this API checks whether the `game_user_id` they entered actually exists on the game server.

#### 5.1 Request <a href="#id-v1.0-5.1-request" id="id-v1.0-5.1-request"></a>

<table><thead><tr><th width="150">Item</th><th>Value</th></tr></thead><tbody><tr><td>Method</td><td>GET (example)</td></tr><tr><td>Endpoint (example)</td><td><code>https://{Game_Server_Host}/onequest/users/validate?game_user_id=13f664fc-3d8a-f011-94e3-e0451a3b66b3</code></td></tr><tr><td>Content-Type</td><td>application/json</td></tr></tbody></table>

The endpoint path is only an example. Set it up to suit your game service, then register it in ONEconsole. **The request and response data formats can't be changed.**

<table><thead><tr><th width="83">In</th><th width="151">Parameter</th><th width="99">Type</th><th width="97">Required</th><th>Description</th></tr></thead><tbody><tr><td>Query</td><td>game_user_id</td><td>String</td><td>Y</td><td>The player's in-game ID to check (UUID, max 255 characters)</td></tr></tbody></table>

#### Request Example <a href="#id-v1.0-5.2-response" id="id-v1.0-5.2-response"></a>

```
curl -X GET \
  "https://api.game-company.com/onequest/users/validate?game_user_id=13f664fc-3d8a-f011-94e3-e0451a3b66b3" \
  -H "Content-Type: application/json"
```

#### 5.2 Response <a href="#id-v1.0-5.2-response" id="id-v1.0-5.2-response"></a>

<table><thead><tr><th width="127">Field</th><th width="107">Type</th><th width="88">Required</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>Boolean</td><td>Y</td><td>Whether the user exists (<code>true</code>: exists, <code>false</code>: not found)</td></tr><tr><td>joined_at</td><td>String</td><td>N</td><td>When the user joined the game, in ISO 8601 with time zone</td></tr></tbody></table>

#### Success: valid user

```
{
  "success": true,
  "joined_at": "2026-09-01T07:14:08.920+09:00"
}
```

#### Failure: user does not exist

```
{
  "success": false,
  "joined_at": null
}
```

## 6. In-Game Action Verification API <a href="#id-v1.0-6.-api" id="id-v1.0-6.-api"></a>

When a user completes a specific in-game quest and claims the reward, this API checks in real time whether that user actually completed it. It is called at the URL registered in ONEconsole for each quest.

#### 6.1 Request <a href="#id-v1.0-6.1-request" id="id-v1.0-6.1-request"></a>

<table><thead><tr><th width="159">Item</th><th>Value</th></tr></thead><tbody><tr><td>Method</td><td>GET (example)</td></tr><tr><td>Endpoint (example)</td><td><code>https://{Game_Server_Host}/onequest/quests/{quest_id}/verify?game_user_id=13f664fc-3d8a-f011-94e3-e0451a3b66b3</code></td></tr><tr><td>Content-Type</td><td>application/json</td></tr></tbody></table>

<table><thead><tr><th width="90">In</th><th width="132">Parameter</th><th width="105">Type</th><th width="83">Required</th><th>Description</th></tr></thead><tbody><tr><td>Path</td><td>quest_id</td><td>String</td><td>N</td><td>Your own quest ID. ONEquest calls the registered URL exactly as it is and doesn't read it, so your server uses the URL to tell quest conditions apart (level, tutorial, and so on).</td></tr><tr><td>Query</td><td>game_user_id</td><td>String</td><td>Y</td><td>The user's in-game ID (UUID), saved during Step 1</td></tr></tbody></table>

#### Request Example

```
curl -X GET \
  "https://api.game-company.com/onequest/quests/1/verify?game_user_id=13f664fc-3d8a-f011-94e3-e0451a3b66b3" \
  -H "Content-Type: application/json"
```

#### 6.2 Response <a href="#id-v1.0-6.2-response" id="id-v1.0-6.2-response"></a>

Based on the verification result, the response must clearly state either completed (`true`) or not completed (`false`).

<table><thead><tr><th width="117">Filed</th><th width="103">Type</th><th width="86">Required</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>Boolean</td><td>Y</td><td>Whether the quest was completed (<code>true</code>: completed, <code>false</code>: not completed)</td></tr><tr><td>message</td><td>String</td><td>Y</td><td>Result message. Please include the reason when it fails. It's for internal use and isn't shown to players.</td></tr></tbody></table>

#### Success: quest completed

```
{
  "success": true,
  "message": "Quest 1 Complete"
}
```

#### Failure: quest not completed

```
{
  "success": false,
  "message": "Conditions not met. (Current level: 25)"
}
```

#### Failure: user does not exist

```
{
  "success": false,
  "message": "User ID does not exist."
}
```

## 7. Error Handling and Response Codes <a href="#id-v1.0-7" id="id-v1.0-7"></a>

If the normal verification logic can't run (for example, during server maintenance), return the appropriate HTTP status code.

<table><thead><tr><th width="116">HTTP Code</th><th width="181">Status</th><th width="227">What it means</th><th>What the user sees</th></tr></thead><tbody><tr><td>200</td><td>OK</td><td>Handled normally. <code>success</code> in the body says whether the quest was completed.</td><td>Completed: reward granted / Not completed: "Conditions not met"</td></tr><tr><td>401 / 403</td><td>Unauthorized / Forbidden</td><td>The request came from an IP that isn't allowed and was blocked.</td><td>"Can't check right now." Our ops team is alerted, since the IP may be missing from your allowlist.</td></tr><tr><td>500</td><td>Internal Server Error</td><td>Your server hit an internal error.</td><td>"Can't check right now."</td></tr><tr><td>503</td><td>Service Unavailable</td><td>Maintenance or a temporary outage. During maintenance, return 503 right away instead of letting the request time out.</td><td>"Game under maintenance."</td></tr></tbody></table>

{% hint style="danger" %}
**Do not use 4xx to mean "not completed."**

ONEquest treats only **200 + `success=false`** as "not completed." Every other 4xx is treated as a temporary error, because a 401/403 means the IP is missing from the allowlist and can't be told apart from other cases. Please respond with **200 + `success=false`**, not 404/400, **when the user doesn't exist or a parameter has the wrong format.**
{% endhint %}

#### ONEquest Server Call Policy

<table><thead><tr><th width="220">Item</th><th width="218">Value</th><th>Notes</th></tr></thead><tbody><tr><td>Timeout</td><td>Connect 1 s / Read 3 s</td><td>If exceeded, the check fails ("Can't check right now"). You won't hit this if you meet the 500 ms SLA.</td></tr><tr><td>Retries</td><td>None (one call)</td><td>Each time the player tries again, ONEquest makes a new call. That's why the verify API must be read-only.</td></tr><tr><td>Redirects</td><td>3xx not followed, so the check fails</td><td>The registered URL must be final.</td></tr><tr><td>2xx with a non-JSON body or no <code>success</code></td><td>The check fails</td><td>This includes an empty body.</td></tr><tr><td>Failure isolation</td><td>Blocked per game company</td><td>If one company's API keeps failing, ONEquest pauses calls to it for a while and tells players it can't check right now. Other companies' quests aren't affected.</td></tr></tbody></table>

## 8. Implementation Example <a href="#id-v1.0-8" id="id-v1.0-8"></a>

**Scenario:** A user (`game_user_id` = 13fc-...) completes the "Reach Level 30" quest (game company Quest ID: 1) and claims the reward.

{% stepper %}
{% step %}

#### **User validation** (once, at initial linking)

* ONEquest request: `GET /onequest/users/validate?game_user_id=13f664fc-...`
* Game company response: `{"success": true}`
* Result: The user is confirmed as valid, and the link to their ONE store account is saved.
  {% endstep %}

{% step %}

#### In-game action verification

* ONEquest request: `GET /onequest/quests/1/verify?game_user_id=13f664fc-...` (Source IP: 211.188.201.250)
* Game company server logic:
  1. Check that the source IP is on the allowlist → Pass
  2. Look up the user's level in the database → Lv. 32 (condition met)
* Game company response: `{"success": true, "message": "Quest Complete"}`
  {% endstep %}

{% step %}

#### Final processing

* ONEquest: A reward is granted only once per user per quest.
  {% endstep %}
  {% endstepper %}

## 9. Integration Checklist <a href="#id-v1.0-9" id="id-v1.0-9"></a>

* [ ] `game_user_id` is issued and stored as a UUID (36 characters), not a sequential number or email address.
* [ ] Both APIs are served on a DNS domain (hostname). HTTPS is recommended; using HTTP requires separate agreement.
* [ ] Both APIs receive `game_user_id` as a query parameter (any HTTP method).
* [ ] The response body matches the spec (`success` required; `message` / `joined_at`).
* [ ] Missing users and format errors return 200 + `success=false`, not 404/400.
* [ ] Responses complete within 500 ms (check database indexes and caching).
* [ ] 503 is returned right away during maintenance.
* [ ] The verification API is read-only, so repeated calls don't change any state.
* [ ] The ONEquest source IPs (Dev 211.188.207.190 / Prod 211.188.201.250) are added to the firewall's inbound allowlist.
* [ ] Requests from unregistered IPs are blocked with 401/403.
* [ ] The endpoint URLs are final URLs with no redirects.
* [ ] The endpoint URLs (Dev/Prod) are registered in ONEconsole and have passed the connectivity test.
