Skip to content

Overview

Looking for documentation for version 1 of the API?

You can still find it here.

Note: Version 1 of the API will be deprecated on January 1, 2026. Please plan your migration accordingly.

Location#

The API is available at https://api.bflist.io/v2/.

Pagination#

To handle the fast-moving environment with servers and players being constantly added and removed, the API uses cursor-based pagination.

Cursor#

Each response returning a list of objects also contains a cursor and hasMore property:

HTTP/1.1 200 OK
Content-Type: application/json
// [Request URI: https://api.bflist.io/v2/bf2/servers]

{
  "servers": [
    {
      "guid": "56be01-bfd9160-a0324d8-3e1af98",
      "ip": "37.230.210.130",
      "port": 16567,
      // more attributes
    },
    // more servers
  ],
  "cursor": "4c379877-b1f0-4534-8a4c-627d9503de9e",
  "hasMore": true
}

The cursor points to a snapshot of the requested list of objects. Any follow-up request using this cursor as a query parameter will return data from the same snapshot, ensuring consistency.

Snapshots are short-lived

Snapshots are temporary and are only stored for about 90 seconds. If the snapshot referenced by the provided cursor has expired, the API will respond with 410 Gone.

Because of this limited lifespan, we strongly recommend fetching all pages before processing the data.

To request the next page of servers, pass the cursor parameter and the {ip}:{port} of the last server on the current page as after.

HTTP/1.1 200 OK
Content-Type: application/json
// [Request URI: https://api.bflist.io/v2/bf2/servers?cursor=4c379877-b1f0-4534-8a4c-627d9503de9e&after=37.230.210.130:16567]

{
  "servers": [
    {
      "guid": "42fd2a6-399101e-c01aca-2cc568",
      "ip": "135.125.56.26",
      "port": 16469,
      // more attributes
    },
    // more servers
  ],
  "cursor": "4c379877-b1f0-4534-8a4c-627d9503de9e",
  "hasMore": false
}

Page size#

By default, the API returns up to 50 items per page. You can adjust the number of items by specifying a perPage query parameter, with a valid range of 20 to 100 (inclusive).

Use larger pages when possible

If you need to retrieve the entire list, we recommend using the largest page size that works for you. Larger page sizes mean fewer API requests—making things faster for you and reducing the load on our servers!

Example#

As an example, here's what an implementation of the client side could look like in JavaScript.

async function getServers() {
    let cursor;
    let after;
    let hasMore;
    const servers = [];
    do {
        const url = new URL(
            '/v2/bf2/servers',
            'https://api.bflist.io'
        );
        url.searchParams.set('perPage', '100');

        // Set pagination parameters if present
        if (cursor && after) {
            url.searchParams.set('cursor', cursor);
            url.searchParams.set('after', after);
        }

        const resp = await fetch(url);
        const data = await resp.json();

        for (const server of data.servers) {
            servers.push(server);
            // Update `after` marker on the fly (avoids having to pop() later)
            after = server.ip + ':' + server.port;
        }

        cursor = data.cursor;
        hasMore = data.hasMore;
    } while (hasMore);

    return servers;
}

Error messages#

Errors are returned as simple JSON objects containing only a message matching the status code. The contained messages are subject to change. If you need to detect the status of a response, use the HTTP status code instead.

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "message": "Not Found"
}

Migration#

This section will guide you through everything you need to know to smoothly migrate from version 1 to version 2 of the API. Most of the updates involve minor adjustments, mainly updating the endpoint URLs. However, there are a couple of breaking changes you'll want to pay special attention to:

  • Pagination: The server list endpoint now uses cursor-based pagination instead of offset-based pagination.
  • Property access: Direct access to individual server or player properties has been removed.

We'll walk you through each of these changes and provide examples to make the transition as straightforward as possible.

Endpoint URL pattern#

Versions 1 and 2 of the API use different URL patterns:

  • https://api.bflist.io/{game}/v1/...
  • https://api.bflist.io/v2/{game}/...

For version 1, the idea was to allow each game to have its own API versioning. However, since we never had to make significant changes for individual games, we simplified the URL pattern in version 2.

Pagination#

The main motivation for creating and releasing version 2 of the API was to address issues with pagination. In version 1, the way pagination was handled could sometimes lead to inconsistencies because servers and players are constantly being added and removed.

Version 2 solves these challenges by using temporarily stored snapshots of the list for pagination. These snapshots ensure that any changes to the list of servers won’t affect a running set of paginated API requests.

For details regarding pagination in version 2, refer to this section.

Property access#

Version 1 allowed direct access to server or player properties by appending the property name to the endpoint URL. For example, you could request a server's name in plain text directly via:

GET /{game}/v1/servers/{ip}:{port}/name HTTP/1.1

This feature was originally designed to help in environments where working with JSON might be challenging (like Twitch bot chat commands). However, environments like these can now be better served by the chat message API from statbits.io.

To reduce complexity, we completely removed the ability to access individual server or player properties in version 2.