A game’s own achievements: the ones its servers declare and report. They are not the site’s member achievements (the rungs you earn for using the site), and nothing here awards site points. A player is the credential’s own pseudonymous key (the same scoped player key as everywhere else in this API) and is never resolved to a site account.
The client is the dot-achievements addon’s reporter, and these shapes are its wire format. As with the other integration routes, no body names an app or server: the credential decides whose achievements these are.
Declaring the catalogue
/api/integration/v1/achievements/defineIntegrationACHIEVEMENTS_WRITESend the whole catalogue once per boot. Idempotent: an unchanged catalogue
writes nothing. PUT is accepted too. The credential must be scoped to an app
or one of its servers.
{
"achievements": [
{
"id": "first_blood",
"name": "First blood",
"description": "Get a kill.",
"points": 10,
"require_all": true,
"rules": [{ "stat": "kills", "op": "at_least", "value": 1, "merge": "sum" }],
"category": "combat",
"hidden": false,
"secret": false,
"series": "",
"tier": 0
}
]
}
{ "ok": true, "created": 1, "updated": 0, "unchanged": 0 }
- The id is
id(orkey, the stats routes’ name; if both are sent they must agree). It is letters, digits,.,_,:or-, up to 64 characters. rulestakes 1 to 16 conditions on statistics:opisat_least,at_most,equalsornot_equals;mergeissum,latest,highestorlowest, which are the stat kindsCOUNTER,GAUGE,BESTandLOWEST.pointsis 0 to 100000 and defaults to 10;namefalls back to the id.- Ceilings: 500 achievements per request and per owner. An id twice in one
request is a
400. Ones the site refuses by name come back inrefused, and the rest still apply. - A top-level
appthe reporter sends is ignored.
Filing unlocks
/api/integration/v1/achievements/unlockIntegrationACHIEVEMENTS_WRITEUp to fifty { player, key, unlockedAt } rows per request, unlockedAt in
Unix seconds.
{ "unlocks": [{ "player": "…", "key": "first_blood", "unlockedAt": 1735689600 }] }
{ "ok": true, "unlocked": 1, "already": 0 }
- Idempotent per player and key. A retried batch changes nothing, and a second report of an unlock only ever moves its time earlier.
- The achievement must already be declared. An unknown key is named in
refusedand the rest of the batch applies. unlockedAtis accepted between the years 2000 and 2100, which is what refuses milliseconds loudly. A time in the future is clamped to now rather than refused.- A malformed batch is a
400. The reporter drops it rather than retrying forever.
Reading a player’s unlocks
/api/integration/v1/achievements/playerIntegrationACHIEVEMENTS_READEvery achievement one player holds under this credential’s owner, oldest first.
Takes player in the query string.
{
"player": "…",
"points": 10,
"unlocks": [
{ "key": "first_blood", "name": "First blood", "description": "Get a kill.",
"points": 10, "category": "combat", "icon": "", "unlockedAt": 1735689600 }
]
}
points is the sum over those unlocks, in the game’s own points. The scopes are
split for the reason every pair is: a HUD that only reads must never be able to
file.
