Documentation

Build on the Lineage HTTP API

Read chain state, submit transactions, and query node metadata directly over HTTP. No smart contracts required. Move through node concepts, the mempool, storage, and miner reference, and the SDK tutorials using the contents tree.

Contents

Documentation / Overview

Lineage HTTP API

The Lineage HTTP API lets you integrate with the network directly: read chain state, submit transactions, and query node metadata. None of the flows in this documentation require on-chain smart contracts. Use a plain HTTP client (curl, fetch, or your language of choice) against the endpoints listed under each subsystem.

Routes are grouped by node class. Each class is served from its own origin, so confirm which host a route belongs to before you call it, as sending a storage read to the mempool host (or vice versa) will not resolve.

Public service URLs

These are the public reference hosts used in every example below.

Node classBase URLUse for
Mempoolhttps://mempool.lineage.toTransactions, balances, supply, mempool metadata
Storagehttps://storage.lineage.toBlocks, chain entries, read-oriented history
Minerhttps://miner.lineage.toOperator-facing HTTP where exposed (small surface)

Request & response envelope

Operations are POST to a path named after the route (for example/fetch_balance on the mempool host). Read-only routes take an empty body; routes that need input take a JSON body documented per endpoint. Every request carries two headers:

  • Content-Type: application/json
  • x-cache-id: a 32-character idempotency key matching ^[a-z0-9]{32}$.

Every response uses the same envelope. Field semantics:

FieldMeaning
idEchoes the request's x-cache-id (null on a rejected request).
statusOne of Success, Error, or Pending.
reasonHuman-readable context, most useful on errors.
routeThe route name that was handled.
contentThe route-specific payload. Shape varies by route (documented below).

Error envelope

json
{"id": null,"status": "Error","reason": "Bad Request","route": null,"content": null}

API quick start

Pick a node class, point your HTTP client at its base URL, and verify connectivity with a read-only route before sending anything that writes. A good first call isstorage latest_block ormempool fetch_balance.

shell
# 1 — check the chain head on the storage hostcurl -sS -X POST "https://storage.lineage.to/latest_block" \ -H "Content-Type: application/json" \ -H "x-cache-id: 0123456789abcdef0123456789abcdef"\ -d ''
NoteExact content field names and nesting are defined by the node release. See the Lineage Foundation repositories for the schema shipped by your target deployment.

Node types

Lineage separates three roles so that who assembles a block, who stores history, and who expends hashrate this round are independent jobs.Mempool nodes collect transactions and coordinate validation;miner nodes perform proof-of-work to produce block candidates and earn rewards; storage nodes retain full chain history and serve reads to clients. The split enables fast settlement, geographic resilience, and specialised hardware without forcing archival storage on every participant.

Mempool node

A bounded set of long-lived components that accept user transactions, batch them into blocks, and work with the mining network. Each round, the mempool set advances valid transactions, agrees on ordering within protocol rules, hands a candidate to miners, then validates the winner's block and forwards it to storage. Mempool and miner responsibilities are interdependent, and both must make progress for the chain to advance.

Storage node

Keeps full chain history, receives valid blocks (typically along the mempool path), and replicates them for durability and API consumers. Its core job is persisting blocks and building indices for header, transaction-id, and proof lookups. Distributed consensus between storage operators keeps replicas agreeing on the same head, and witness data is preserved so light clients and auditors can re-check proofs.

Miner node

Miners compete to extend the chain when it is their turn. They receive work units from the mempool, find valid proofs, and return them so the mempool declares a winner and forwards the block to storage. The protocol does not require every miner to grind on the same block simultaneously; a subset is selected each round, keeping energy use proportionate. Rewards follow the network's token rules once a block is accepted.

Block mining

Producing a block is a multi-step collaboration: (1) client transactions are queued by the mempool; (2) when a round starts, a block body is built from the queue and offered to selected miners; (3) miners produce proofs and return candidates; (4) the mempool picks a winner, validates the block, and sends it to storage. A single per-round randomness object (a UNiCORN), derived from agreed inputs such as the transactions, the eligible miner set, and prior-round metadata, drives who may mine and who wins.

Transactions

Lineage uses a UTXO model: a transaction spends one or more previous outputs and creates new outputs that a later spend can refer to. There is no global account balance in the contract layer; a balance is a view over unspent outputs. Each input points at a previous transaction hash and output index with a script proving spend authorisation; each output states a locked value and its script (for example pay-to-pubkey-hash). Transactions carry a version and optional application-specific data (such as DRUID or item metadata) that higher layers interpret.

Two-way transactions

A two-way transaction lets two parties each contribute compatible halves to a single block, so an exchange or payment clears atomically without a smart-contract runtime. It is the mechanism for flows where both sides must sign before either side's funds move. Wallets and SDKs hide most of the wiring.

UNiCORN randomness

A UNiCORN, an UN-COntestable Random Number, is a randomness-and-witness object generated so that no single participant can steer it toward anything but a random result. It depends on the transactions in the block, which miners are eligible, and recent chain state, so winner selection is hard to bias without breaking consensus. The protocol uses it to restrict which miners may attempt work in a round, to choose the winning valid proof, and to supply the data storage nodes re-check during validation.

POST info

https://mempool.lineage.to/info

Returns metadata about the mempool node, including its node type and the routes it exposes. Empty body; x-cache-id header only.

Example response

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Node info","route": "info","content": {"node_type": "Mempool","node_api": [ "debug_data", "fetch_balance", "create_transactions", "create_item_asset", "total_supply", "issued_supply" ]}}

POST debug_data

https://mempool.lineage.to/debug_data

Node diagnostics for the mempool: its node type, the routes it exposes, and the peers it is connected to. Empty body; x-cache-id header only.

Example response

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Debug data successfully retrieved","route": "debug_data","content": {"node_type": "Mempool","node_api": [ "debug_data", "fetch_balance", "create_transactions", "create_item_asset", "total_supply", "issued_supply" ],"node_peers": [ "<peer-address>" ]}}

POST fetch_balance

https://mempool.lineage.to/fetch_balance

Fetch token and item balances for one or more addresses. The request body is a JSON array of address strings.

Request body

json
[ "<address-1>", "<address-2>" ]

Example response

json
{"id": "45v340cd2f8c4782a5b058832565afb1","status": "Success","reason": "Balance successfully fetched","route": "fetch_balance","content": {"total": { "tokens": 5463669, "items": {} },"address_list": {"d6fa779a3de8b216c56375018375e490c7e2ce92918abce4caecf73b1f77c38f": [{"out_point": { "t_hash": "g9182e1e2a55b0ef36f1183602d74e63", "n": 0 },"value": { "Token": 5463669 }}]}}}

POST create_transactions

https://mempool.lineage.to/create_transactions

Submit one or more fully formed UTXO-style transactions to the mempool. Each input references a previous_out and carries a script signature (Pay2PkH); each output states a value, locktime, and script public key. Adruid_info block is included only for two-way transactions.

Request body (shape)

json
{"inputs": [{ "previous_out": { "t_hash": "<hex>", "n": 0 }, "script_signature": { /* Pay2PkH */ } }],"outputs": [{ "value": { "Token": 1000 }, "locktime": 0, "script_public_key": "<script>" }],"version": 1,"druid_info": null}

Example response

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Transaction/s successfully created","route": "create_transactions","content": { "transaction": { "tx_hash": "<32-byte-hex>" } }}

POST create_item_asset

https://mempool.lineage.to/create_item_asset

Create a new item-type asset with an amount, a script public key, a public key, a signature, and a DRS spec.

Request body

json
{"item_amount": 1,"script_public_key": "<script>","public_key": "<hex>","signature": "<hex>","drs_tx_hash_spec": "default"}

Example response

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Item asset created","route": "create_item_asset","content": { "item_amount": 1, "tx_hash": "<32-byte-hex>", "metadata": {} }}

POST total_supply

https://mempool.lineage.to/total_supply

Returns the total token supply figure. Empty body; x-cache-id header only. content is a numeric value in the standard envelope.

Request

shell
curl -sS -X POST "https://mempool.lineage.to/total_supply" \ -H "Content-Type: application/json" \ -H "x-cache-id: <32-lowercase-hex>"\ -d ''

Example response

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Supply returned","route": "total_supply","content": 0}

POST issued_supply

https://mempool.lineage.to/issued_supply

Returns the issued token supply figure. Same call shape as total_supply: empty body, numeric content.

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Supply returned","route": "issued_supply","content": 0}

POST info

https://storage.lineage.to/info

Returns metadata about the storage node, including its node type and the read routes it serves. Empty body; x-cache-id header only.

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Node info","route": "info","content": {"node_type": "Storage","node_api": [ "debug_data", "latest_block", "block_by_num", "blockchain_entry" ]}}

POST debug_data

https://storage.lineage.to/debug_data

Node diagnostics for the storage node: node type, the read routes it serves, and connected peers. Empty body; x-cache-id header only.

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Debug data successfully retrieved","route": "debug_data","content": {"node_type": "Storage","node_api": [ "debug_data", "latest_block", "block_by_num", "blockchain_entry" ],"node_peers": [ "<peer-address>" ]}}

POST latest_block

https://storage.lineage.to/latest_block

Returns the best block this storage node has received and stored. Empty body; x-cache-id header only.

Request

shell
curl -sS -X POST "https://storage.lineage.to/latest_block" \ -H "Content-Type: application/json" \ -H "x-cache-id: <32-lowercase-hex>"\ -d ''

Example response

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Latest block","route": "latest_block","content": {"height": 12345,"block_hash": "<32-byte-hex header hash>","prev_block": "<hex or null for genesis parent>","merkle": "<root hex>","tx_ids": [ "<tx-id-1>", "<tx-id-2>" ],"header": {}}}

POST block_by_num

https://storage.lineage.to/block_by_num

Fetch one or more blocks by height. The request body is a JSON array of non-negative integers. content returns one nested result per requested height, in order.

Request body

json
[ 0, 1, 42 ]

Example response

json
{"id": "45v340cd2f8c4782a5b058832565afb1","status": "Success","reason": "Database item(s) successfully retrieved","route": "block_by_num","content": [ ["<block-hash hex>",{ "block": { "header": { "b_num": 0, "previous_hash": null, "merkle_root_hash": "<hex>" }, "transactions": [ "<tx-id>" ] } }] ]}

The inner block object is defined by the node release; content nesting mirrors the order of the requested heights.

POST blockchain_entry

https://storage.lineage.to/blockchain_entry

Fetch a block or a transaction by hash. The request body is a single JSON string (the hash), not an object. The returned content is tagged with a type of either block or transaction.

Request body

json
"<hex-or-encoded-hash>"

Response: block

json
{"status": "Success","route": "blockchain_entry","content": { "type": "block", "height": 100, "block_hash": "<hex>", "tx_ids": [ "<tx-id>" ], "header": {} }}

Response: transaction

json
{"status": "Success","route": "blockchain_entry","content": {"type": "transaction","tx_hash": "<hex>","inputs": [ { "previous_out": { "t_hash": "<hex>", "n": 0 }, "script_signature": {} } ],"outputs": [ { "value": { "Token": 0 }, "locktime": 0, "script_public_key": "<script>" } ],"version": 1}}

POST info

https://miner.lineage.to/info

Miner nodes build new blocks from work assigned through the mempool, compete for partition slots, and claim rewards when a block is accepted. The HTTP surface exposed to operators is deliberately small compared with mempool and storage; most mining logic runs inside the process rather than as ad hoc REST calls. inforeturns the standard envelope describing the running node.

Running a minerFor practical operation, including installing a node, hardware, key management, and release-specific flags, see Running a node and the lineage-foundation/fleet repository.

POST debug_data

https://miner.lineage.to/debug_data

Node diagnostics for a miner: node type, the routes it exposes, and the mempool/storage peers it is connected to. Empty body; x-cache-id header only.

json
{"id": "<matches x-cache-id>","status": "Success","reason": "Debug data successfully retrieved","route": "debug_data","content": {"node_type": "Miner","node_api": [ "debug_data" ],"node_peers": [ "<peer-address>" ]}}

SDKs & tutorials

Beyond the raw endpoint reference, Lineage ships official client libraries in three languages plus node tooling. The full walkthroughs and runnable code live in the published repositories; the cards below summarise each SDK and where it fits. All three wrap the same HTTP API documented above; configure each with a mempool base URL, a storage base URL, and a passphrase for local key encryption.

Install

Add the client for your stack. Confirm the published package name in each repository's README.

shell
# JavaScript / TypeScriptnpm install @lineage/sdk-js# Pythonpip install git+https://github.com/lineage-foundation/sdk-python# PHPcomposer require lineage-foundation/sdk-php

First call

Create a Wallet, point it at a mempool host with a passphrase for local key encryption, and initialise a new keypair. initNew returns the generated seed phrase. Store it securely; it is the only way to recover the wallet.

javascript
import { Wallet } from '@lineage/sdk-js';const wallet = new Wallet();const CONFIG = {mempoolHost: 'https://mempool.lineage.to', passphrase: 'a secure passphrase',}; wallet.initNew(CONFIG).then((res) => {console.log(res.content.initNewResponse.seedphrase);});

sdk-js

The JavaScript / TypeScript client for browser and Node apps and wallets: create a wallet, create items and assets, run two-way payments, send and receive. Drop-in for web front-ends and Valence servers.

lineage-foundation/sdk-js

sdk-python

The Python client for backends, data tooling, and automation: key management, balance and supply reads, transaction construction, and two-way flows. It covers the same surface as sdk-js, idiomatic for Python services and notebooks.

lineage-foundation/sdk-python

sdk-php

The PHP client for server-side web stacks: wallet creation, asset issuance, payments, and chain reads from within PHP applications and CMS integrations.

lineage-foundation/sdk-php

Valence node & core

The application-server pattern. Valence node exposes HTTP routes (health checks, JSON forwarding, optional static/webhook endpoints); Valence core is the embeddable part with lifecycle hooks and plugin registration. Plugins add application behaviour but never change chain rules.

Repositories

API usage

A guided order of operations for calling the public HTTP API directly: pick a node class, verify connectivity with a read-only route, then move on to writes. Start from the quick start above.

Service URLs

Running a node

The fastest way to stand up a full Lineage stack (mempool, storage, and miner) is the lineage-foundation/fleet repository, which ships a Docker Compose stack and a from-source build. The steps below mirror its README.

Prerequisites

A recent Rust toolchain and the Linux build dependencies. On Ubuntu:

shell
sudo apt-get update && sudo apt-get install -y \ build-essential m4 llvm libclang-dev clang cmake pkg-config \ git curl python3 libglfw3-dev libxrandr-dev libxinerama-dev \ libxcursor-dev libxi-dev
shell
# install Rustcurl https://sh.rustup.rs -sSf | sh source "$HOME/.cargo/env"rustc --version

Docker Compose (recommended)

Build and start the full multi-node stack from the repo root:

shell
docker compose build docker compose up

This brings up three services:

ServicePortNotes
Mempool3003HTTP API
Storage3001Read / history
MinerStarts after mempool & storage

Node configuration is read from ./.docker/conf/node_settings.toml (mounted to /etc/node_settings.toml). Point at a different file with the NODE_SETTINGS override:

shell
NODE_SETTINGS=/absolute/path/to/node_settings.toml docker compose up

On Apple Silicon, select the ARM platform (default is linux/amd64):

shell
FLEET_COMPOSE_PLATFORM=linux/arm64 docker compose up

Rebuild a single service, or tear the stack down and remove volumes:

shell
docker compose build mempool-node docker compose down -v

Build from source

shell
cargo build --release cargo test

Or build just the container image (distroless cc-debian13, runs as nonroot; binary at /lineage/lineage):

shell
docker build -t fleet-node:local --platform linux/amd64 .
ContributingBase work on an updated main and open PRs against it, following Conventional Commits (feat, fix, docs, chore, refactor, test, ci, perf; mark breaking changes with a ! suffix). Full details in the fleet README.