API

The Simple Page Node exposes a small HTTP API for staging content, serving CARs and raw blocks, reading history, and syncing off-chain drafts.

The easiest way to inspect the live schema is to run a node and open /docs or /openapi.json.

Base URL

Clients discover public node endpoints from the dservice ENS text record on new.simplepage.eth.

Examples below use:

https://your-node.example

For local development, the default node API is usually:

http://localhost:3000

Authentication Model

Simple Page uses domain-based authorization instead of API keys.

Page uploads and ref uploads require the ENS name to have an active Simple Page subscription. Ref uploads also require a signed SIWE capability from the ENS owner authorizing the agent key that signs the ref.

Capability uploads are verified against ENS ownership. The browser Agents page is the normal way to create them.

Content Types

Type Used For
application/vnd.ipld.car CAR files for page roots, refs, history, and staged content.
application/vnd.ipld.raw Raw IPFS block data.
application/json API responses and errors.
multipart/form-data Uploading CAR files as a file field.

Page Operations

GET /page?cid=<cid>

Returns a lightweight CAR for a page root CID.

curl "https://your-node.example/page?cid=bafy..."

Responses:

Status Meaning
200 CAR file.
400 Missing cid.
404 Page or block data not found by this node.

POST /page?domain=<ens-name>

Stages a page CAR for an ENS name. The upload is accepted only while the domain has an active Simple Page subscription.

curl -X POST \
  -F "file=@page.car" \
  "https://your-node.example/page?domain=example.eth"

Response:

{ "cid": "bafy..." }

Responses:

Status Meaning
200 CAR staged and root CID returned.
400 Missing domain, missing file, or invalid CAR root.
401 Subscription missing or expired.
413 Upload exceeds 500 MB.
500 Server error.

Staged content is temporary until the ENS contenthash is updated to the returned CID. The default staging window is one hour.

File Operations

GET /file?cid=<cid>

Returns a raw IPFS block by CID.

curl "https://your-node.example/file?cid=bafy..."

The node serves blocks it has locally. This endpoint is intentionally not a general public IPFS gateway.

Responses:

Status Meaning
200 Raw block bytes.
400 Missing cid.
404 Block not available locally.

History Operations

GET /history?domain=<ens-name>

Returns a CAR containing indexed history entries for a domain.

curl "https://your-node.example/history?domain=example.eth"

The frontend History page uses this endpoint to render the timeline and restore older versions.

Responses:

Status Meaning
200 History CAR.
400 Missing domain.
500 History index error.

Ref Operations

Refs are signed off-chain draft revisions. They let CLI agents submit content for review without holding the ENS owner key.

GET /refs/:ensName

Lists signed refs for an ENS name.

curl "https://your-node.example/refs/example.eth"

Response:

{ "refs": [] }

Each ref includes the ref name, sequence number, content CID, signer did:key, SIWE capability data, owner address, issue time, optional agent name, and a latest flag.

POST /refs/:ensName

Stores a signed ref revision as a CAR upload.

curl -X POST \
  -F "file=@ref.car" \
  "https://your-node.example/refs/example.eth"

Responses:

Status Meaning
200 Ref stored.
400 Invalid ref payload or malformed upload.
401 Invalid signature, missing capability, owner mismatch, or inactive subscription.
413 Upload exceeds 500 MB.

Capability Operations

Capabilities are signed SIWE messages that authorize an agent did:key to submit refs for an ENS name until an expiry time.

GET /capabilities/:ensName

Lists active stored capabilities for a domain.

curl "https://your-node.example/capabilities/example.eth"

Response:

{ "capabilities": [] }

POST /capabilities/:ensName

Stores a signed capability.

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"key":"did:key:...","siweMessage":"...","siweSignature":"0x..."}' \
  "https://your-node.example/capabilities/example.eth"

Responses:

Status Meaning
200 Capability stored.
400 Invalid request body.
401 SIWE, owner, or did:key validation failed.
503 Capability store unavailable.

System Operations

GET /info

Returns the node API version.

curl "https://your-node.example/info"

Response:

{ "version": "1.6.0" }

GET /docs

Serves Swagger UI for the generated API schema.

GET /openapi.json

Serves the OpenAPI schema as JSON.

Limits And CORS

  • Maximum upload size is 500 MB.
  • Page and ref uploads are rate-limited by the node.
  • Default staged content expiry is one hour.
  • CORS allows localhost and ENS-style origins ending in .eth or .wei.
  • CID subdomain IPFS origins are blocked for upload-style requests.