Freedom Street

Socket API

The Socket API provides real-time cryptocurrency data through Server-Sent Events (SSE). It streams live transactions, blocks, and RBF replacements from multiple networks. Events use the same { time, type, crypto, data } envelope as the Query API, so the same data structures and query patterns work across both.

Endpoint

GET https://sock.freedom.st/sse?q={base64-encoded-query}

Connection

Connect by opening an EventSource to the endpoint. The server sends a heartbeat every 5 seconds to keep the connection alive. Events arrive as JSON in the data field of each SSE message.

const query = btoa(JSON.stringify({
  find: { crypto: "btc", type: "tx" }
}));
const source = new EventSource(`https://sock.freedom.st/sse?q=${query}`);

source.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log(data);
};

An empty query {} streams all events across all networks.

Query Language

The socket uses the same query language as the Query API. Your query is a JSON object, base64-encoded and passed as the q parameter.

{
  "find": { ... },
  "project": [ ... ]
}

find contains filter conditions. Each field must match for an event to be streamed.

project is optional. When provided, only the specified fields are included in streamed events.

Operators

Operator Meaning Example
(direct value) Equals { "crypto": "btc" }
(array value) Any of { "crypto": ["btc", "ltc"] }
eq Equal to { "data.fee": { "eq": 0.001 } }
ne Not equal to { "crypto": { "ne": "btc" } }
gt Greater than { "data.fee": { "gt": 0.001 } }
lt Less than { "data.size": { "lt": 500 } }
ge Greater/equal { "data.size": { "ge": 5000 } }
le Less/equal { "data.to.amount": { "le": 0.01 } }
sw Starts with { "data.to.address": { "sw": "bc1q" } }
ew Ends with { "data.to.address": { "ew": "abc" } }
co Contains { "data.mining.miner_message": { "co": "pool" } }

Multiple operators can be combined on the same field: { "data.fee": { "gt": 0.001, "lt": 0.1 } }

All string matching is case-insensitive. Every operator accepts both a single value and an array of values. With an array, the condition matches if any element satisfies it (except ne, which requires none to match).

Dot-path notation

Use dot-separated paths to query nested fields. For example, data.fee accesses the fee field inside data.

When a path passes through an array (like data.to), the condition matches if any element in the array satisfies it. This means "data.to.amount": { "gt": 1 } matches a transaction if at least one output has an amount greater than 1.

Queryable Fields

Path Type Description
type string "tx", "block", or "rbf"
crypto string Network: btc, bch, ltc, doge, dash, xec
data.seen number When first indexed (Unix seconds)
data.hash string Transaction or block hash
data.block string/null Block hash (null if unconfirmed)
data.fee number Transaction fee
data.fee_usd number Fee in USD
data.size number Transaction or block size in bytes
data.from.address string Input address
data.from.amount number Input amount
data.to.address string Output address
data.to.amount number Output amount
data.to.script_type string Output script type
data.height number Block height
data.mining.miner string Mining pool name

Networks

Code Network
btc Bitcoin
bch Bitcoin Cash
ltc Litecoin
doge Dogecoin
dash Dash
xec eCash

Event Types

Type Description
tx New transaction
block New block
rbf Replace-By-Fee replacement

Query Examples

Stream everything

{}

Only blocks

{
  "find": { "type": "block" }
}

BTC and LTC transactions

{
  "find": {
    "crypto": ["btc", "ltc"],
    "type": "tx"
  }
}

Everything except BTC

{
  "find": { "crypto": { "ne": "btc" } }
}

Transactions with an output over 10 BTC

{
  "find": {
    "crypto": "btc",
    "type": "tx",
    "data.to.amount": { "gt": 10 }
  }
}

Transactions over 5KB

{
  "find": {
    "type": "tx",
    "data.size": { "ge": 5000 }
  }
}

Monitor an address for incoming payments

{
  "find": {
    "data.to.address": "bc1qryhgpmfv03qjhhp2dj8nw8g4ewg08jzmgy3cyx"
  }
}

RBF replacements

{
  "find": { "type": "rbf" }
}

OP_RETURN and multisig outputs

{
  "find": {
    "type": "tx",
    "data.to.script_type": ["nulldata", "multisig"]
  }
}

Only stream hash and fee (projection)

{
  "find": { "type": "tx", "crypto": "btc" },
  "project": ["data.hash", "data.fee", "data.fee_usd"]
}

Address prefix matching for k-anonymity

By querying a prefix instead of a full address, the server cannot determine which specific address you are monitoring. The shorter the prefix, the more addresses match, providing stronger privacy. Filter for your exact address client-side.

{
  "find": {
    "type": "tx",
    "data.to.address": { "sw": "bc1q0awq9" }
  }
}

Since every operator accepts arrays, you can monitor multiple address prefixes in a single connection:

{
  "find": {
    "type": "tx",
    "data.to.address": { "sw": ["bc1q0awq9", "1Df43", "36hNC"] }
  }
}

Event Data

All events share the same envelope: type, crypto, and data. The data.seen field is a unix timestamp (seconds) indicating when the event was first indexed. This format is identical to how events are returned by the Query API, so the same data structures work across both SSE and HTTP.

Transaction

{
  "type": "tx",
  "crypto": "btc",
  "data": {
    "hash": "287a1af93ffa2e0f86071670344ab867c50256b3ed5b2ff8e1ac6bf2a6673c9a",
    "version": 2,
    "locktime": 943587,
    "seen": 1775278749,
    "mined": null,
    "block": null,
    "size": 222,
    "fee": 0.00000141,
    "fee_usd": 0.09,
    "from": [
      {
        "hash": "bd78d64b339a01fa740af6b7f15a51f78e61c6a3f4bc4162c1ae131bf6f11570",
        "index": 1,
        "sequence": 4294967293,
        "address": "bc1qnj93mcjyf7a6pxr7x4uzd3dn82tqsszgu4erp5",
        "script_type": "witness_v0_keyhash",
        "amount": 0.02605691,
        "amount_usd": 1742.12
      }
    ],
    "to": [
      {
        "index": 0,
        "address": "bc1q3kxmhgz7jr4mngxeeluegqz24gknfmwdzkx3nz",
        "script_type": "witness_v0_keyhash",
        "script": "00148d8dbba05e90ebb9a0d9cff994004aaa2d34edcd",
        "amount": 0.0024,
        "amount_usd": 160.46
      },
      {
        "index": 1,
        "address": "bc1q2th7r9ms67c3w0r3qx2he9vdaa4chz5ljj7ent",
        "script_type": "witness_v0_keyhash",
        "script": "001452efe19770d7b1173c7101957c958def6b8b8a9f",
        "amount": 0.0236555,
        "amount_usd": 1581.56
      }
    ],
    "vsize": 141,
    "weight": 561
  }
}

Block

{
  "type": "block",
  "crypto": "btc",
  "data": {
    "hash": "000000000000000000010391f292467e02d166a172684750f23222f6d75c5e05",
    "height": 943587,
    "version": "2c2da000",
    "seen": 1775278334,
    "mined": 1775278318,
    "previous_block": "000000000000000000018abc2b20bc00fae79ba53770106122e47420c93ef23c",
    "next_block": null,
    "merkle_root": "a853b0b15fbab2897b21cd78d97b2dc9748b67bb049079df2c1b65cd3a5d8aa3",
    "size": 1550516,
    "weight": 3993707,
    "mining": {
      "nonce": 868323383,
      "bits": "17020684",
      "difficulty": "138966872071213",
      "chainwork": "00000000000000000000000000000000000000011cc048b774f70b6bf763eb60",
      "miner": "Foundry USA",
      "miner_message": "/Foundry USA Pool #dropgold/..."
    },
    "reward": {
      "hash": "b475a4ff15a75b8c077c627eed7f6dd70f4ccde24f5099ab9adcc662981caee6",
      "subsidy": 3.125,
      "subsidy_usd": 208892.28,
      "fees": 0.0273978,
      "fees_usd": 1831.42
    },
    "transactions": [
      "b475a4ff15a75b8c077c627eed7f6dd70f4ccde24f5099ab9adcc662981caee6",
      "..."
    ]
  }
}

RBF Replacement

{
  "type": "rbf",
  "crypto": "btc",
  "data": {
    "seen": 1775278749,
    "replaced": true,
    "opt_in": true,
    "outputs_changed": true,
    "old_hash": "048b6041694f0ee1567a55d015661bfcbf3d6771d60cbc28040f2d59c1b0937d",
    "old_fee": 0.00000203,
    "old_fee_usd": 0.14,
    "new_hash": "5856d22c50e42be84cedee272031190a0954cabe91392348f7aad35f184de807",
    "new_fee": 0.00000468,
    "new_fee_usd": 0.31
  }
}