Developer API

Build custom Second Life integrations with the FixedBit Streams API. Create tip jars, venue greeters, now-playing displays, and more.

API Overview

Base URL: https://fixedbit.stream/api/v1
Auth: X-FixedBit-Key header
Format: JSON

All API requests require your API key sent in the X-FixedBit-Key header. You can find your API key in the dashboard.

Rate Limiting

API requests are rate limited to 30 requests per minute per API key. If you exceed the limit, you will receive a 429 Too Many Requests response. Wait 60 seconds before retrying.

For LSL scripts, use llSetTimerEvent(15.0) or longer intervals to stay well within the limit.

Endpoint Reference

Method Path Description
GET /api/v1/stream/status Stream online/offline status, listener count, bitrate
GET /api/v1/stream/now-playing Current artist and title
GET /api/v1/stream/history Last 10 songs played
GET /api/v1/stream/details Subdomain, land URL, protocol info
GET /api/v1/account/rental Rental tier, time remaining, expiry date
POST /api/v1/stream/metadata Set custom metadata fields (owner only)
POST /api/v1/stream/title Override stream title (owner only)

Example Responses

GET /api/v1/stream/status

{
  "online": true,
  "listeners": 7,
  "max_listeners": 100,
  "bitrate": 128,
  "source_connected": true
}

GET /api/v1/stream/now-playing

{
  "artist": "DJ Goat",
  "title": "Summer Vibes Mix",
  "duration": 0,
  "listeners": 7
}

GET /api/v1/stream/history

{
  "songs": [
    {"artist": "DJ Goat", "title": "Summer Vibes Mix", "played_at": "2026-03-30T14:22:00Z"},
    {"artist": "DJ Goat", "title": "Chill Beats", "played_at": "2026-03-30T14:10:00Z"}
  ]
}

LSL Code Examples

Copy-paste ready scripts for Second Life. Replace YOUR_API_KEY with your actual API key from the dashboard.

Get Now Playing

string API_KEY = "YOUR_API_KEY";
string BASE_URL = "https://fixedbit.stream/api/v1";
key http_req;

default
{
    state_entry()
    {
        llSetTimerEvent(15.0);
    }

    timer()
    {
        http_req = llHTTPRequest(
            BASE_URL + "/stream/now-playing",
            [HTTP_METHOD, "GET",
             HTTP_CUSTOM_HEADER, "X-FixedBit-Key", API_KEY],
            ""
        );
    }

    http_response(key req, integer status, list meta, string body)
    {
        if (req != http_req) return;
        if (status != 200) return;

        // Parse JSON response
        string artist = llJsonGetValue(body, ["artist"]);
        string title = llJsonGetValue(body, ["title"]);
        integer listeners = (integer)llJsonGetValue(body, ["listeners"]);

        llSetText(
            artist + " - " + title + "\n" +
            (string)listeners + " listeners\n" +
            "Stream by FixedBit Streams",
            <1.0, 1.0, 1.0>, 1.0
        );
    }
}

Get Listener Count

string API_KEY = "YOUR_API_KEY";
string BASE_URL = "https://fixedbit.stream/api/v1";
key http_req;

default
{
    state_entry()
    {
        llSetTimerEvent(15.0);
    }

    timer()
    {
        http_req = llHTTPRequest(
            BASE_URL + "/stream/status",
            [HTTP_METHOD, "GET",
             HTTP_CUSTOM_HEADER, "X-FixedBit-Key", API_KEY],
            ""
        );
    }

    http_response(key req, integer status, list meta, string body)
    {
        if (req != http_req) return;
        if (status != 200) return;

        integer listeners = (integer)llJsonGetValue(body, ["listeners"]);
        integer max_listeners = (integer)llJsonGetValue(body, ["max_listeners"]);
        string online = llJsonGetValue(body, ["online"]);

        if (online == "true")
        {
            llSetText(
                "LIVE\n" +
                (string)listeners + " / " + (string)max_listeners + " listeners",
                <0.0, 1.0, 0.0>, 1.0
            );
        }
        else
        {
            llSetText("OFFLINE", <0.5, 0.5, 0.5>, 1.0);
        }
    }
}

Get Stream Status

string API_KEY = "YOUR_API_KEY";
string BASE_URL = "https://fixedbit.stream/api/v1";
key http_req;

default
{
    state_entry()
    {
        llSetTimerEvent(30.0);
    }

    timer()
    {
        http_req = llHTTPRequest(
            BASE_URL + "/stream/status",
            [HTTP_METHOD, "GET",
             HTTP_CUSTOM_HEADER, "X-FixedBit-Key", API_KEY],
            ""
        );
    }

    http_response(key req, integer status, list meta, string body)
    {
        if (req != http_req) return;
        if (status != 200)
        {
            llOwnerSay("FixedBit API error: " + (string)status);
            return;
        }

        string online = llJsonGetValue(body, ["online"]);
        integer listeners = (integer)llJsonGetValue(body, ["listeners"]);
        integer bitrate = (integer)llJsonGetValue(body, ["bitrate"]);

        llOwnerSay("Stream: " + online +
                   " | Listeners: " + (string)listeners +
                   " | Bitrate: " + (string)bitrate + " kbps");
    }
}

Authentication

Every API request must include your API key in the X-FixedBit-Key header.

GET /api/v1/stream/status HTTP/1.1
Host: fixedbit.stream
X-FixedBit-Key: your-api-key-here

Your API key is generated when you first rent a stream. You can view and regenerate it from the API Keys page in your dashboard. Regenerating your key invalidates the old one immediately.

Error Responses

Status Meaning
200 Request successful
401 Missing or invalid API key
404 No active stream found for this account
429 Rate limit exceeded (30 requests/minute)
500 Internal server error