Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

22 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

dbfz-api-py

Async library for interfacing with the replay REST API of Dragonball FighterZ.

Massively inspired by Felix WindstrΓΆm's creation of http://ratingupdate.info/.

Please keep in mind this is a Python implementation of dealing with the API. Depending on how Messagepack is done on your preferred language, some aspects may change.

How the API works

How the API works

The API works by sending a POST request to https://dbf.channel.or.jp/api/catalog/get_replay. The header needs to contain Content Type: application/x-www-form-urlencoded as you need to pass a hex (non-escaped) encoded messagepack to the server.

The server will then give a response back in hex encoded messagepack which can be unpacked.

The request for the replay requires having a very specific timestamp(?) which is in hex, this can be gotten by using sending a POST request to https://dbf.channel.or.jp/api/user/login. Follows the same suite as above.

Headers

headers = {
    "Host": "dbf.channel.or.jp",
    'Content-Type': 'application/x-www-form-urlencoded',
}

These are the only headers needed for sending a request to the API endpoints (For a lot of these headers, they're VERY specific to your own game login which can be found by using a packet sniffer application such as Fiddler to find these out)

Making request

JSON Structure for login_url

[
    [
        "", 
        "", 
        2,
        "0.0.3", 
        103
    ],
    [
        "76561198077238919", # SteamID in decimal
        "110000106f8de9a", # SteamID in hexadecimal
        256, 
        0
    ]
]

The workflow for sending to api is:

  1. Get json and pack to msgpack
  2. Add to another json and add to the key "data", and transform the escaped hex to hex. For example: binascii.hexlify(msgpack.packb(loginData)). Example of the hex would be dd00000002dd00000005a0a002a5302e302e3303dd00000004b13736353631313938303737323338393339af313130303030313036663864653962cd010000
  3. POST to the api as data= and response will be plaintext msgpack to be decoded using msgpack.unpackb()

After, you get a response from the server such as the following:

[
    [
        "636d55d3a3736",
        0,
        "2022/11/11 04:49:39",
        "0.0.3",
        "0.0.3",
        "0.0.3",
        "",
        ""
    ],
    [
        0,
        [
            "180205073302944621",
            "Deviance",
            "76561198077238939",
            "110000106f8de9b",
            869826
        ]
    ]
]

Which you take the first value (in the example above would be 636d55d3a3736) and put that into the JSON for the get_replay_url below as this is the handshake token needed to verify the user.

JSON Structure for get_replay_url

[
  [
    "180205073302944621", # player ID doing request, please use your own player ID as this rate limits the actual user from playing
    "636d55d3a3736", # handshake token taken from loggging into the servers
    2, # unknown
    "0.0.3", # game version
    103 # unknown, probably platform such as PC and PS4
  ],
  [
    7, # unknown
    1, # order by [1: newest, 2: views, etc]
    0, # number of replay pages scrolled (starts at 0), max is 50000 upwards but gets very slow so best to stick to 5000 or less
    10, # number of matches queried, can be more than 10000
    [
      35, # current game build number
      -1, # character list, [all character: -1, ssj goku: 0, ssj vegeta: 1, etc] always goes upwards (easy to make enum)
      102, # query for play mode, [all modes: -1 , ranked: 102 , casual: 104, arena: 103, ring: 105, ring party match: 107, tournament: 110]
      1, # queries from this number downwards up to 10 ranks (starts at 1), can go up to 50000 upwards but gets very slow so best to stick to 5000 or less
      -1, # unknown
      []
    ]
  ]
]

Workflow to Send Request

The workflow for sending to api is:

  1. Get json and pack to msgpack
  2. Add to another json and add to the key "data", and transform the escaped hex to hex. For example: binascii.hexlify(msgpack.packb(replayData))
  3. POST to the api as data= and response will be plaintext msgpack to be decoded using msgpack.unpackb()

OR

  1. Get msgpack data (such as 9295b2313830323035303733333032393434363233ad3633356661306433313734303802a5302e302e3303950701000a961cffff01ff90)
  2. Add to another json and add to the key "data"
  3. POST to the api as data= and response will be plaintext msgpack to be decoded using msgpack.unpackb()

Parsing response

Converting from Messagepack to JSON

You can unpack the messagepack using msgpack.unpackb(), however each item in the JSON will be encoded so manually decoding via the functions provided (decode_list and subsequently decode_dict) helps it be parsed as a json

JSON Structure

The JSON always has 10 matches inside it with the first player always being the winner. A shortened example with only one match is annotated below:

[
    [
        "6365b7aff20b5",
        0,
        "2022/11/05 10:09:03", # time it was queried in JST (irrelevant to the actual match stats)
        "0.0.3",
        "0.0.3",
        "0.0.3",
        "",
        ""
    ],
    [
        0, 
        10,
        [
            [
                221105064149496874, # unique identifer for the match itself
                28,
                "WIN_PlmRVer035",
                [ # characters for player who won
                    0,
                    39,
                    38
                ],
                [# characters for player who lost
                    0,
                    31,
                    19
                ],
                [ # person who won
                    [
                        "211127010233268016", # player ID who won
                        "Deviance",
                        "76561199013492555",
                        "11000013ec6f74b",
                        856119
                    ],
                    [
                        "0",
                        "",
                        "",
                        "",
                        0
                    ],
                    [
                        "0",
                        "",
                        "",
                        "",
                        0
                    ]
                ],
                [ # person who lost
                    [
                        "210319054513269637", # player ID who lost
                        "paddu",
                        "76561199080463934",
                        "110000142c4de3e",
                        829720
                    ],
                    [
                        "0",
                        "",
                        "",
                        "",
                        0
                    ],
                    [
                        "0",
                        "",
                        "",
                        "",
                        0
                    ]
                ],
                1,
                "2022-11-05 20:41:43", # timestamp of the match (UTC? or Japan time?)
                102,
                0,
                1,
                "",
                "",
                ""
            ]
        ]
    ]
]
Reference guide: All reverse engineered parts of the API

DBFZ Replay API (Reverse Engineered)

πŸ“€ Request (Client β†’ Server) for replay_url

Request JSON

[
  [
    "player_id": "180205073302944623",
    "session_token": "6a425002dd0b1",
    "auth_type: 2",
    "client_version": "0.0.3",
    "build_id: 103"
  ],
  [
    "opcode: 7",
    "order_by: 1",
    "replay_page_offset: 0",
    "limit: 10",
    [
      "mode: 104", // all modes: -1 , ranked: 102 , casual: 104, arena: 103, ring: 105, ring party match: 107, tournament: 110
      "character_filter: -1", // [all character: -1, ssj goku: 0, ssj vegeta: 1, etc] always goes upwards
      "version_filter: 35",
      "number_of_replays: 1",
      "unknown1: -1",
      "unknown_list: []"
    ]
  ]
]

Structure

[ [ AUTH_BLOCK ], [ QUERY_BLOCK ] ]


AUTH_BLOCK

[ playerId, sessionToken, authType, clientVersion, buildId ]

Fields

  • playerId β†’ internal account ID
  • sessionToken β†’ login/session token
  • authType β†’ login type flag
  • clientVersion β†’ game version (e.g. "0.0.3")
  • buildId β†’ internal build number

QUERY_BLOCK

[ mode, page, offset, limit, filters ]

mode (match type)

  • -1 = all modes
  • 102 = ranked
  • 103 = arena
  • 104 = casual
  • 105 = ring
  • 107 = ring party
  • 110 = tournament

pagination

  • page β†’ page index
  • offset β†’ usually 0

limit

  • number of replays to fetch
  • example: 10 = latest 10 replays

filters

[ character, unknown, version, rankedFlag, unknown, extraList ]


character filter

  • -1 = all characters
  • 0+ = character enum ID

πŸ“₯ Response (Server β†’ Client)

Structure

[ [ SERVER_META ], [ RESULT_BLOCK ] ]


SERVER_META

[ sessionId, statusCode, serverTime, clientVersion, serverVersion, latestVersion, message, updateUrl ]

  • statusCode = 0 success
  • serverTime = UTC timestamp string
  • version fields = build/version info

RESULT_BLOCK

[ statusCode, replayCount, replayList ]


replayList entry

[ replayId, characterSet, gameVersion, teamA, teamB, playerA, playerB, flags, timestamp, ratingBucket, resultFlags ]


characterSet

[ char1, char2, char3 ]

  • 0+ = character enum IDs
  • -1 = none

player structure

[ playerId, displayName, steamId64, steamIdHex, profileId ]


gameVersion

  • numeric build (e.g. 35)
  • matches string version (e.g. WIN_PlmRVer035)

timestamp

  • UTC string format
  • example: 2026-06-29 17:17:36

Notes

  • -1 = wildcard / no filter
  • integers = enums or flags
  • arrays = structured objects
  • protocol is RPC-style, not REST
  • optimized for replay retrieval and matchmaking history

About

Async library for interfacing with the replay REST API of Dragonball FighterZ

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages