Skip to main content
  1. Writing/

An In-Depth Overview Of The Halo Infinite Career Ranks

·1597 words
This blog post is part of a series on exploring the Halo game API.

It’s almost the Halo weekend, and to mark the occasion - here is another post digging through the Halo Infinite data.

One of the exciting additions to Halo Infinite since Season 4: Infection is the ability to gain career experience and get an assigned career rank. I generally enjoyed Halo 5’s progression system - I topped at SR138:

Halo 5 showing the player service record at SR138.
Halo 5 showing the player service record at SR138.

Maybe once I burn through the Halo Infinite ranks, I’ll come back and get myself to SR152. One day. In the meantime, career ranks are a welcome addition to the latest installment in the franchise, and as much as I enjoy playing Halo, I also enjoy being able to talk to the Halo Infinite API, so naturally my curiosity got the best of me and I started digging through the ins and outs of how career ranks are actually tracked. Let’s dive in.

A quick intro to ranks #

There’s a total of 272 career ranks that can be earned, spread across six tiers that should already be familiar to anyone that participated in any of the ranked playlists - Bronze, Silver, Gold, Platinum, Diamond, and Onyx. Notably, while the names are the same as for each of the ranked tiers, the career ranks bear no relation to them. Players do not earn any ranked progression or ranked rewards for hitting a specific career rank (e.g., you’re not going to get the Diamond Signum for hitting Diamond career rank).

Each rank within a tier has three sub-tiers, so to progress to the next level you have to complete three stages of a given rank, each with slightly more XP required than the last. The further you go, the harder it gets to level up. You can see the full spread in the official breakdown (4K image) put together by folks at 343 Industries.

For example, I am currently ranked as Major, Platinum, Grade 1 (the first sub-tier of the Major rank, in the Platinum band). This rank can be seen in the game when looking at the player profile:

Halo Infinite in-game view of player stats.
Halo Infinite in-game view of player stats.

The same rank information can also be seen in my Halo Waypoint Service Record for Halo Infinite:

Image of my rank from within Halo Waypoint Service Record

Career ranks are not private - you can easily look at them for any other Halo Infinite players, either through Halo Waypoint or by using Halo Infinite itself. The ranks can be seen in the post-game carnage report (PGCR) or even in the list of recent players:

Player ranks as displayed in Halo Infinite PGCR and Recent player list.
Player ranks as displayed in Halo Infinite PGCR and Recent player list.

Let’s take a closer look at how those can be queried through the Halo Infinite API.

Getting career data through the API #

The first endpoint that we need to look at is the one that will give us a static representation of all available career ranks in the game. I refer to it as static because, unlike your game stats, the content returned by this specific API call doesn’t change dynamically unless it’s actually updated on the back-end. Which, if you think about it, does make a lot of sense - ranks, once established, don’t really change that much - it would be pretty bad if the XP requirements fluctuated.

You can use a tool like Fiddler or Postman to send a GET request to the following endpoint (it requires authentication):

https://gamecms-hacs.svc.halowaypoint.com
  /hi
  /Progression
  /file
  /RewardTracks
  /CareerRanks
  /careerRank1.json

If successful, the call with return a very long (remember - there are 272) list of available ranks in a JSON array, containing data like this:

{
    "Rank": 272,
    "FreeRewards": {
        "InventoryRewards": [],
        "CurrencyRewards": []
    },
    "PaidRewards": {
        "InventoryRewards": [],
        "CurrencyRewards": []
    },
    "XpRequiredForRank": 1,
    "RankTitle": {
        "status": "Test",
        "value": "Hero",
        "translations": {
            "qps-ploc": "Неřό !",
            "qps-ploca": "Ηěґö !",
            "qps-plocm": "Ħěřǿ !"
        }
    },
    "RankSubTitle": {
        "status": "Test",
        "value": "",
        "translations": {}
    },
    "RankTier": {
        "status": "Test",
        "value": "",
        "translations": {}
    },
    "RankIcon": "career_rank/ProgressWidget/272_Hero.png",
    "RankLargeIcon": "career_rank/CelebrationMoment/272_Hero.png",
    "RankAdornmentIcon": "career_rank/NameplateAdornment/272_Hero.png",
    "TierType": "Gold",
    "RankGrade": 0
}

I find it kinda funny that Hero is Gold tier, but that’s irrelevant to our discussion. By looking at the data returned from careerRank1.json, we get all the required information to piece together rank requirements:

Property Description
Rank The index of the rank, starting from Recruit at 1 and Hero at 272.
FreeRewards Rewards offered for free when hitting the rank. For certain milestones these include career emblems and nameplate combos. For Hero, it was announced that players will get the Mark VI armor kit.
PaidRewards Premium rewards, which I can only assume are relevant to battle pass owners. Haven’t seen any actually included.
XpRequiredForRank The amount of XP required to reach this particular tier of a rank. This is the number only for the given tier (i.e., not from the start of the progression bar).
RankTitle The title offered to the player when hitting the rank, along with translated values, where applicable.
RankSubtitle While this is really a dummy value for Hero, for other ranks it maps to the tier type the rank is in.
RankTier Numeric representation of the tier within the given rank band (e.g., Major 2).
RankIcon The relative link in the game CMS to the rank icon.
RankLargeIcon The relative link in the game CMS to the larger version of the rank icon.
RankAdornmentIcon The relative link in the game CMS to the nameplate adornment that is displayed opposite of the emblem.
TierType Bronze, Silver, Gold, Platinum, Diamond, or Onyx.
RankGrade Same as RankTier, but just an integer.

For the referenced images, they can be obtained by following the game CMS image base path:

https://gamecms-hacs.svc.halowaypoint.com
  /hi
  /Images
  /file

The rank icon looks like this:

https://gamecms-hacs.svc.halowaypoint.com
  /hi
  /Images
  /file
  /career_rank
  /ProgressWidget
  /272_Hero.png
Hero rank icon in Halo Infinite.
Hero rank icon in Halo Infinite.

The larger icon - like this:

https://gamecms-hacs.svc.halowaypoint.com
  /hi
  /Images
  /file
  /career_rank
  /CelebrationMoment
  /272_Hero.png
Large Hero rank icon in Halo Infinite.
Large Hero rank icon in Halo Infinite.

And lastly - the adornment:

https://gamecms-hacs.svc.halowaypoint.com
  /hi
  /Images
  /file
  /career_rank
  /NameplateAdornment
  /272_Hero.png
Hero rank nameplate adornment in Halo Infinite.
Hero rank nameplate adornment in Halo Infinite.

If we take all of the experience (XP) data and lay it out over a bar chart, the XP requirements for each individual tier block and sub-tier will look like this:

That’s quite a bit of work required to get to Hero! A player would need a whopping 9,319,351 experience points to reach the top rank. Although, compared to Halo 5’s requirement of 494,410,400 experience points to reach SR152, this suddenly doesn’t sound terribly bad. Running some back of the napkin math:

$$\frac{9319351\text{ XP}}{2500\text{ XP/match}}*10\text{ minutes/match} = 37278\text{ minutes}$$

If you’re moderately good at a high XP yield game mode like Husky Raid, earning around 2,500 XP per match, you will need to play 3,728 matches to get to maximum rank. Assuming that (in my experience) a match goes on for about 10 minutes, you would need to spend 37,278 minutes, or roughly 621 hours, or almost 26 days, to get there. Still not as bad as Halo 5.

Great, so now we have an idea of what ranks and tiers there are out there and how they stack up against each other XP-wise.

Seems like at every somewhat regular interval, there is a drop-off and it starts picking up again. Is the data correct?

Indeed it is! Ever major drop-off that you see is the start of the next tier type (e.g., Diamond). It gives the player a bit of a break to start progressing, but then accelerates again until the next drop-off. Notice that there are also smaller spikes that happen every tier grade reset.

But how do we actually get a player career rank? That data is dynamic and can be obtained by querying the following endpoint (in addition to X-343-Authorization-Spartan it also requires a 343-clearance header attached):

https://economy.svc.halowaypoint.com
  /hi
  /players
  /xuid(PLAYER_XUID)
  /rewardtracks
  /careerranks
  /careerrank1

The XUID is the Xbox player identifier that you can obtain by looking at the requests being sent on the Halo Waypoint website (if you really don’t want to do it solo).

If the call is successful, you will get the following JSON blob:

{
    "RewardTrackPath": "RewardTracks/CareerRanks/careerRank1.json",
    "TrackType": "CareerRank",
    "CurrentProgress": {
        "Rank": 167,
        "PartialProgress": 8050,
        "IsOwned": false,
        "HasReachedMaxRank": false
    },
    "PreviousProgress": null,
    "IsOwned": false,
    "BaseXp": null,
    "BoostXp": null
}

You can get the progress against the current rank and tier. One of the things I wanted to do with this data, however, is understand how am I progressing against the Hero rank - that’s something that is missing from the game or Halo Waypoint. While seeing how far along the current tier I am is helpful, I want to get a percentage of “how far along I am” - which means I need to measure my progress against all rank requirements. To do that, we can leverage every single XP data point from the careerRank1.json above like this:

$$\sum_{i=1}^r \text{(XP)}_i + \text{(XP)}_p$$

Keep in mind that in the equation above:

$$r = \text{current rank}$$

And:

$$\text{(XP)}_p = \text{partial XP progress for current rank}$$

In plain terms, you want to calculate the sum of experience for every single rank including the partial progress at the current rank. In C#, this could look like this (given that the JSON was deserialized into an array) - as seen through the lens of my OpenSpartan project:

var relevantRanks = 
  (from c in careerTrackContainerResult.Result.Ranks
   where c.Rank <= HomeViewModel.Instance.CareerSnapshot.RewardTracks[0].Result.CurrentProgress.Rank
   select c);
HomeViewModel.Instance.ExperienceEarnedToDate = 
  relevantRanks.Sum(rank => rank.XpRequiredForRank) + careerTrackResult.Result.RewardTracks[0].Result.CurrentProgress.PartialProgress;

In the beta UI, it looks like this:

A screenshot of OpenSpartan showing the career breakdown.
A screenshot of OpenSpartan showing the career breakdown.

Looks like I barely made a dent in the progress! Time to charge the controller.