WalkScape Public API

A read-only API for community tools that track WalkScape characters, the leaderboards, where players are, and the weekly job boards.

If your tool currently calls /portal/shared/characters/{id}, please move to this API. The portal endpoint is shaped by what the portal needs and may change without notice; this one will not.


Authentication and limits

None required. Requests are anonymous. Please do not poll faster than the Cache-Control header allows (see Caching); rate limits per IP address will be introduced, and tools that respect the cache headers will not notice them.

Endpoints

GET /public/v1/characters/{id}

Returns one character.

GET /public/v1/characters?ids={id},{id},...

Returns up to 100 characters in one request. Ids can be comma separated or given as repeated parameters (?ids=a&ids=b); duplicates are ignored. If you track many characters, use this instead of one request per character.

{
  "characters": [ { "id": "...", "...": "..." } ],
  "not_found": ["id-that-does-not-exist"]
}

characters follows the order the ids were requested in, leaving out the ones listed in not_found.

GET /public/v1/characters/directory?after={cursor}

Lists which characters exist, so you can find ids without scraping the leaderboards. Returns pages of 1000 in the order characters were created:

{
  "characters": [ { "id": "...", "character_name": "..." } ],
  "next_cursor": "12815",
  "has_more": true
}

The character object

{
  "id": "walker-4fdb40cb-9cc2-4c7f-b1f8-6eb95e91f950",
  "character_name": "Walker",
  "created_at": "2024-01-07T03:42:37.124597Z",
  "updated_at": "2026-08-02T19:43:55.887438Z",
  "total_steps": 1234567,
  "location_uid": "b1f0e251-ad0c-4be8-bb9b-7e5449dfc221",
  "statistics": { "agility": 123456, "...": "..." },
  "ironfoot": false,
  "user": { "username": "walker", "avatar": null }
}
Field Type Notes
id string Stable character id.
character_name string
created_at ISO 8601 UTC string
updated_at ISO 8601 UTC string Last time the character was saved.
total_steps integer or null null when the player has chosen to hide their steps.
location_uid string or null The character's current location.
statistics object Skill experience and other statistics, keyed by name.
ironfoot boolean Whether this is an Ironfoot character.
user object or null The owning account's username and avatar. null unless the player's profile visibility is public.

Every field is always present; optional values are null rather than missing.

GET /public/v1/jobs/weeks

Lists the job board weeks there are jobs for, oldest first, ending with the running week. A week runs from Monday 00:00 UTC to the next Monday; week 0 began on 2024-01-01.

{
  "current_week_index": 147,
  "weeks": [
    { "week_index": 146, "starts_at": "2026-10-19T00:00:00.000Z", "ends_at": "2026-10-26T00:00:00.000Z" },
    { "week_index": 147, "starts_at": "2026-10-26T00:00:00.000Z", "ends_at": "2026-11-02T00:00:00.000Z" }
  ]
}

Every player sees the same jobs. A week is never available before it starts.

GET /public/v1/jobs/weeks/{weekIndex}

Returns every board's jobs for one week. {weekIndex} is a week number from the list above, or current for the running week.

{
  "week_index": 147,
  "starts_at": "2026-10-26T00:00:00.000Z",
  "ends_at": "2026-11-02T00:00:00.000Z",
  "jobs": [ { "id": 552, "board_id": "...", "...": "..." } ]
}

jobs are job objects, ordered by board_id and then slot. On rare occasions a running week's board is rolled again: its jobs are then replaced by new ones with new ids, and the old ones disappear from this list and from the stats.

GET /public/v1/jobs/weeks/{weekIndex}/stats

How many characters took part, for one week (current works here too). Counts only; the API never lists who.

{
  "week_index": 147,
  "generated_at": "2026-10-29T12:05:00.000Z",
  "jobs": [
    { "job_id": 552, "accepted_characters": 1834, "completed_characters": 1210 }
  ],
  "boards": [
    {
      "board_id": "...",
      "hand_ins": 5120,
      "characters": 2048,
      "bonus_claims": [ { "milestone": 5, "characters": 312 } ]
    }
  ]
}
Field Notes
jobs One entry per job of this week that anyone accepted, among the jobs the week lists. Accepted jobs can be handed in until their expires_at, weeks after their board closed, so these counts keep growing after the week ends. A job never accepted is left out.
accepted_characters Characters who accepted the job, including those who accepted and handed it in at once.
completed_characters Characters who handed it in.
boards What happened on each board during this week: hand_ins counts every job handed in there, whichever week it was from, and characters the characters who handed in at least one.
bonus_claims Characters who reached each weekly bonus milestone, by the number of jobs it needs.
generated_at When the counts were taken.

The job object

{
  "id": 552,
  "board_id": "jobboard-kallaheim-...",
  "slot": 0,
  "difficulty_id": "jobdifficulty-hard",
  "special_id": null,
  "bonus": false,
  "required_level": 2,
  "expires_at": "2026-11-30T00:00:00.000Z",
  "goals": [
    {
      "item": { "id": "item-birch_logs-...", "quality": "common", "tag": "none" },
      "quantity": 214,
      "alternatives": []
    }
  ],
  "rewards": [
    { "kind": "faction_reputation", "item": null, "target_id": "faction-jarvonia-...", "amount": 3 },
    { "kind": "item", "item": { "id": "item-jarvonia_chest-...", "quality": "common", "tag": "none" }, "target_id": null, "amount": 1 }
  ]
}
Field Type Notes
id integer Stable job id, unique across all weeks.
board_id string The job board, as in the game data.
slot integer Position on the board.
difficulty_id string
special_id string or null Set for a hand-made job, null for a generated one.
bonus boolean One of its difficulty's bonus jobs, which ask and pay more.
required_level integer Level in the board's faction needed to accept it.
expires_at ISO 8601 UTC string A player who accepted the job can hand it in until then.
goals array Every goal must be met. A goal takes quantity of item, or the quantity of any one of its alternatives instead (higher qualities of the same item).
rewards array kind is item, coins, faction_reputation or skill_experience. item is set for item rewards, target_id (a faction or skill id) for the last two.

Items are given as their game data id, a quality (common, uncommon, rare, epic, legendary or ethereal) and a tag (none, fine or rare_egg). Every field is always present.

GET /public/v1/leaderboards/{type}?page={n}

One page of a leaderboard, 100 entries per page, best first. {type} is one of total_level, total_xp, total_steps, achievement_points, agility, carpentry, cooking, crafting, fishing, foraging, hunting, mining, smithing, tailoring, trinketry or woodcutting. page counts from 1 and defaults to 1; every page of a board can be fetched.

{
  "type": "total_level",
  "page": 1,
  "page_size": 100,
  "has_more": true,
  "entries": [
    {
      "rank": 1,
      "position": 1,
      "character_id": "walker-4fdb40cb-9cc2-4c7f-b1f8-6eb95e91f950",
      "character_name": "Walker",
      "title_id": null,
      "ironfoot": false,
      "value": 1234,
      "total_xp": 98765432
    }
  ]
}
Field Type Notes
rank integer Characters with the same score share a rank, and the next rank skips accordingly (1, 2, 2, 4). On total_level, total_xp breaks ties.
position integer The place in the list, counting from 1.
character_id string or null null for a player who is anonymous on the leaderboards.
character_name string Anonymous Walker for an anonymous player.
title_id string or null The character's title, as in the game data. null without one, and for an anonymous player.
ironfoot boolean Whether this is an Ironfoot character.
value integer or null The score this board ranks by.
total_xp integer

GET /public/v1/census

How many characters are at each location, counting the characters whose game was saved in the last 30 days. The window is fixed and counted from the start of the current hour.

{
  "total": 10779,
  "locations": [
    { "location_uid": "b1f0e251-ad0c-4be8-bb9b-7e5449dfc221", "name": "Kallaheim", "count": 312 }
  ]
}

locations is ordered by count, highest first. name is the location's English name.

GET /public/v1/census/activities

How many of those characters are doing each activity, and where. Characters that are not doing anything are not counted.

{
  "total": 6259,
  "activities": [
    {
      "activity_id": "...",
      "name": "Birch Logs",
      "total": 120,
      "locations": [
        { "location_uid": "...", "name": "Kallaheim", "count": 80 }
      ]
    }
  ]
}

Names are in English. The census never lists characters, only counts.

Caching

Character data is refreshed at most once a minute. Every response carries:

Because of the server-side cache, a change to a character can take up to about two minutes to appear here. The leaderboards are rebuilt every two minutes and cached for five, so they can be up to about seven minutes behind the game, and the census up to about fifteen.

Errors

Errors use the standard WalkScape error body:

{
  "error": {
    "type": "character_does_not_exist",
    "code": "1002",
    "error_message": "Character does not exist.",
    "hint": "The character you tried to access does not exist.",
    "http_code": 404
  }
}

Only GET is accepted; other methods get 400 with error type wrong_http_method.