Skip to main content

REST API Quickstart

This is the fastest way to poke at Clocktower from any stack that speaks HTTP. You get reads and prepared writes without an MCP client or on-chain SDK — just curl, fetch, or whatever HTTP client you already use.

The REST API exposes the same capabilities as MCP over standard HTTP. Access is controlled by free rate limits and optional developer API keys (ctk_…). Start with the catalog and a subscription search; you will have real protocol data in under a minute.

Base URL

https://api.clocktower.finance

On this host, paths omit the /api prefix (e.g. GET /catalog). Legacy *.workers.dev URLs keep /api.

Protocol routes accept optional ?chainId= (decimal or CAIP-2, e.g. 8453 or eip155:8453). Omitted uses Base (8453). Check GET /catalogchains[] for which chains are live. MCP tools take optional chainId (default Base) — see MCP chain selection. See REST chain selection.

Read protocol state

curl -s https://api.clocktower.finance/catalog | jq .
curl -s https://api.clocktower.finance/protocol/state | jq .
curl -s "https://api.clocktower.finance/protocol/state?chainId=8453" | jq .

With a developer key (higher limits; check X-Clocktower-Lane: developer):

curl -s https://api.clocktower.finance/catalog \
-H "Authorization: Bearer <YOUR_API_KEY>" | jq .

Search subscriptions

curl -s "https://api.clocktower.finance/subscriptions?first=10" | jq .

Free tier: first max 10, no includeDetails. Developer: first max 25, includeDetails allowed.

Create a subscription

amount is a human-readable token string (e.g. "10"), not protocol wei.

frequency is 0 weekly, 1 monthly, 2 quarterly, 3 yearly.

details.url and details.description may be empty strings.

curl -s -X POST "https://api.clocktower.finance/prepare/create_subscription?chainId=8453" \
-H "Content-Type: application/json" \
-d '{
"from": "0xProviderAddress",
"amount": "10",
"token": "0x...",
"details": { "url": "https://example.com/", "description": "Premium" },
"frequency": 1,
"dueDay": 15
}' | jq .

See Create subscription workflow.

Subscribe

When you already know the subscription id, use by-id endpoints (amount, token, and provider are loaded on-chain):

curl -s -X POST "https://api.clocktower.finance/check_subscribe_readiness_by_id?chainId=8453" \
-H "Content-Type: application/json" \
-d '{ "from": "0xYourAddress", "id": "0x..." }' | jq .

curl -s -X POST "https://api.clocktower.finance/prepare/subscribe_by_id?chainId=8453" \
-H "Content-Type: application/json" \
-d '{ "from": "0xYourAddress", "id": "0x..." }' | jq .

Optional: "readinessOnly": true on prepare for preflight without unsigned transactions. Object-based prepare/subscribe still works when you already hold a full subscription object.

Sign unsignedTransactions in your wallet, broadcast to the chain in unsignedTransactions[].chainId, then poll status (pass the same ?chainId=):

curl -s -X POST "https://api.clocktower.finance/transactions/status?chainId=8453" \
-H "Content-Type: application/json" \
-d '{ "txHash": "0x..." }' | jq .

Prepare/readiness is rate-limited (free: 2/min · 20/day; developer: 5/min · 100/day).

Developer API key (optional)

Obtain a free ctk_… key from developers.clocktower.finance. Send:

Authorization: Bearer <YOUR_API_KEY>

See Authentication, Rate limits, and the Terms of Use.

CLI helper

The clocktower-agent repo provides a Node CLI:

npm start rest get /catalog
npm start rest get /protocol/state
npm start rest post /prepare/subscribe_by_id --body '{"from":"0x...","id":"0x..."}'