Nexon Open Api
Give your AI agent the Markdown source URL below.
View Markdown source

AI Agent Guide

This document is published as Markdown for AI agents to read. If you are looking for how to use the API as a person, see Using the API.

This document is written for AI agents, not people, so that an agent can use the NEXON Open API from start to finish on its own. It targets agents capable of tool calling, and the developers who build them. Where the other guides explain what the service provides, this one covers what goes wrong when you call it automatically. The behavior described here was confirmed by making real calls, and "Obligations and limits" restates rules from the official documentation. Because each game offers a different set of endpoints, this page carries only the rules common to every game rather than examples from one of them. The {game} segment in a path is where the game identifier goes. That identifier is the first segment of the paths in the game's spec file (see "Getting the whole specification at once"); do not guess it from the game's name.

How to use this page

  1. "An API Key is scoped to one game" — confirm which game your key covers first.
  2. "Obligations and limits" — check the call limits and the data refresh obligation before you design anything.
  3. "Making a request" — apply the header. Read "The date parameter rule" only when the API you call takes a date parameter. Most APIs do not.
  4. "Error handling" — separate the codes worth retrying from the ones that are not.
  5. "Count the calls before you start" — count what one screen needs, then add a cache.
  6. "Agent checklist" — run the final checklist to catch what is missing.

30-second summary

The minimum an agent needs to remember.

Item Value
API host https://open.api.nexon.com. Some static assets such as images are served from another host named in the spec file's servers
Authentication HTTP header x-nxopen-api-key. Open ID APIs use Authorization: Bearer {Access Token}. /static/ metadata needs none
Method GET only
Response format JSON
date parameter Only some APIs take it. If optional, omit it for the latest; if required, omitting it returns 400
Key scope Per game (application). One key cannot call another game
Call limits Development phase 5 requests/sec and 1,000/day; launch stage 500 requests/sec and 20,000,000/day
Data refresh obligation Data pulled through the API must be updated at least every 30 days
Lookup pattern Games with an identifier lookup API take two steps: name, identifier, details. Games without one call list or search APIs directly
Attribution Data based on NEXON Open API

The docs site and the API host are different

The documentation lives at https://openapi.nexon.com, while calls go to https://open.api.nexon.com. Mixing them up fails the whole path.

The overall flow

An agent goes through the following steps. Each step fails in a different way, so confirm one before moving to the next.

  1. Sign in with a NEXON ID and register an application to receive an API Key.
  2. Check the API list and parameters for the game you will use.
  3. Convert a name into an identifier. Skip this step for games without an identifier lookup API.
  4. Request the details with that identifier.
  5. Read the error code to decide whether to retry or stop.
  6. Cache the response and show the attribution on screen.

An API Key is scoped to one game

This is the most common thing to get caught on. NEXON Open API registers applications (keys) per game. Calling another game's path with a key rejects the path itself. Calling another game's path with one game's key returns OPENAPI00006, and the reverse is the same. Reading that code only as "a typo in the path" will not lead you to the cause.

Situation Response What the agent should do
A path for a game the key covers 200 Normal
A path for a game the key does not cover 400 OPENAPI00006 Issue a separate key for that game. Retrying is pointless
A path that does not exist 400 OPENAPI00006 Same code as above. Check both the path and the key's registration

When you handle several games

Store a key per game and select the key by looking at the first segment of the request path. If you keep only one key, everything fails silently the moment you add a game. Call quotas are also summed per application, so splitting keys by game splits the quota as well. Diagnostic code must follow the same key-selection rule. Code that checks permissions with only the default key will report "blocked" even when a per-game key exists.

NXOPEN_API_KEY_{gameA}=...      use this key when the first path segment is {gameA}
NXOPEN_API_KEY_{gameB}=...      use this key when the first path segment is {gameB}

Obligations and limits

These rules come from the official Getting Started page. They matter at design time, so they are restated here.

Data refresh obligation

You must update the data pulled from NEXON Open API at least every thirty (30) days. If you store responses, record when you received them and fetch them again before 30 days pass. Long-lived stored data needs an expiry of its own, separate from any short cache.

Application types and call limits

Application type Limit per second Daily limit
Development phase 5 requests 1,000 requests
Launch stage 500 requests 20,000,000 requests

The officially recommended order is to build and test with a development phase application, then register a new launch stage application once your service URL is ready. Moving to the launch stage requires issuing a new API Key.

Issuance rules

  1. Up to two API Keys can be issued per application.
  2. Up to three applications can be registered for the same game with one NEXON ID.

Treat the identifier as a secret

The identifier you receive from a name lookup exists to query internal data. It is not a value meant to be shown on screen. In our measurements the identifier length was not consistent — it came back as 32 or 64 characters — and when it was 64 characters, the trailing 32 matched the trailing 32 of the API Key in use. Those 32 characters are tied to the issuing account.

What the identifier looks like

API Key      {env}_..............................<32 chars tied to the account>
Identifier   <32 chars that differ per target><32 chars tied to the account>

Length is not a reliable test — there are 64-character identifiers that carry no key fragment.

Some games announce that identifiers can change. Do not store identifiers for long; if you store them, keep a path that fetches them again by name.

What to follow

Length is not a reliable test. Rather than trying to tell them apart by length, check the actual value right before you store it.

Do not Instead
Put identifier values in cache or log file names Keep only the parameter name and hash the value
Leave raw identifiers in logs and error messages Keep only the first 8 characters
Send identifiers to the frontend and put them in URLs Use them only inside the server
Paste real responses into documents or issues Redact the values first

Move the check into code

Do not leave the rule to human attention. Right before storing a response, check whether the trailing 32 characters of your API Key appear in the body, and skip the write if they do.

Storage schema

Size identifier columns to at least 64 characters. Fixing them at 32 truncates the values that arrive as 64.

Making a request

Every API is a GET, and request bodies are not used. The authentication header differs per API; the parameter marked in: header in the spec is that API's authentication header.

Applies to Header Value
Most APIs x-nxopen-api-key The API Key you were issued
Open ID APIs Authorization Bearer {Access Token}
Metadata whose path starts with /static/ None Fetched without authentication

Open ID APIs

APIs whose spec category name carries Open ID return data that needs the user's own consent. You call them not with an API Key but with the Access Token issued when the user signs in with NEXON Open ID. Handle Access Tokens only on the server. NEXON Open ID is offered through the Friends Program, and its development guide is visible only after signing in with a NEXON account.

Metadata without authentication, and other hosts

Metadata whose path starts with /static/ is static JSON, so you can fetch it without an API Key. Use it to turn code values in responses into names or images. Even for a game you have no key for, some screens can be built from metadata alone. A placeholder such as {language_code} in a path is a path substitution, not a query parameter. A query string builder will not fill it in, so insert it yourself. Each spec file has its own servers, and some files, such as images, point somewhere other than the API host. Calling those paths on the API host returns 400. Do not drop servers when you merge spec files.

Response format

A successful response is JSON containing the data you asked for. A failure arrives as an error object holding name and message. Do not put message straight into user-facing text — see "What to show the user" below.

{ "error": { "name": "OPENAPI00004", "message": "Please input valid parameter" } }

Parameter encoding

Values that contain non-ASCII text, such as names, need URL encoding. Building the query string with a proper encoder is safer than concatenating strings yourself. The braces in the example below are placeholders. Identifier parameter names differ per game — more than five distinct names are in use across the published specifications. Read them from the specification rather than guessing.

# 1) Get the identifier by name
curl -G 'https://open.api.nexon.com/{game}/v1/id' \
  --data-urlencode '{name_parameter}=TARGET_NAME' \
  -H 'x-nxopen-api-key: YOUR_API_KEY_HERE'

# 2) Get the details with that identifier. Omit date to get the latest data.
curl -G 'https://open.api.nexon.com/{game}/v1/{resource}' \
  --data-urlencode '{identifier_parameter}=RECEIVED_IDENTIFIER' \
  -H 'x-nxopen-api-key: YOUR_API_KEY_HERE'

# Parameter names differ by game. Read them from the spec.

The date parameter rule

Only some APIs take a date parameter. Check the spec of the API you call: does it have date, and if so, is it required? The rules differ between optional and required.

"Today" and "yesterday" in the tables below are counted in that API's reference time zone. The time zone is stated in the spec's date description (besides KST, some games use their service region's time, such as SGT or TST), and it can differ between APIs of the same game. Do not compute it from the server's local time.

When date is optional

date value Result
Omitted 200. Latest data. The date field in the response is null
Yesterday 200. Snapshot from one day earlier
Today 400 OPENAPI00004
A future date 400 OPENAPI00004
Before the service opened 200, but every field except the requested date is null

When date is required

On APIs where date is required, such as rankings, omitting it returns an error instead of the latest data. Unlike optional-date APIs, they also accept today's date.

date value Result
Omitted 400 OPENAPI00004
Yesterday 200
Today 200
A future date 400 OPENAPI00009
Earlier than the first available date 400 OPENAPI00009 or OPENAPI00004 — differs per API

Today's date works only after that day's data has been compiled (see "When data becomes available" below). Default to yesterday.

A future date returns OPENAPI00009 (data is being prepared). Some APIs also return 00009 for past dates earlier than the first available date.

When data becomes available

The time from which a day's data can be queried differs per API and is written in the spec's description. Some APIs open the previous day's data only in the early hours of the next day; others open today's rankings during the morning. Before that time, the data for that date does not exist. Code that fills in dates automatically should use the time given in the description, not midnight.

The available range differs per API

How far back you can go differs per API, and the first queryable date is also written in the description. Documented ranges and actual behavior do not always agree, so we recommend calling the boundary values yourself before building a date picker. In some games the queryable range is written only at the top of the spec (info), not on the endpoint — see "Do not take the specification at face value" below.

Error handling

This is the most important section for an agent. Retrying a code that should not be retried only doubles the quota you spend.

Code HTTP Retry Why
OPENAPI00001 500 Yes Internal server error. Retry after a backoff
OPENAPI00002 403 No Not permitted. Check the key and the target
OPENAPI00003 400 No Invalid identifier. Sending the same request again does not change the result
OPENAPI00004 400 No Missing parameter, or the target does not exist. This does not change over time
OPENAPI00005 400 No Invalid API Key
OPENAPI00006 400 No A game the key does not cover, or a wrong path
OPENAPI00007 429 Yes Quota exceeded. A backoff is required
OPENAPI00009 400 Yes Data is being prepared. Retry shortly. It also comes for requests with a date or out-of-range input, so stop if one retry returns the same
OPENAPI00010 400 Yes The game is under maintenance
OPENAPI00011 503 Yes The API is under maintenance

Retry with backoff and jitter

Retrying at a fixed interval bunches requests at the same moment and recreates OPENAPI00007. Use exponential backoff with jitter to spread them out.

What to show the user

Do not put the official description of an error code straight on screen. OPENAPI00004 is described as "missing or invalid parameter", but looking up a name that does not exist returns the same code. If the screen says "invalid parameter", the user reads it as a broken service rather than as their own input. Replace it with wording that fits the situation, such as "We could not find that name".

Do not treat step one as proof of existence

Even when the name lookup returns an identifier, requesting details with that identifier can return OPENAPI00003. You only know whether a lookup is possible after the second step. For that reason, avoid showing "Found it" at the moment step one succeeds.

The same "nothing" arrives in different shapes

All of these mean "nothing", but each looks different. Keep the user-facing wording consistent, such as "No record".

Situation Response
An item with no record 200 with the field set to 0 (not always null)
An unregistered sub-resource OPENAPI00004 — not a parameter error
No data for that day 200 with every field null
A target outside your permission OPENAPI00004 or OPENAPI00003 — a permission problem that looks like a parameter error
The conditions are valid but nothing matches (including a list lookup for a specific target) 200 with an empty array
A slot with no value Some games return a placeholder string such as "(Unknown)" instead of null

When HTTP 200 does not mean success

There are responses that return 200 with no error, yet every field except the requested date is null. Querying a date from before the service opened is one such case. An implementation that checks only the status code and the error code accepts this as normal and stores empty values. Check whether the key fields are null as well.

# A date before the service started returns 200, not an error.
curl -G 'https://open.api.nexon.com/{game}/v1/{resource}' \
  --data-urlencode '{identifier_parameter}=RECEIVED_IDENTIFIER' \
  --data-urlencode 'date=2023-12-20' \
  -H 'x-nxopen-api-key: YOUR_API_KEY_HERE'

# HTTP 200
# { "date": "2023-12-20T00:00+09:00", "<name field>": null, "<level field>": null, ... }   ← only the requested date is filled in; everything else is null
#
# An implementation that checks only the status code and the error code accepts this as normal.
# Check whether the key fields are null as well. Do not decide by the date field — a normal response with date omitted also has date null.

There are also parameters where a value outside the enum is silently ignored rather than rejected with 400. A typo or an old name in a filter value comes back as a 200 with the filter dropped — the full, unfiltered result — and this differs per parameter even within one API. Pick filter values only from the spec's enum, and check that the corresponding field in each response row matches what you asked for.

Count the calls before you start

A number like "N requests per second" is hard to reason about. Counting how many calls one screen needs makes it obvious that caching is not optional. Below is a measurement for drawing a single profile card.

Step Calls
Name to identifier 1
Basic information 1
Stats and detail lookups 6
Total 8

Adding rankings roughly doubles it

The 8 calls above are for a basic profile. Putting ranking badges on the card brings it to 13 to 15 calls, because the ranking API returns one kind of ranking per call. A development-stage key cannot draw even one card in a single pass. Building the cache first is the faster path.

Ask for one target's rank instead of scanning the list

When a list or ranking API has an identifier parameter, passing it returns only that target's row (other filters still apply). Paging through the list to find one target's rank multiplies the calls by hundreds. Be aware, though, that on some APIs the default value of an optional parameter fixes the segment being searched. When a lookup for a specific target returns nothing, ask once more with the segment value that target belongs to before concluding "no record". Defaults are written only in the spec's description.

Cache effect

Game data changes slowly, so a cache keyed by (endpoint, identifier, date) works well. One cache gives a 16x difference. Treat caching as a precondition for using this API, not an optimization. Bound concurrency below the quota with a semaphore or token bucket, and put a timeout on every call. Isolate failures so that one lookup cannot block the whole screen.

Item Value
Cache miss 179ms
Cache hit 11ms
Sequential throughput 8.0 req/s (20 in a row, no 429)

Building aggregates the API does not provide

Values the API does not return directly, such as population by class or a ranking by combat power, have to be counted yourself from several pages of rankings. Two things deserve care.

  1. The sample is the top N of a ranking, not the whole player base. If you do not state the sample range on screen, readers take it as the overall distribution.
  2. When the ranking response carries no identifier, attaching detail values costs an extra call per entry. The cost multiplies by the sample size.

Record what the count was based on

Carry the sample range in the response alongside the aggregate. Once only the number survives, nobody can interpret it.

Paging through a list

  • page starts at 1. 0 returns OPENAPI00004.
  • Past the last page, some games return an empty array and others return OPENAPI00004. Treat both as "the end".
  • The number of rows per page is not fixed. Ties make a page larger or smaller than the nominal size. Do not compute the rank as (page−1)×size+i; use the rank field in the response, and do not treat "fewer than the nominal size" as the last page.
  • For cursor-based lists, check the sort direction first. If they arrive oldest first, reaching the latest value costs as many calls as there are pages. Some games return OPENAPI00003 for a malformed cursor, and you cannot skip pages.

Response fields that actually caught us

Guessing a field's meaning from its name goes wrong in places.

Easy to assume Actual
A ..._part field is the equipped slot It can be the item category. The slot is the ..._slot field
No record means null Some fields return 0. A null check will not catch it
Numeric fields hold numbers Some arrive as strings. Convert before comparing or sorting
List-shaped fields are objects Some are arrays. Look entries up by name
Timestamps are in KST Some games return Z (UTC). See "Time fields in responses" below

Time fields in responses

The time zone of timestamps in responses differs per game. Some games return +09:00; others return Z (UTC, with milliseconds). If you take the first 10 characters of the string as the date, UTC responses shift by a day. Parse the value, then convert it to the service's reference time zone. For the time zone of the date parameter, see "The date parameter rule".

Do not discard values you do not recognize

A game update can add a new slot or a new grade. Dropping anything missing from an allow-list makes data disappear quietly with every update. Appending unknown values and logging them is safer.

Getting the whole specification at once

Instead of clicking through the documentation per game, download the specification files and read them in one pass so an agent can work with them. Building a list of which endpoints exist for which game removes any need to guess paths.

# The list of games currently offered and their spec files
curl -s 'https://openapi.nexon.com/static/script/specification.json'

# Download each game's OpenAPI spec from the paths in that list.
# With the specs on hand, the agent can read endpoints, parameters, and required flags directly.
# The first segment of the paths in a spec file (/{game}/v1/...) is the game identifier to use in URLs.
#
# Caution: the spec's required flag sometimes cannot express a conditional requirement.
# Even when required is false, follow any condition written in the description.

Do not take the specification at face value

Some parameters are marked required: false but carry a condition in the description. Omitting them on a request that meets the condition returns OPENAPI00004. The specification cannot express "conditionally required". Read the description too when you use a new endpoint. Response schemas can also differ from reality. Field names, numbers versus strings, arrays versus objects, and whether the top level is an array or an object have all come back differently, and fields without a nullable mark still return null. Before writing parsing code, compare one real response per endpoint with the schema, and follow the real response where they differ. Rules that apply to a whole game — the delay before data is reflected, the first queryable date, a notice that identifiers may change — are sometimes written only in info.description at the top of the spec, not on any endpoint. Read info first even for games without date. The dates in info have also been wrong in practice, so confirm boundary values by calling them.

When you download the specification

  1. No authentication is needed. The index and each specification file are available without a key.
  2. Keep the bytes exactly as received. Converting line endings makes parser verification meaningless.
  3. Stop on a parse failure instead of swallowing it. It signals that the published format changed.

Agent checklist

Go through the items below once the implementation is done.

Always do

  1. Keep the API Key on the server, never in the frontend or a repository.
  2. On APIs where date is optional, pass it only when you need it and omit it for the latest value. On APIs where date is required, never omit it.
  3. Retry only on 429, 5xx, and maintenance codes, together with a backoff.
  4. Check whether the key fields are null even when you receive a 200.
  5. Cache responses, and keep raw identifiers out of the cache key.
  6. Show Data based on NEXON Open API in your service.
  7. If you store responses, fetch them again within 30 days.
  8. Confirm that the call volume you designed fits within your application type's limits.
  9. Pick filter values only from the spec's enum, and check that each response row matches the filter you asked for.

Never do

  1. Leave raw identifiers in logs, file names, or URLs.
  2. Retry OPENAPI00003, 00004, or 00006.
  3. Use a successful step-one lookup as proof that the target exists.
  4. Put the official description of an error code straight into user-facing text.
  5. Present an aggregate as an overall statistic without stating the sample range.
  6. Page through a list to find one target's rank. Ask directly with the identifier parameter.

Standard call procedure

1. Pick this game's API Key from the first path segment
2. Name -> identifier     (when an identifier lookup API exists; stop immediately on failure; do not retry)
3. Identifier -> details  (omit date when you want the latest)
4. Check key fields for null even on a 200
5. Cache the successful response (never put the raw identifier in the key)
6. Show the attribution on screen

Related documents

This page covers only what goes wrong under automated calls. For the service overview and basic usage, see the documents below.

  1. Getting Started — signing in with a NEXON ID and registering an application
  2. Using the API — API lookup, testing, and the error code table
  3. Games — endpoints and parameters per game
  4. Notices — history of endpoint additions and changes. Check here first when this document and the actual behavior disagree
  5. Terms of Service — the conditions that apply to what you build
  6. Apply for the Friends Program — required before you can use Open ID APIs (sign-in required)

Glossary

Term Meaning
Application The unit an API Key is issued for. Registered per game
API Key The credential sent in the x-nxopen-api-key header. Issued when you register an application
Identifier The internal lookup value returned from a name lookup. Treat it as a secret
Quota The call limit, summed per application
Specification The OpenAPI document listing endpoints and parameters per game