BvPTiers

Developers

Public API

Free, read-only JSON for bots, overlays and mods. No key needed.

Common rules

  • Base URL: https://bvptiers.com/api. Everything is GET, JSON, UTF-8.
  • CORS is open (Access-Control-Allow-Origin: *), so you can call it from a browser.
  • Responses carry Cache-Control: public, max-age=30 (the snapshot: 60) and an ETag. Send it back in If-None-Match to get a cheap 304.
  • Errors look like {"error":{"code":"not_found","message":"…"}} and are never cached. Bad parameters give a 400.
  • Private data (tester notes, Discord IDs, accounts) is never exposed. Hidden players don't exist as far as the API is concerned.

Objects

Ranking object

pos is 0 for High and 1 for Low. points is what this mode adds to overall (its peak tier). label never has the R prefix: use retired.

{
  "tier": 1,
  "pos": 0,
  "label": "HT1",
  "peak_tier": 1,
  "peak_pos": 0,
  "peak_label": "HT1",
  "retired": false,
  "attained": 1793600000,
  "points": 60
}

Player summary

{
  "uuid": "0123456789abcdef0123456789abcdef",
  "name": "BvP",
  "region": "EU",
  "points": 260,
  "active_points": 200,
  "rank": 3,
  "title": "Warlord",
  "rankings": {
    "sword": {
      "tier": 1,
      "pos": 0,
      "label": "HT1",
      "peak_tier": 1,
      "peak_pos": 0,
      "peak_label": "HT1",
      "retired": false,
      "attained": 1793600000,
      "points": 60
    },
    "mace": {
      "tier": 2,
      "pos": 1,
      "label": "LT2",
      "peak_tier": 1,
      "peak_pos": 1,
      "peak_label": "LT1",
      "retired": true,
      "attained": 1791000000,
      "points": 45
    }
  }
}

TierTagger compatibility

The /api/v2 endpoints use the MCTiers v2 shapes, so existing tier-tagger mods can read BvPTiers. In TierTagger, set the custom API URL to https://bvptiers.com/api (for example apiUrl = "https://bvptiers.com/api" in its config).

For your own mod, prefer /api/v1/snapshot: one request with an ETag every few minutes instead of one request per player.

GET/api/v1/modes

Enabled modes in display order.

Example responseTry it

{
  "modes": [
    {
      "slug": "sword",
      "title": "Sword",
      "short": "SWD",
      "description": "Pure sword duels, no shields",
      "icon": "sword",
      "icon_url": "/icons/modes/sword.svg",
      "discord_url": "",
      "sort": 2
    }
  ]
}
GET/api/v1/rankings/overall

The overall leaderboard: players by total points (peak tier per mode, retired included). Equal points share a rank. Players with 0 points are left out.

Query parameters

NameTypeMeaning
fromint ≥ 0Offset (default 0).
countint 1–100Page size (default 50; values outside the range are clamped).
regionNA|EU|SA|AS|OC|ME|AF|??Only this region; rank is then the rank inside the region.

Example responseTry it

{
  "total": 74,
  "from": 0,
  "count": 50,
  "players": [
    {
      "uuid": "0123456789abcdef0123456789abcdef",
      "name": "BvP",
      "region": "EU",
      "points": 260,
      "active_points": 200,
      "rank": 3,
      "title": "Warlord",
      "rankings": {
        "sword": {
          "tier": 1,
          "pos": 0,
          "label": "HT1",
          "peak_tier": 1,
          "peak_pos": 0,
          "peak_label": "HT1",
          "retired": false,
          "attained": 1793600000,
          "points": 60
        },
        "mace": {
          "tier": 2,
          "pos": 1,
          "label": "LT2",
          "peak_tier": 1,
          "peak_pos": 1,
          "peak_label": "LT1",
          "retired": true,
          "attained": 1791000000,
          "points": 45
        }
      }
    }
  ]
}
GET/api/v1/rankings/active

Same as overall, ordered by active points (current, non-retired tiers only); rank is the active rank.

Query parameters

NameTypeMeaning
fromintOffset.
countint 1–100Page size.
regioncodeRegion filter.

Example responseTry it

{
  "total": 70,
  "from": 0,
  "count": 50,
  "players": [
    {
      "uuid": "0123456789abcdef0123456789abcdef",
      "name": "BvP",
      "region": "EU",
      "points": 260,
      "active_points": 200,
      "rank": 3,
      "title": "Warlord",
      "rankings": {
        "sword": {
          "tier": 1,
          "pos": 0,
          "label": "HT1",
          "peak_tier": 1,
          "peak_pos": 0,
          "peak_label": "HT1",
          "retired": false,
          "attained": 1793600000,
          "points": 60
        },
        "mace": {
          "tier": 2,
          "pos": 1,
          "label": "LT2",
          "peak_tier": 1,
          "peak_pos": 1,
          "peak_label": "LT1",
          "retired": true,
          "attained": 1791000000,
          "points": 45
        }
      }
    }
  ]
}
GET/api/v1/rankings/{slug}

One mode's tier lists. Each tier is sorted HT first, then by the date the tier was reached. count and from apply per tier; totals gives the full size of each tier.

Query parameters

NameTypeMeaning
regioncodeRegion filter.
retired0|11 = only retired players, 0 (default) = only active ones.
fromintOffset per tier.
countint 1–100Players per tier (default 100).

Example responseTry it

{
  "mode": {
    "slug": "sword",
    "title": "Sword",
    "short": "SWD",
    "icon": "sword",
    "icon_url": "/icons/modes/sword.svg",
    "discord_url": "",
    "sort": 2
  },
  "tiers": {
    "1": [
      {
        "uuid": "0123456789abcdef0123456789abcdef",
        "name": "BvP",
        "region": "EU",
        "pos": 0,
        "label": "HT1",
        "peak_label": "HT1",
        "retired": false,
        "attained": 1793600000
      }
    ],
    "2": [],
    "3": [],
    "4": [],
    "5": []
  },
  "totals": { "1": 1, "2": 0, "3": 0, "4": 0, "5": 0 }
}
GET/api/v1/players/{name-or-uuid}

A full profile: the player summary plus badges, the last 50 tests and both ranks. A UUID works with or without dashes. 404 for unknown or hidden players.

Example response

{
  "uuid": "0123456789abcdef0123456789abcdef",
  "name": "BvP",
  "region": "EU",
  "points": 260,
  "active_points": 200,
  "rank": 3,
  "title": "Warlord",
  "rankings": {
    "sword": {
      "tier": 1,
      "pos": 0,
      "label": "HT1",
      "peak_tier": 1,
      "peak_pos": 0,
      "peak_label": "HT1",
      "retired": false,
      "attained": 1793600000,
      "points": 60
    },
    "mace": {
      "tier": 2,
      "pos": 1,
      "label": "LT2",
      "peak_tier": 1,
      "peak_pos": 1,
      "peak_label": "LT1",
      "retired": true,
      "attained": 1791000000,
      "points": 45
    }
  },
  "badges": [
    { "title": "Founder", "desc": "Created BvPTiers" },
    { "title": "Sword Champion", "desc": "Reached Tier 1 in Sword" }
  ],
  "tests": [
    {
      "mode": "sword",
      "at": 1793600000,
      "result_label": "HT1",
      "prev_label": "LT1",
      "tester": "some_tester"
    }
  ],
  "overall_rank": 3,
  "active_rank": 5
}
GET/api/v1/tests/recent

The latest test results, newest first (public fields only).

Query parameters

NameTypeMeaning
countint 1–50How many (default 20).
high0|11 = only results at HT3 or better.

Example responseTry it

{
  "tests": [
    {
      "player": {
        "uuid": "0123456789abcdef0123456789abcdef",
        "name": "BvP",
        "region": "EU"
      },
      "mode": "sword",
      "at": 1793600000,
      "result_label": "HT1",
      "prev_label": "LT1"
    }
  ]
}
GET/api/v1/stats

Headline numbers.

Example responseTry it

{ "players_ranked": 74, "tests_total": 332, "modes": 8 }
GET/api/v1/snapshot

The compact feed used by the mod: every ranked player with a UUID. It has a strong ETag ("<data_version>"), so poll it with If-None-Match and you get a 304 until something changes. Each t value is [tier, pos, peak_tier or 0, peak_pos or 0, retired 0/1]; k is the overall rank.

Example responseTry it

{
  "v": 1,
  "generated": 1793600000,
  "data_version": 42,
  "modes": [
    { "slug": "sword", "title": "Sword", "short": "SWD", "icon": "sword" }
  ],
  "players": {
    "0123456789abcdef0123456789abcdef": {
      "n": "BvP",
      "r": "EU",
      "p": 260,
      "k": 3,
      "t": {
        "sword": [1, 0, 1, 0, 0],
        "mace": [2, 1, 1, 1, 1]
      }
    }
  }
}
GET/api/v2/mode/list

Modes keyed by slug.

Example responseTry it

{
  "sword": {
    "title": "Sword",
    "info_text": null,
    "kit_image": null,
    "discord_url": null
  }
}
GET/api/v2/mode/overall

The overall list in the MCTiers v2 shape (dashed UUIDs).

Query parameters

NameTypeMeaning
fromintOffset.
countint 1–100Page size.

Example responseTry it

[
  {
    "uuid": "01234567-89ab-cdef-0123-456789abcdef",
    "name": "BvP",
    "region": "EU",
    "points": 260,
    "overall": 3,
    "rankings": {
      "sword": {
        "tier": 1,
        "pos": 0,
        "peak_tier": 1,
        "peak_pos": 0,
        "attained": 1793600000,
        "retired": false
      }
    }
  }
]
GET/api/v2/profile/{uuid}

One profile. Also available as /api/v2/profile/by-name/{name}; /api/v2/profile/{uuid}/rankings returns only the rankings object.

Example response

{
  "uuid": "01234567-89ab-cdef-0123-456789abcdef",
  "name": "BvP",
  "region": "EU",
  "points": 260,
  "overall": 3,
  "rankings": {
    "sword": {
      "tier": 1,
      "pos": 0,
      "peak_tier": 1,
      "peak_pos": 0,
      "attained": 1793600000,
      "retired": false
    }
  },
  "badges": []
}