Appearance
Inventory & offers (R6 Siege)
PC Rainbow Six Siege inventory, catalogues, offer redeem, and clearance level.
- spaceId: R6 primary
0d2ae42d-4c27-4cb7-af6c-2099062302bb - Currencies: item IDs
- Catalogues: compressed payloads
Headers are standard. Inventory worker app ID 3587dcbb-… is used by some official jobs; a main-auth or R6 PC ticket is what most clients send after exchange.
Inventory
GET
https://public-ubiservices.ubi.com/v1/profiles/{userId}/inventory?spaceId={spaceId}&offset=0&limit=10000Full inventory: skins, charms, currencies.
Query
| Name | Notes |
|---|---|
spaceId | R6 primary space |
offset | 0 then next page |
limit | Practical max ~10000. If items.length hits the limit, paginate |
{userId} is the Ubisoft user / profile UUID you are allowed to read (usually your own).
Response
ts
{ items: Array<{ itemId: string; quantity?: number }> }Cosmetics omit quantity. Currencies have it. Pull Renown / R6 Credits / Level by the known item IDs.
To name items, join itemId against the item catalogue.
Redeem offer
POST
https://public-ubiservices.ubi.com/v1/profiles/{profileId}/inventoryRedeem an offer into the profile inventory (in-game unlock / grant). offerId comes from the offer catalogue.
Body
ts
type RedeemOfferBody = {
spaceid: string // note: lowercase "i"
offerId: string
}json
{
"spaceid": "0d2ae42d-4c27-4cb7-af6c-2099062302bb",
"offerId": "{offerId}"
}Only redeem offers the account is entitled to. Failed redeems return 400 / 409 rather than a silent no-op. Response body was not in the dumps.
Offer catalogue
GET
https://public-ubiservices.ubi.com/v1/spaces/{spaceId}/offersCompressed offer catalogue (smaller / filtered vs /all).
Decode: compressed payloads.
Full offer catalogue
GET
https://public-ubiservices.ubi.com/v1/spaces/{spaceId}/offers/allResponse (outer)
ts
type CompressedOffersResponse = {
compressedOffers: string // base64 gzip
}Inner JSON has an .items (or equivalent offers) array including offerId used by redeem.
Item catalogue
GET
https://public-ubiservices.ubi.com/v1/spaces/{spaceId}/items/allResponse (outer)
ts
type CompressedItemsResponse = {
compressedItems: string // base64 gzip
}After decode, each row is a CatalogueItem: itemId, name, tags[], item_type.
ts
zlib.gunzipSync(Buffer.from(res.compressedItems, 'base64'))Cache this. It is a patch-sized blob, not a per-user blob.
Clearance level
GET
https://public-ubiservices.ubi.com/v1/profiles/stats?spaceId={spaceId}&statNames=PClearanceLevel&profileIds={userId}Canonical account level for Siege.
Query
| Name | Value |
|---|---|
spaceId | R6 primary |
statNames | PClearanceLevel (comma-separate more stats if needed) |
profileIds | Target profile / user UUID |
Response
ts
type StatsResponse = {
profiles: Array<{
profileId: string
stats: {
PClearanceLevel: { value: number }
}
}>
}Read profiles[].stats.PClearanceLevel.value. Prefer this over the inventory Level item or the legacy rewards URL.
Legacy public profile rewards
GET
https://public-ubiservices.ubi.com/v1/spaces/{spaceId}/title/r6s/rewards/public_profile?profile_id={userId}Level + XP. Hit/miss — do not use as the canonical level. Use PClearanceLevel.