APILink to this section
TL;DRLink to this section
GET https://api.squeekchain.com/v1/…serves Squeekchain's public data as JSON: no key, no wallet, nine read-only endpoints.- Call it from a server, script or agent; browser calls from other websites are refused.
- A response can say
"status": "unavailable"with HTTP 200; that is a valid answer, not an empty result or a zero balance. - Use the API to display and explore. Read the contracts before preparing any transaction.
In active development
The Squeekchain API is in active development and is likely to change. Endpoints, fields and limits described here may change before a mainnet release. Validate responses against the published schemas and handle unknown fields.
Base URL and accessLink to this section
https://api.squeekchain.com
Every endpoint is a read-only GET under /v1. There is no API key and no request body. The API serves the Sepolia deployment listed under Deployments.
Call it from a server, script or agent. Browsers can call it only from Squeekchain's own website; a request from any other site gets 403 cors_origin_not_allowed.
For monitoring, GET /healthz answers 200 while the API runs, and GET /readyz answers 200 only while its database is reachable.
ConventionsLink to this section
These rules apply to every endpoint.
Numbers and unitsLink to this section
Large numbers (IDs, amounts, block numbers and work) are decimal strings. Parse them as BigInt or your language's big-integer type, never as floating point. Small values such as levels and speeds are plain JSON integers.
Field names carry their unit, as listed below.
Field names and units
| Field | Meaning |
|---|---|
…BaseUnits, rewardPerBlock, supplyCap |
SQK with 18 decimals: 1000000000000000000 is 1 SQK |
weight, activeWeight, targetWeight, totalWeight, eligibleWeight |
Power. activeWeight earns now; targetWeight applies once a pending change activates |
blockHeight, completedBlockHeight, closedThroughBlock, nextMergeBlock |
Squeek block numbers, not Ethereum blocks |
blockProgress, cumulativeBlockUnits |
Block units: 1,000,000,000 make one Squeek block |
workPerThousandBlocks |
Difficulty: work units needed for 1,000 Squeek blocks; see SqueekCore |
cumulativeWork, workUnits, cumulativeWorkUnits |
Wheel work units |
…Round, roundId |
600-second rounds counted from the genesis timestamp |
ethereumBlockNumber, blockNumber, chain.…ThroughBlock |
Ethereum block numbers |
…At, blockTimestamp |
ISO 8601 times in UTC; on /v1/core, blockTimestamp and genesisTimestamp are Unix seconds |
date, utcDate |
YYYY-MM-DD |
…Bps |
Basis points, 0–10,000 |
…Milli |
Thousandths: 12500 is 12.5 |
rpmMilli, speedMmPerSecond, distanceMm |
Thousandths of a revolution per minute, millimetres per second, millimetres |
Chain dataLink to this section
Everything read from Ethereum is 12 blocks behind the chain tip, so it is safe from short reorganizations. The chain object says which block a response was read at: compare safeThroughBlock, not generatedAt, to tell whether the chain has moved.
release and identities name the deployment and the contract addresses the data came from. Check them against Deployments before relying on a response.
AvailabilityLink to this section
Most responses have a status. When it is "unavailable", the response has a reason and no data, even though the HTTP status is 200. Show it as unknown, never as zero or empty.
CachingLink to this section
Responses come from a snapshot shared by all callers, so polling faster than it refreshes returns the same data. Three endpoints support conditional requests: send their ETag back in If-None-Match exactly as received, and an unchanged response comes back as 304 with no body.
| Endpoint | Refreshes | Conditional requests |
|---|---|---|
| Pipeline status | Every second, and on each new measurement | Yes |
| Measurement statistics | When the data changes | Yes |
| Settlement history | Every 5 seconds, and at each range boundary | Yes |
| SqueekCore state, Issuance state | Every 5 seconds | No |
| Event feed, owner and metadata endpoints | Every request | No |
PaginationLink to this section
List endpoints return up to limit items (1–100) and a nextCursor. For the next page, repeat the request with cursor set to that value; nextCursor is null on the last page. Treat cursors as opaque. A cursor the API can't use gets 400 invalid_cursor, and an owner cursor invalidated by a chain reorganization gets 409 cursor_invalidated; either way, start again from the first page.
Rate limitsLink to this section
Each IP address has a request budget per class of endpoint. Over budget, the API answers 429 with a Retry-After header: wait that many seconds before retrying.
| Class | Endpoints | Rate | Burst |
|---|---|---|---|
publicFast |
Pipeline status, SqueekCore state, Issuance state | 30 per second | 60 |
publicHeavy |
Measurement statistics, Settlement history, Event feed, Owner's Squeeks, Owner activity | 5 per second | 20 |
metadata |
Squeek metadata | 20 per second | 40 |
HeadersLink to this section
| Header | Use |
|---|---|
X-Request-Id |
On every response. Send your own (8–128 letters, digits, ., _, : or -) to trace a request, and quote it when reporting a problem |
ETag |
On cacheable responses; send it back as If-None-Match. See Caching |
Retry-After |
On 429 and 503 responses: seconds to wait before retrying |
X-Squeek-Settlement-Source |
On Settlement history: live, durable-cache or unavailable |
Versioning and schemasLink to this section
/v1 versions the whole API. New endpoints, fields and optional parameters can appear within /v1, so ignore fields you don't use; removing or changing a field ships as /v2. Every response also has a schemaVersion.
Each endpoint links its complete JSON Schema (draft 2020-12). Enable the date, date-time and uuid formats; the uint…-decimal formats are unsigned decimal strings. The examples on this page are real responses with arrays shortened.
ErrorsLink to this section
Errors return an HTTP status and a body of the form {"error": "<code>"}. The codes below can come from any endpoint; endpoints list their own extra codes.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | invalid_query |
A parameter is missing, malformed, repeated or unknown | Fix the request |
| 403 | cors_origin_not_allowed |
A browser on another website called the API | Call it from your server |
| 404 | not_found |
No such endpoint | Check the path |
| 429 | rate_limited |
Over the rate limit | Wait Retry-After seconds |
| 503 | database_busy, indexer_busy, database_unavailable |
The API is overloaded or a dependency is down | Wait Retry-After seconds, then retry with backoff |
| 504 | request_timeout |
The request took too long | Retry with backoff |
| 500 | internal_error |
Unexpected server failure | Retry a few times; report the X-Request-Id |
A response that doesn't parse or doesn't match its schema is an error, not empty data.
API or contracts?Link to this section
The API is an indexed, confirmation-delayed view for display, history and exploration. Anything that leads to a transaction reads the contracts, at a block you choose.
| You want to | Use |
|---|---|
| Show whether the wheel is running and how far the next block is | /v1/status |
| Chart wheel activity, records and settlement performance | /v1/measurement/stats |
| Show settled work, block height and difficulty | /v1/core; for an exact value at a block, SqueekCore state() |
| List settlements and SQK issued per period | /v1/settlements; to rebuild history yourself, Index events |
| Show a feed of what happened | /v1/events |
| Show an owner's Squeeks and SQK | /v1/owners/{address}/squeeks |
| Prepare a claim or merge | The contracts: position, claimable and Build owner actions. Never take token IDs, amounts or eligibility from the API into a transaction |
| Show a Squeek's image and traits | /v1/squeeks/{tokenId}/metadata; onchain, tokenURI |
Measurement and validationLink to this section
What the WHEELY9000 measured, how the Oracle validated it, and how close the next Squeek block is.
Pipeline status · GET /v1/statusLink to this section
The live state of the whole pipeline in one read: the latest accepted measurement, the block builder's projection, Oracle validation, the settlement queue and the device signer. Poll it to show whether the wheel is turning and how far the next block is.
The endpoint takes no parameters; any query parameter returns 400 invalid_query.
Example request
curl -i https://api.squeekchain.com/v1/status
Response
Example response
{
"schemaVersion": 1,
"installationId": "hamster-sepolia-core3-mining6-001",
"revision": "YTgBydeEb9_TxJt9Z-Ke6LnZ4mAmm1TEmpUzWFB4Ys0",
"generatedAt": "2026-10-15T00:56:11.129Z",
"measurement": {
"freshness": "online",
"observedAt": "2026-10-15T00:56:09.341Z",
"receivedAt": "2026-10-15T00:56:09.626Z",
"staleAfterSeconds": 120,
"counterEpoch": "fe146d83-582f-44cc-ae4f-372fa5e83920",
"cumulativeWorkUnits": "29848",
"provenance": "hardware",
"coreStatus": "IDLE",
"rpmMilli": 73330,
"speedMmPerSecond": 1073,
"distanceMm": 5727194
},
"builder": {
"status": "available",
"anchor": {
"cumulativeWork": "29212",
"cumulativeBlockUnits": "2614966878647",
"blockHeight": "2614",
"blockProgress": "966878647",
"workPerThousandBlocks": "11676",
"settledThroughRound": "295",
"confirmedAt": "2026-10-15T00:41:12.000Z",
"transactionHash": "0xe354794ba80cde1d2f75f0bcead87f652c2541fd5622ee46ef47b6f2ee78b274"
},
"queued": {"closedRoundCount": "1", "closedWorkUnits": "257", "openRoundWorkUnits": "379"},
"projected": {
"cumulativeWork": "29848",
"cumulativeBlockUnits": "2669934363044",
"blockHeight": "2669",
"blockProgress": "934363044",
"workPerThousandBlocks": "11432",
"firstCompletedBlock": "2615",
"lastCompletedBlock": "2669",
"completedBlockCount": "55",
"lifecycle": "optimistic"
}
},
"oracle": {
"state": "accepted",
"reason": null,
"latestAcceptedAt": "2026-10-15T00:56:09.626Z",
"latestClosure": {
"firstRound": "296",
"lastRound": "296",
"roundCount": "1",
"acceptedAt": "2026-10-15T00:50:00.960Z"
}
},
"settlementQueue": {
"status": "available",
"state": "ready",
"settlementEnabled": true,
"reporterEnvironmentEnabled": true,
"buffered": {
"firstRound": "296",
"lastRound": "296",
"roundCount": "1",
"activeRoundCount": "1",
"workUnits": "257"
},
"projected": {
"cumulativeWork": "29469",
"cumulativeBlockUnits": "2636977841305",
"blockHeight": "2636",
"blockProgress": "977841305",
"workPerThousandBlocks": "11500",
"firstCompletedBlock": "2615",
"lastCompletedBlock": "2636",
"completedBlockCount": "22",
"lifecycle": "optimistic"
},
"incidentOpen": false,
"blockedReason": null,
"lastRun": {
"startedAt": "2026-10-15T00:50:50.210Z",
"finishedAt": "2026-10-15T00:50:50.707Z",
"result": "failed"
},
"latestSubmission": {
"submissionId": "eecbd361-33aa-43aa-984c-a38b4cf07cd6",
"lifecycle": "confirmed",
"previousSettledThroughRound": "294",
"settledThroughRound": "295",
"roundCount": "1",
"activeRoundCount": "1",
"expected": {
"cumulativeWork": "29212",
"cumulativeBlockUnits": "2614966878647",
"blockHeight": "2614",
"blockProgress": "966878647",
"workPerThousandBlocks": "11676",
"firstCompletedBlock": "2560",
"lastCompletedBlock": "2614",
"completedBlockCount": "55"
},
"transactionHash": "0xe354794ba80cde1d2f75f0bcead87f652c2541fd5622ee46ef47b6f2ee78b274",
"createdAt": "2026-10-15T00:40:51.915Z",
"submittedAt": "2026-10-15T00:40:51.915Z",
"confirmedAt": "2026-10-15T00:45:32.542Z",
"terminalAt": "2026-10-15T00:45:32.542Z",
"changedAt": "2026-10-15T00:45:32.542Z",
"outcomeCode": null
}
},
"signer": {
"kind": "trust-m",
"algorithm": "ecdsa-p256-sha256",
"keySlot": "0xE0F2",
"enrolledAt": "2026-10-12T23:51:14.066Z",
"lastVerifiedAt": "2026-10-15T00:56:09.626Z",
"lastSignature": "tJG5ZDKdvX3cHC5rFeXu0rVj1aY2IXsJ/Dj1jMrtR5tI1wZiJUGxi7qMyLtl5lLbUphBGXBTA0+vJHhQzjPafA=="
},
"modules": [
{
"instanceId": "wheel",
"moduleType": "wheel.counter",
"driverId": "usb-rp2040-a3144e-lm393",
"moduleVersion": "0.2.1",
"schemaVersion": 1,
"state": "ready",
"observedAt": "2026-10-15T00:56:09.341611Z",
"provenance": "hardware",
"health": {"checkedAt": "2026-10-15T00:56:09.341611Z"},
"data": {}
}
]
}
| Field | Type | Description |
|---|---|---|
revision |
string |
Opaque snapshot revision; the ETag is derived from it and from modules |
measurement |
object or null |
Latest accepted device reading; null before the first |
measurement.freshness |
string |
online, or stale once more than staleAfterSeconds (120) have passed since receivedAt |
measurement.observedAt |
string |
When the device took the reading |
measurement.receivedAt |
string |
When the API accepted it |
measurement.counterEpoch |
string |
UUID of the device's counter epoch; cumulativeWorkUnits counts from its start |
measurement.cumulativeWorkUnits |
string |
Work units counted in this counter epoch |
measurement.provenance |
string |
hardware, simulated, replay or derived |
measurement.coreStatus |
string |
Device state: IDLE, ACTIVE or COUNTER_FAULT |
measurement.rpmMilli |
integer |
Wheel speed in thousandths of a revolution per minute |
measurement.speedMmPerSecond |
integer |
Running speed in millimetres per second |
measurement.distanceMm |
integer |
Distance the device reports for its current day, in millimetres |
builder.status |
string |
available, or unavailable with builder.reason |
builder.anchor |
object |
The settled frontier on SqueekCore: settledThroughRound, cumulativeWork, blockHeight, blockProgress, workPerThousandBlocks, cumulativeBlockUnits, and the confirming transactionHash and confirmedAt |
builder.queued |
object |
Work not yet settled: closedRoundCount, closedWorkUnits and openRoundWorkUnits |
builder.projected |
object |
lifecycle: "optimistic": the frontier if all queued work settles, with firstCompletedBlock, lastCompletedBlock and completedBlockCount |
oracle.state |
string |
accepted, stale, blocked or unavailable, with oracle.reason |
oracle.latestClosure |
object or null |
The latest closed rounds the Oracle accepted: firstRound, lastRound, roundCount, acceptedAt |
settlementQueue.status |
string |
available, or unavailable with settlementQueue.reason |
settlementQueue.state |
string |
disabled, empty, ready, preparing, submitted, retrying, blocked or stale |
settlementQueue.buffered |
object |
Closed rounds waiting to settle: firstRound, lastRound, roundCount, activeRoundCount, workUnits |
settlementQueue.projected |
object |
The frontier once the buffered rounds settle; same fields as builder.projected |
settlementQueue.latestSubmission |
object or null |
The latest settlement transaction: lifecycle (preparing, submitted, retrying, confirmed, reverted, superseded), round range, expected result, transactionHash, timestamps and outcomeCode |
signer |
object or null |
The device's signing credential: kind (trust-m, software-ecdsa or ed25519), algorithm, keySlot, enrolledAt, lastVerifiedAt. May be absent |
modules[] |
object |
The installation's sensor modules, as last reported: instanceId, moduleType, driverId, moduleVersion, observedAt and provenance |
modules[].state |
string |
disabled, starting, ready, degraded, faulted or stopped |
modules[].health |
object |
checkedAt, plus code and message when the module reports a problem |
Projected values are optimistic. A projected completed block is not settled on Ethereum and has not issued SQK; settlement happens when the Reporter's batch confirms, and issuance when SqueekMining checkpoints it.
Freshness
A shared snapshot is recomputed at most once a second and right after each accepted measurement. Builder unavailable reasons: no_measurement, counter_fault, counter_epoch_unapproved, round_projection_gap, oracle_head_unavailable, round_ineligible. Queue unavailable reasons: oracle_head_unavailable, round_projection_gap, round_ineligible. A stale measurement alone doesn't make the builder unavailable.
Measurement statistics · GET /v1/measurement/statsLink to this section
Aggregates over the last 7 or 30 days: lifetime totals, daily and half-hourly activity, records, block production, round activity and settlement performance. Use it for charts and summaries; it's too heavy to poll.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
range |
string |
Yes | 7d or 30d. Exactly one range; no other parameter is accepted |
Example request
curl -i "https://api.squeekchain.com/v1/measurement/stats?range=7d"
Response
Example response
{
"installationId": "hamster-sepolia-core3-mining6-001",
"revision": "NVgZYvWK_8zjMiI9Tyhpt1wIySrwP2RSZILgqbhNtWQ",
"generatedAt": "2026-10-15T00:56:10.810Z",
"range": "7d",
"timezone": "UTC",
"window": {
"startAt": "2026-10-08T12:00:00.000Z",
"endAt": "2026-10-15T00:56:10.810Z",
"dayCount": 7,
"bucketSeconds": 1800,
"roundSeconds": 600
},
"activity": {
"provenance": "accepted_rounds",
"coverage": {"expectedRoundCount": 941, "observedRoundCount": 296, "coverageBps": 3145, "complete": false},
"summary": {
"observedWorkUnits": "29469",
"observedDistanceMm": "29757176",
"activeDayCount": 3,
"inactiveDayCount": 0,
"averageWorkPerActiveDayMilli": "9823000",
"medianWorkPerActiveDay": "8356",
"averageDistancePerActiveDayMm": "9919058",
"mostActiveDate": "2026-10-13",
"mostActiveDateWorkUnits": "14969",
"peakWindowStartMinuteUtc": 1410
},
"days": [
{
"date": "2026-10-14",
"coverage": {"expectedRoundCount": 77, "observedRoundCount": 77, "coverageBps": 10000},
"observedWorkUnits": "6144",
"distanceMm": "5727194",
"buckets": [
{
"startMinuteUtc": 0,
"coverage": "complete",
"observedRoundCount": 3,
"workUnits": "1488"
},
{"startMinuteUtc": 30, "coverage": "partial", "observedRoundCount": 2, "workUnits": "897"}
]
}
],
"typicalDay": [
{
"startMinuteUtc": 0,
"totalWorkUnits": "4370",
"observedDayCount": 3,
"meanWorkMilli": "1456666"
},
{
"startMinuteUtc": 30,
"totalWorkUnits": "2944",
"observedDayCount": 2,
"meanWorkMilli": "1472000"
}
]
},
"records": {
"mostWorkHalfHour": {"value": "1706", "occurredAt": "2026-10-13T23:30:00.000Z", "coverage": "complete"},
"mostWorkUtcDay": {"value": "14969", "occurredAt": "2026-10-13T12:00:00.000Z", "coverage": "complete"},
"maximumDailyDistanceMm": {"value": "13142782", "occurredAt": "2026-10-13T12:00:00.000Z", "coverage": "complete"},
"peakObservedRpmMilli": {"value": "104281", "occurredAt": "2026-10-14T22:44:45.996Z", "coverage": "partial"},
"peakObservedSpeedMmPerSecond": {"value": "1526", "occurredAt": "2026-10-14T22:44:45.996Z", "coverage": "partial"},
"longestActiveWindowMinutes": {"value": "250", "occurredAt": "2026-10-13T22:00:00.000Z", "coverage": "complete"},
"longestActiveDayStreak": {"value": "3", "occurredAt": "2026-10-12T12:00:00.000Z", "coverage": "partial"}
},
"blocks": {"status": "unavailable", "reason": "completion_boundaries_unavailable"},
"rounds": {
"observedCount": 296,
"activeCount": 64,
"zeroWorkCount": 232,
"missingCount": 645,
"activeRateBps": 2162,
"averageActiveWorkMilli": "460453",
"medianActiveWork": "479",
"p90ActiveWork": "650",
"mostActiveWork": "686"
},
"oracle": {"status": "unavailable", "reason": "projection_not_initialized"},
"schemaVersion": 1,
"lifetime": {
"acceptedWorkUnits": "29469",
"observedDistanceMm": "29757176",
"activeDayCount": 3,
"settledBlockCount": "2614",
"settlementCount": "279",
"coverageBps": 10000,
"firstObservedAt": "2026-10-12T23:30:00.000Z",
"settledWorkUnits": "29212"
}
}
| Field | Type | Description |
|---|---|---|
revision |
string |
Content revision; the ETag |
window |
object |
startAt, endAt, dayCount, bucketSeconds (1800) and roundSeconds (600) |
lifetime |
object |
Totals since the first observation: acceptedWorkUnits, observedDistanceMm, activeDayCount, settledBlockCount, settlementCount, settledWorkUnits, coverageBps, firstObservedAt |
activity.coverage |
object |
Expected and observed rounds in the window, coverageBps and complete |
activity.summary |
object |
Observed work and distance, active and inactive days, averages, median, the most active date and peakWindowStartMinuteUtc |
activity.days[] |
object |
One entry per day: date, coverage, observedWorkUnits, distanceMm and 48 half-hour buckets |
activity.days[].buckets[] |
object |
startMinuteUtc, coverage (complete, partial, missing, future), observedRoundCount, workUnits |
activity.typicalDay[] |
object |
48 half-hour slots averaged over the window: startMinuteUtc, totalWorkUnits, observedDayCount, meanWorkMilli |
records |
object |
mostWorkHalfHour, mostWorkUtcDay, maximumDailyDistanceMm, peakObservedRpmMilli, peakObservedSpeedMmPerSecond, longestActiveWindowMinutes, longestActiveDayStreak: each null or a value, occurredAt and coverage |
blocks |
object |
Available: blocks completed in the range and all time, per-day figures and completion times. Unavailable reasons: completion_boundaries_unavailable, insufficient_history |
rounds |
object |
Observed, active, zero-work and missing rounds, activeRateBps, and active-round work statistics |
oracle |
object |
Available: settlement submissions, confirmations, reverts and timings. Unavailable reasons: projection_not_initialized, insufficient_history |
Days run from 12:00 UTC to 12:00 UTC and are named by the date of their starting noon, matching the distance the device reports per day.
Freshness
Computed from accepted rounds and confirmed settlements. Send the ETag back in If-None-Match to get 304 while nothing has changed.
Errors
| Status | Code | Cause |
|---|---|---|
| 503 | public_stats_rebuilding |
The statistics are being rebuilt; wait Retry-After and retry. Don't show an empty history |
Settlement and eventsLink to this section
What SqueekCore has settled on Ethereum, the history of settlements and issuance, and the event feed.
SqueekCore state · GET /v1/coreLink to this section
SqueekCore's identity, configuration and settled state at the safe block, with its newest events. Use it to show settled work, block height and difficulty, and to check the API reads the deployment you expect.
The endpoint takes no parameters; any query parameter returns 400 invalid_query.
Example request
curl -i https://api.squeekchain.com/v1/core
Response
Example response
{
"schemaVersion": 1,
"installationId": "hamster-sepolia-core3-mining6-001",
"status": "available",
"chain": {
"target": "sepolia",
"chainId": "11155111",
"confirmations": "12",
"deploymentBlock": "11902282",
"indexedThroughBlock": "11916986",
"safeThroughBlock": "11916975"
},
"identities": {
"core": "0x74665daeca35a2303e767e76a2ff1fb6f93e119f",
"proxyAdmin": "0x05a9af6c3f6780dd58168f2e145cdd0d64564a5e",
"proxyAdminOwner": "0x6b35ab6e96ef292e4fdd3f15a4e812f3ca291844",
"operatorTimelock": "0x6b35ab6e96ef292e4fdd3f15a4e812f3ca291844",
"operatorProposer": "0x83a8d3e5ed02e5201a996c3f03e017b6a6c19d31",
"proxyImplementation": "0x0a71c86ab63a77675002a389fdf4d096a07b11e2",
"proxyAdminSlot": "0x05a9af6c3f6780dd58168f2e145cdd0d64564a5e"
},
"configuration": {
"streamId": "0xa0186b1a24b217f12f56c8574b492e286d00cd94bb5546cba45b048b19c60e44",
"genesisTimestamp": "1791847800",
"roundDuration": "600",
"maxWorkPerRound": "10000",
"maxRoundsPerBatch": "16",
"guardian": "0x0e1b21ed2fc5fc48e221d3e863f09589cb490e73",
"reporter": "0xa663b5c05eafa3e90bfbd3f7decdaaa3d41f5a75",
"initialWorkPerThousandBlocks": "10875",
"targetBlocksPerActiveRound": "40",
"difficultySmoothingRounds": "30",
"blockUnitsPerBlock": "1000000000"
},
"core": {
"cumulativeWork": "29212",
"cumulativeBlockUnits": "2614966878647",
"blockHeight": "2614",
"blockProgress": "966878647",
"workPerThousandBlocks": "11676",
"settledThroughRound": "295",
"authorizationNonce": "280",
"paused": false
},
"implementation": {
"codeAddress": "0x0a71c86ab63a77675002a389fdf4d096a07b11e2",
"codeVersion": "3",
"storageLayoutDigest": "0x9a9c008e029460808209571703fbf2679785874e0e6d3232f16a864d12abcb20",
"runtimeHash": "0xe8a5a5aa913141ddd8951cf9fcc1375044b541773e5b0bf8ee04a5c7ac2d194d"
},
"governance": {
"operationId": "0x0000000000000000000000000000000000000000000000000000000000000000",
"operationKind": "None",
"operationState": "None"
},
"source": {
"eventName": "BatchSettled",
"blockNumber": "11916912",
"blockHash": "0x894b28afb201a9df4dcc19a7077deab5ad5b24f875e3a83d3acdda9778365be7",
"blockTimestamp": "1792024872",
"transactionHash": "0xe354794ba80cde1d2f75f0bcead87f652c2541fd5622ee46ef47b6f2ee78b274",
"transactionIndex": "117",
"logIndex": "434"
},
"events": [
{
"id": "179202487200000000111551110000000011916912000000000000011750000000000000434",
"contractKind": "core",
"contractAddress": "0x74665daeca35a2303e767e76a2ff1fb6f93e119f",
"eventName": "BatchSettled",
"blockNumber": "11916912",
"blockHash": "0x894b28afb201a9df4dcc19a7077deab5ad5b24f875e3a83d3acdda9778365be7",
"blockTimestamp": "1792024872",
"transactionHash": "0xe354794ba80cde1d2f75f0bcead87f652c2541fd5622ee46ef47b6f2ee78b274",
"transactionIndex": "117",
"logIndex": "434",
"arguments": [
{
"name": "digest",
"value": "0x1c35b19677c08a83a7622bf1f7cd3849c57f646e702f4f1e146cd45b6856a1d0"
},
{"name": "reporter", "value": "0xa663b5c05eafa3e90bfbd3f7decdaaa3d41f5a75"},
{"name": "settledThroughRound", "value": "295"}
]
},
{
"id": "179202487200000000111551110000000011916912000000000000011750000000000000433",
"contractKind": "core",
"contractAddress": "0x74665daeca35a2303e767e76a2ff1fb6f93e119f",
"eventName": "RoundRecorded",
"blockNumber": "11916912",
"blockHash": "0x894b28afb201a9df4dcc19a7077deab5ad5b24f875e3a83d3acdda9778365be7",
"blockTimestamp": "1792024872",
"transactionHash": "0xe354794ba80cde1d2f75f0bcead87f652c2541fd5622ee46ef47b6f2ee78b274",
"transactionIndex": "117",
"logIndex": "433",
"arguments": [
{"name": "roundId", "value": "295"},
{"name": "work", "value": "640"},
{"name": "cumulativeWork", "value": "29212"}
]
}
]
}
| Field | Type | Description |
|---|---|---|
status |
string |
available, or unavailable with a reason |
identities.core |
string |
The SqueekCore proxy address |
identities.proxyImplementation |
string |
The implementation the proxy runs |
identities.proxyAdmin, identities.proxyAdminOwner |
string |
The ProxyAdmin and its owner, the governance timelock |
identities.operatorTimelock, identities.operatorProposer |
string |
The governance timelock and the account that proposes its operations |
configuration |
object |
Launch configuration: streamId, genesisTimestamp, roundDuration, maxWorkPerRound, maxRoundsPerBatch, guardian, reporter, initialWorkPerThousandBlocks, targetBlocksPerActiveRound, difficultySmoothingRounds, blockUnitsPerBlock |
core.settledThroughRound |
string |
The last settled round |
core.cumulativeWork |
string |
All settled work units |
core.blockHeight |
string |
Completed Squeek blocks |
core.blockProgress |
string |
Block units into the next block, out of 1,000,000,000 |
core.workPerThousandBlocks |
string |
Current difficulty |
core.cumulativeBlockUnits |
string |
All block units earned |
core.paused |
boolean |
Whether the Guardian has paused settlement |
implementation |
object |
The running code: codeAddress, codeVersion, storageLayoutDigest, runtimeHash |
governance |
object |
The latest timelock operation on the proxy: operationId, operationKind, operationState |
source |
object |
The event the state was last read from: eventName, block, transaction and log position |
events[] |
object |
Up to 25 newest events from SqueekCore, its proxy, ProxyAdmin and timelock: id, contractKind, contractAddress, eventName, block, transaction and log position, and arguments as name/value pairs |
Compare identities and implementation with Deployments; stop if they differ.
Freshness
Read at chain.safeThroughBlock and shared for up to 5 seconds. Unavailable reasons: indexer_disabled, not_yet_safe (the indexer hasn't reached 12 confirmations past the deployment), indexer_unavailable, indexer_mismatch (the indexer reports a different deployment).
Settlement history · GET /v1/settlementsLink to this section
Settlement totals and the most recent settlements for a time range, with SQK issuance by round. Use it for settlement and issuance charts.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
range |
string |
No | now (default), 24h, 7d or 30d. At most one range; no other parameter is accepted |
Example request
curl -i "https://api.squeekchain.com/v1/settlements?range=24h"
Response
Example response, range=24h
{
"schemaVersion": 1,
"installationId": "hamster-sepolia-core3-mining6-001",
"status": "available",
"range": "24h",
"generatedAt": "2026-10-15T00:56:09.168Z",
"chain": {
"target": "sepolia",
"chainId": "11155111",
"confirmations": "12",
"deploymentBlock": "11902282",
"indexedThroughBlock": "11916986",
"safeThroughBlock": "11916975"
},
"window": {
"startAt": "2026-10-14T01:00:00.000Z",
"endAt": "2026-10-15T01:00:00.000Z",
"bucketSeconds": 3600
},
"summary": {
"settlementCount": "136",
"activeRoundCount": "27",
"workAdded": "12429",
"completedBlockCount": "1093",
"archivedSettlementCount": "124"
},
"recentSettlements": [
{
"transactionHash": "0xe354794ba80cde1d2f75f0bcead87f652c2541fd5622ee46ef47b6f2ee78b274",
"previousSettledThroughRound": "294",
"settledThroughRound": "295",
"activeRoundCount": "1",
"workAdded": "640",
"cumulativeWork": "29212",
"cumulativeBlockUnits": "2614966878647",
"firstCompletedBlock": "2560",
"lastCompletedBlock": "2614",
"completedBlockCount": "55",
"blockHeight": "2614",
"ethereumBlockNumber": "11916912",
"blockTimestamp": "2026-10-15T00:41:12.000Z",
"logIndex": "434",
"confirmationStatus": "safe",
"sqkMintedBaseUnits": "308000000000000000000000"
}
],
"buckets": [
{
"startAt": "2026-10-14T01:00:00.000Z",
"endAt": "2026-10-14T02:00:00.000Z",
"settlementCount": "5",
"activeRoundCount": "6",
"workAdded": "2665",
"completedBlockCount": "230",
"sqkMintedBaseUnits": "1394400000000000000000000"
},
{
"startAt": "2026-10-14T02:00:00.000Z",
"endAt": "2026-10-14T03:00:00.000Z",
"settlementCount": "6",
"activeRoundCount": "2",
"workAdded": "1001",
"completedBlockCount": "87",
"sqkMintedBaseUnits": "716800000000000000000000"
}
],
"mining": {
"status": "available",
"economy": {
"releaseId": "squeeks-sepolia-core3-mining6-001",
"mining": "0x3bee588fc20de788bac17d33b41da7346cb27ec4",
"token": "0x6872bfa5ccc3e9e440c6c16e5ffdabb8dba4cc76",
"symbol": "SQK",
"decimals": 18
},
"rewardPerBlock": "5600000000000000000000",
"supplyCap": "2100000000000000000000000000",
"totalMintedBaseUnits": "13624800000000000000000000",
"unmintedCapacityBaseUnits": "2086375200000000000000000000",
"processedThroughRound": "295",
"rangeMintedBaseUnits": "6456800000000000000000000",
"rangeCheckpointCount": "125",
"nextRound": {
"state": "accruing",
"round": "296",
"countedThroughRound": "295",
"startsAt": "2026-10-15T00:40:00.000Z",
"endsAt": "2026-10-15T00:50:00.000Z",
"previousCumulativeBlockUnits": "2614966878647",
"cumulativeBlockUnits": "2614966878647",
"completedBlockCount": "0",
"eligibleWeight": "100000",
"amountBaseUnits": "0"
},
"recentCheckpoints": [
{
"afterRound": "294",
"throughRound": "295",
"completedBlockCount": "55",
"cumulativeWork": "29212",
"cumulativeBlockUnits": "2614966878647",
"eligibleWeight": "100000",
"amountBaseUnits": "308000000000000000000000",
"totalMintedBaseUnits": "13624800000000000000000000",
"transactionHash": "0x73380faf2c7c14f93af8c99f1d42d9f5d0ea32dddc18a606db5c735e550bbb65",
"ethereumBlockNumber": "11916936",
"blockTimestamp": "2026-10-15T00:46:00.000Z",
"logIndex": "758",
"confirmationStatus": "safe"
}
]
},
"previousPeriod": {
"startAt": "2026-10-13T01:00:00.000Z",
"endAt": "2026-10-14T00:56:09.000Z",
"sqkMintedBaseUnits": "6540800000000000000000000"
}
}
Example response, range=now
{
"schemaVersion": 1,
"installationId": "hamster-sepolia-core3-mining6-001",
"status": "available",
"range": "now",
"generatedAt": "2026-10-15T00:56:10.041Z",
"chain": {
"target": "sepolia",
"chainId": "11155111",
"confirmations": "12",
"deploymentBlock": "11902282",
"indexedThroughBlock": "11916986",
"safeThroughBlock": "11916975"
},
"window": null,
"summary": {
"settlementCount": "279",
"activeRoundCount": "63",
"workAdded": "29212",
"completedBlockCount": "2614",
"archivedSettlementCount": "267"
},
"recentSettlements": [
{
"transactionHash": "0xe354794ba80cde1d2f75f0bcead87f652c2541fd5622ee46ef47b6f2ee78b274",
"previousSettledThroughRound": "294",
"settledThroughRound": "295",
"activeRoundCount": "1",
"workAdded": "640",
"cumulativeWork": "29212",
"cumulativeBlockUnits": "2614966878647",
"firstCompletedBlock": "2560",
"lastCompletedBlock": "2614",
"completedBlockCount": "55",
"blockHeight": "2614",
"ethereumBlockNumber": "11916912",
"blockTimestamp": "2026-10-15T00:41:12.000Z",
"logIndex": "434",
"confirmationStatus": "safe",
"sqkMintedBaseUnits": "308000000000000000000000"
}
],
"buckets": [],
"mining": {
"status": "available",
"economy": {
"releaseId": "squeeks-sepolia-core3-mining6-001",
"mining": "0x3bee588fc20de788bac17d33b41da7346cb27ec4",
"token": "0x6872bfa5ccc3e9e440c6c16e5ffdabb8dba4cc76",
"symbol": "SQK",
"decimals": 18
},
"rewardPerBlock": "5600000000000000000000",
"supplyCap": "2100000000000000000000000000",
"totalMintedBaseUnits": "13624800000000000000000000",
"unmintedCapacityBaseUnits": "2086375200000000000000000000",
"processedThroughRound": "295",
"rangeMintedBaseUnits": "13624800000000000000000000",
"rangeCheckpointCount": "263",
"nextRound": {
"state": "accruing",
"round": "296",
"countedThroughRound": "295",
"startsAt": "2026-10-15T00:40:00.000Z",
"endsAt": "2026-10-15T00:50:00.000Z",
"previousCumulativeBlockUnits": "2614966878647",
"cumulativeBlockUnits": "2614966878647",
"completedBlockCount": "0",
"eligibleWeight": "100000",
"amountBaseUnits": "0"
},
"recentCheckpoints": [
{
"afterRound": "294",
"throughRound": "295",
"completedBlockCount": "55",
"cumulativeWork": "29212",
"cumulativeBlockUnits": "2614966878647",
"eligibleWeight": "100000",
"amountBaseUnits": "308000000000000000000000",
"totalMintedBaseUnits": "13624800000000000000000000",
"transactionHash": "0x73380faf2c7c14f93af8c99f1d42d9f5d0ea32dddc18a606db5c735e550bbb65",
"ethereumBlockNumber": "11916936",
"blockTimestamp": "2026-10-15T00:46:00.000Z",
"logIndex": "758",
"confirmationStatus": "safe"
}
]
},
"recentRounds": [
{"roundId": "254", "endAt": "2026-10-14T17:50:00.000Z", "sqkMintedBaseUnits": "0"},
{"roundId": "255", "endAt": "2026-10-14T18:00:00.000Z", "sqkMintedBaseUnits": "0"}
]
}
| Field | Type | Description |
|---|---|---|
range |
string |
The requested range |
window |
object or null |
startAt, endAt and bucketSeconds; null for now |
summary |
object |
settlementCount, activeRoundCount, workAdded, completedBlockCount and archivedSettlementCount for the range |
recentSettlements[] |
object |
Up to 10 newest settlements that completed blocks (within the window, for ranged requests); settlements that completed none are counted in summary and buckets but never listed. Each has its round range, activeRoundCount, workAdded, cumulativeWork, completed blocks, blockHeight, cumulativeBlockUnits, the Ethereum transactionHash, ethereumBlockNumber, blockTimestamp and logIndex, and sqkMintedBaseUnits, the SQK its blocks minted, once mining.processedThroughRound reaches its settledThroughRound |
buckets[] |
object |
Per-period totals: 24 hourly buckets for 24h, 28 six-hour buckets for 7d, 30 daily buckets for 30d, none for now; each with sqkMintedBaseUnits when issuance is available |
mining.status |
string |
available, or unavailable with not_configured or not_yet_safe |
mining.totalMintedBaseUnits, mining.unmintedCapacityBaseUnits |
string |
SQK issued so far and the capacity left under the supply cap |
mining.rangeMintedBaseUnits, mining.rangeCheckpointCount |
string |
SQK issued and checkpoints run in the range |
mining.processedThroughRound |
string |
The last round SqueekMining has funded |
mining.nextRound |
object |
The next round to fund: state (accruing or ready), round, its time span, the blocks it completes, eligibleWeight and amountBaseUnits |
mining.recentCheckpoints[] |
object |
Up to 12 newest checkpoints: round span, blocks completed, eligibleWeight, amountBaseUnits, totalMintedBaseUnits, transaction and block |
recentRounds[] |
object |
now only: up to 42 recent rounds with roundId, endAt and sqkMintedBaseUnits |
previousPeriod |
object |
Ranged only, when available: SQK issued in the period before the window |
Settlements and issuance are separate steps. A settlement records work on SqueekCore; SQK is issued later, per round, when SqueekMining checkpoints. Never attribute SQK to a single settlement.
Freshness
Read at the safe block and shared for up to 5 seconds. The 24h window ends at the next full hour; the 7d and 30d windows end at the next 12:00 UTC, so buckets shift on those boundaries even without new events. The response header X-Squeek-Settlement-Source is live, durable-cache (the indexer is behind or unavailable and the last good snapshot is served) or unavailable. Unavailable reasons: indexer_disabled, not_yet_safe, indexer_unavailable, indexer_mismatch.
Event feed · GET /v1/eventsLink to this section
The newest-first feed of what happened: settlements and checkpoints, mints, merges and claims, and wheel milestones. Use it for an activity feed.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
category |
string |
No | all (default), protocol, players or measurement |
limit |
integer |
No | 1–100; default 40 |
cursor |
string |
No | nextCursor from the previous page, with the same category |
Example request
curl -i "https://api.squeekchain.com/v1/events?category=all&limit=20"
Response
Example response
{
"schemaVersion": 1,
"installationId": "hamster-sepolia-core3-mining6-001",
"status": "available",
"generatedAt": "2026-10-15T00:57:41.699Z",
"catalogVersion": "public-activity-v2",
"chain": {
"target": "sepolia",
"chainId": "11155111",
"confirmations": "12",
"deploymentBlock": "11902282",
"economyDeploymentBlock": "11902290",
"indexedThroughBlock": "11916994",
"safeThroughBlock": "11916983",
"safeBlockHash": "0x3af7c3393f01379493be3e10b29649f1ee6e7026b4f880821546ef4fe1e43714",
"safeBlockTimestamp": "2026-10-15T00:55:24.000Z"
},
"release": {
"id": "squeeks-sepolia-core3-mining6-001",
"protocolRevision": "mining-6",
"rewardModelRevision": "q128-round-fixed-1"
},
"identities": {
"core": "0x74665daeca35a2303e767e76a2ff1fb6f93e119f",
"mining": "0x3bee588fc20de788bac17d33b41da7346cb27ec4",
"token": "0x6872bfa5ccc3e9e440c6c16e5ffdabb8dba4cc76",
"collection": "0x0eaf3e0d40a0a8e5a6ac030b2459e9fb0b7905c6",
"miningImplementation": "0x08890b360c65fd878344bf6e23d1c36358433b4e",
"miningImplementationVersion": "6",
"miningStorageLayoutDigest": "0xace564e9c052f30122779a32fdf3333ebce7cc708eae9c01cb7875b4f6ad37a6"
},
"nextCursor": "eyJ2IjoxLCJrIjoicGEiLCJjIjoiYWxsIiwicyI6IjExOTE2OTgzIiwiYiI6IjExOTE2MTA5IiwidCI6IjEyNCIsImwiOiIyNDYiLCJvIjoiMjAyNi0xMC0xNFQyMjozOTozMC45MjNaIiwiciI6IjQyMzciLCJlIjoibWVhc3VyZW1lbnQ6aGFtc3Rlci1zZXBvbGlhLWNvcmUzLW1pbmluZzYtMDAxOmhhbXN0ZXItc3BlZWQtcmVjb3JkLTE6bWVhc3VyZW1lbnQuc3BlZWRfcmVjb3JkOjEzMjcifQ",
"category": "all",
"activeEventTypes": [
"system.settlement_completed",
"system.mining_checkpointed",
"player.squeek_minted",
"player.squeeks_merged",
"player.rewards_claimed",
"measurement.distance_milestone",
"measurement.daily_distance_milestone",
"measurement.speed_milestone",
"measurement.speed_record",
"measurement.distance_streak"
],
"events": [
{
"id": "chain:11155111:0x3bee588fc20de788bac17d33b41da7346cb27ec4:0x73380faf2c7c14f93af8c99f1d42d9f5d0ea32dddc18a606db5c735e550bbb65:758:system.mining_checkpointed",
"eventVersion": 2,
"occurredAt": "2026-10-15T00:46:00.000Z",
"recordedAt": "2026-10-15T00:46:00.000Z",
"source": {
"kind": "chain",
"chainId": "11155111",
"target": "sepolia",
"releaseId": "squeeks-sepolia-core3-mining6-001",
"contractAddress": "0x3bee588fc20de788bac17d33b41da7346cb27ec4",
"blockNumber": "11916936",
"blockHash": "0x275493b9fee9de376b03eece067362aacdc9a8006ed0c31c91ec8264e805e668",
"transactionHash": "0x73380faf2c7c14f93af8c99f1d42d9f5d0ea32dddc18a606db5c735e550bbb65",
"transactionIndex": "144",
"logIndex": "758",
"confirmationStatus": "safe"
},
"type": "system.mining_checkpointed",
"payload": {
"afterRound": "294",
"throughRound": "295",
"completedBlockCount": "55",
"cumulativeWork": "29212",
"cumulativeBlockUnits": "2614966878647",
"amountBaseUnits": "308000000000000000000000",
"asset": {"address": "0x6872bfa5ccc3e9e440c6c16e5ffdabb8dba4cc76", "symbol": "SQK", "decimals": 18}
}
},
{
"id": "measurement:hamster-sepolia-core3-mining6-001:hamster-distance-streak-1:measurement.distance_streak:2026-10-14",
"eventVersion": 1,
"occurredAt": "2026-10-15T00:36:58.351Z",
"recordedAt": "2026-10-15T00:36:58.627Z",
"source": {
"kind": "measurement",
"installationId": "hamster-sepolia-core3-mining6-001",
"receiptCursor": "5285",
"telemetryId": "01a13cfd-a56f-7916-99a2-b18348ee2f98",
"observedAt": "2026-10-15T00:36:58.351Z",
"receivedAt": "2026-10-15T00:36:58.627Z",
"policyVersion": "hamster-distance-streak-1",
"disposition": "accepted"
},
"type": "measurement.distance_streak",
"payload": {"days": 3, "minimumDailyDistanceMm": "5000000", "endingUtcDate": "2026-10-14"}
}
]
}
| Field | Type | Description |
|---|---|---|
category |
string |
The requested category |
activeEventTypes |
string[] |
Event types this feed can contain |
events[].id |
string |
Stable, unique event ID; use it to deduplicate |
events[].type |
string |
One of the types below |
events[].occurredAt |
string |
When it happened: the block time, or the measurement time |
events[].recordedAt |
string |
When Squeekchain recorded it |
events[].source |
object |
kind: "chain" with the contract, block, transaction and log position (always confirmationStatus: "safe"); or kind: "measurement" with the installation, telemetry ID and times |
events[].payload |
object |
Type-specific values, below |
nextCursor |
string or null |
The next page; null at the end |
| Type | Category | Payload |
|---|---|---|
system.settlement_completed |
protocol |
Round range, activeRoundCount, workAdded, completed blocks, cumulativeWork, blockHeight, cumulativeBlockUnits |
system.mining_checkpointed |
protocol |
afterRound, throughRound, completedBlockCount, amountBaseUnits, asset, cumulativeWork, cumulativeBlockUnits |
player.squeek_minted |
players |
owner, tokenId, weight, nextMergeBlock, firstRound |
player.squeeks_merged |
players |
owner, survivorTokenId, donorTokenId, level, nextMergeBlock, effectiveRound |
player.rewards_claimed |
players |
owner, tokenIds, amountBaseUnits, asset |
measurement.distance_milestone |
measurement |
thresholdDistanceMm, observedLifetimeDistanceMm at 1, 3, 5, 10, 15, 20, 30 … 100 km, then every 50 km |
measurement.daily_distance_milestone |
measurement |
thresholdDistanceMm, observedDayDistanceMm, utcDate at 1, 3, 5, 10 and 15 km in a day |
measurement.speed_milestone |
measurement |
thresholdSpeedMmPerSecond, observedSpeedMmPerSecond at 2, 3, 6 and 10 km/h |
measurement.speed_record |
measurement |
previousRecordMmPerSecond, recordMmPerSecond, observedSpeedMmPerSecond; a new top speed at least 0.2 km/h above the last |
measurement.distance_streak |
measurement |
days, minimumDailyDistanceMm, endingUtcDate: 5 km a day on consecutive days, from day two |
The schema also lists measurement.rpm_record, which this endpoint never returns. Days for measurement events run from 12:00 UTC to 12:00 UTC.
Freshness
Chain events appear once they have 12 confirmations; measurement events once the measurement is accepted. Unavailable reasons: indexer_disabled, not_yet_safe, indexer_unavailable, indexer_mismatch, source_disabled.
Errors
| Status | Code | Cause |
|---|---|---|
| 400 | invalid_cursor |
The cursor can't be decoded or was issued for another category; start again from the first page |
| 400 | invalid_query |
Also returned for a cursor containing characters other than A–Z a–z 0–9 _ - |
Issuance and SqueeksLink to this section
SQK issuance and supply, each owner's Squeeks and rewards, their history, and each Squeek's metadata.
Issuance state · GET /v1/mining/stateLink to this section
SQK issuance and supply, how far SqueekMining has processed rounds, and the state of the Squeek sale. Use it for supply figures and the mint page.
The endpoint takes no parameters; any query parameter returns 400 invalid_query.
Example request
curl -i https://api.squeekchain.com/v1/mining/state
Response
{
"schemaVersion": 1,
"installationId": "hamster-sepolia-core3-mining6-001",
"status": "available",
"generatedAt": "2026-10-15T00:56:09.247Z",
"release": {
"id": "squeeks-sepolia-core3-mining6-001",
"protocolRevision": "mining-6",
"rewardModelRevision": "q128-round-fixed-1"
},
"chain": {
"target": "sepolia",
"chainId": "11155111",
"confirmations": "12",
"deploymentBlock": "11902282",
"economyDeploymentBlock": "11902290",
"indexedThroughBlock": "11916986",
"safeThroughBlock": "11916975",
"safeBlockHash": "0x6a4cec14952c737210721a03d40772a52d05650cd173cb627744be69cec18db6",
"safeBlockTimestamp": "2026-10-15T00:53:48.000Z"
},
"identities": {
"core": "0x74665daeca35a2303e767e76a2ff1fb6f93e119f",
"mining": "0x3bee588fc20de788bac17d33b41da7346cb27ec4",
"token": "0x6872bfa5ccc3e9e440c6c16e5ffdabb8dba4cc76",
"collection": "0x0eaf3e0d40a0a8e5a6ac030b2459e9fb0b7905c6",
"miningImplementation": "0x08890b360c65fd878344bf6e23d1c36358433b4e",
"miningImplementationVersion": "6",
"miningStorageLayoutDigest": "0xace564e9c052f30122779a32fdf3333ebce7cc708eae9c01cb7875b4f6ad37a6"
},
"asset": {"address": "0x6872bfa5ccc3e9e440c6c16e5ffdabb8dba4cc76", "symbol": "SQK", "decimals": 18},
"issuance": {
"mintedBaseUnits": "13624800000000000000000000",
"tokenSupplyBaseUnits": "13624800000000000000000000",
"unmintedCapacityBaseUnits": "2086375200000000000000000000",
"closedThroughBlock": "2614",
"processedThroughRound": "295",
"lastActivationRound": "5",
"supplyCapBaseUnits": "2100000000000000000000000000",
"paidBaseUnits": "6272000000000000000000"
},
"collection": {
"phase": "public",
"paused": true,
"publicMinted": "0",
"publicAllocation": "8888",
"reserveMinted": "100",
"protocolReserve": "1111",
"publicPriceBaseUnits": "0",
"allowlistStart": null,
"allowlistEnd": null
},
"livePositionCount": "100"
}
| Field | Type | Description |
|---|---|---|
asset |
object |
The SQK token: address, symbol, decimals |
issuance.mintedBaseUnits |
string |
SQK issued so far |
issuance.tokenSupplyBaseUnits |
string |
SQK total supply |
issuance.unmintedCapacityBaseUnits |
string |
SQK left under the supply cap |
issuance.supplyCapBaseUnits |
string |
The lifetime cap. May be absent |
issuance.paidBaseUnits |
string |
SQK claimed by owners so far. May be absent |
issuance.closedThroughBlock |
string |
The last Squeek block SqueekMining has funded |
issuance.processedThroughRound |
string |
The last round SqueekMining has funded |
issuance.lastActivationRound |
string |
The last round in which pending power changes took effect |
collection.phase |
string |
unconfigured, pending, allowlist, public or closed. The collection object may be absent |
collection.paused |
boolean |
Whether minting is paused |
collection.publicMinted, collection.publicAllocation |
string |
Squeeks minted from, and the size of, the public allocation |
collection.reserveMinted, collection.protocolReserve |
string |
Squeeks minted from, and the size of, the Hamster-Owned Liquidity reserve |
collection.publicPriceBaseUnits |
string |
Mint price in wei (ETH), not SQK |
collection.allowlistStart, collection.allowlistEnd |
string or null |
The allowlist window |
livePositionCount |
string |
Squeeks currently registered in SqueekMining. May be absent |
Freshness
Read at the safe block and shared for up to 5 seconds. Unavailable reasons: indexer_disabled, not_yet_safe, indexer_unavailable, indexer_mismatch, unsupported_contract_version, projection_rebuilding.
Owner's Squeeks · GET /v1/owners/{address}/squeeksLink to this section
Every Squeek an address owns, with its level, power, merge readiness and SQK, plus totals and seven days of earnings. Use it for a portfolio view.
Path and query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
address |
string |
Yes | The owner's address: 0x and 40 hex digits, all lowercase or with a valid EIP-55 checksum. Anything else, including a wrong checksum or the zero address, returns 400 invalid_address |
limit |
integer |
No | Squeeks per page, 1–100; default 25 |
cursor |
string |
No | nextCursor from the previous page, with the same address |
Example request
curl -i "https://api.squeekchain.com/v1/owners/0x828CB04Dbf0BDd8eB35d19045638a1af6E3D17E8/squeeks?limit=25"
// api-owner-squeeks.ts
import { apiGet, required } from "./api";
type Page = {
status: "available" | "unavailable";
reason?: string;
summary?: { positionCount: string; claimableBaseUnits: string };
positions?: { tokenId: string; level: number; activeWeight: string; claimableBaseUnits: string }[];
nextCursor?: string | null;
};
const owner = required("OWNER_ADDRESS");
const positions: NonNullable<Page["positions"]> = [];
let cursor: string | null = null;
do {
const query = new URLSearchParams({ limit: "100", ...(cursor ? { cursor } : {}) });
const page: Page = await apiGet<Page>(`/v1/owners/${owner}/squeeks?${query}`);
if (page.status !== "available") throw new Error(`Owner data unavailable: ${page.reason}`);
positions.push(...(page.positions ?? []));
cursor = page.nextCursor ?? null;
} while (cursor !== null);
const claimable = positions.reduce((sum, position) => sum + BigInt(position.claimableBaseUnits), 0n);
console.log({ owner, squeeks: positions.length, claimableSqkBaseUnits: claimable });
// api.ts
export const required = (name: string): string => {
const value = process.env[name];
if (!value) throw new Error(`Supply ${name}`);
return value;
};
/** GET a public endpoint, waiting out rate limits and capacity errors a bounded number of times. */
export async function apiGet<T>(path: string): Promise<T> {
const base = required("API_BASE_URL");
for (let attempt = 0; ; attempt += 1) {
const response = await fetch(new URL(path, base), { headers: { accept: "application/json" } });
if ((response.status === 429 || response.status === 503) && attempt < 3) {
const seconds = Number(response.headers.get("retry-after") ?? "2");
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
continue;
}
if (!response.ok) throw new Error(`${path}: HTTP ${response.status} ${await response.text()}`);
return (await response.json()) as T;
}
}
Set API_BASE_URL=https://api.squeekchain.com and OWNER_ADDRESS, then run npx tsx api-owner-squeeks.ts.
Response
Example response
{
"schemaVersion": 1,
"installationId": "hamster-sepolia-core3-mining6-001",
"status": "available",
"generatedAt": "2026-10-15T00:57:41.296Z",
"release": {
"id": "squeeks-sepolia-core3-mining6-001",
"protocolRevision": "mining-6",
"rewardModelRevision": "q128-round-fixed-1"
},
"owner": "0x828cb04dbf0bdd8eb35d19045638a1af6e3d17e8",
"chain": {
"target": "sepolia",
"chainId": "11155111",
"confirmations": "12",
"deploymentBlock": "11902282",
"economyDeploymentBlock": "11902290",
"indexedThroughBlock": "11916993",
"safeThroughBlock": "11916982",
"safeBlockHash": "0x44ce0cd3258a6668ba8a9e19c06153a53dca21e68bdcded5189ab951ff99e019",
"safeBlockTimestamp": "2026-10-15T00:55:12.000Z"
},
"identities": {
"core": "0x74665daeca35a2303e767e76a2ff1fb6f93e119f",
"mining": "0x3bee588fc20de788bac17d33b41da7346cb27ec4",
"token": "0x6872bfa5ccc3e9e440c6c16e5ffdabb8dba4cc76",
"collection": "0x0eaf3e0d40a0a8e5a6ac030b2459e9fb0b7905c6",
"miningImplementation": "0x08890b360c65fd878344bf6e23d1c36358433b4e",
"miningImplementationVersion": "6",
"miningStorageLayoutDigest": "0xace564e9c052f30122779a32fdf3333ebce7cc708eae9c01cb7875b4f6ad37a6"
},
"configuration": {
"genesisTimestamp": "1791847800",
"roundDuration": "600",
"maxCheckpointActivations": "32",
"blockUnitsPerBlock": "1000000000",
"rewardPerBlock": "5600000000000000000000",
"supplyCap": "2100000000000000000000000000",
"initialWorkPerThousandBlocks": "10875",
"maximumLevel": 10,
"claimLimit": "32",
"tokenSymbol": "SQK",
"tokenDecimals": 18,
"levels": [
{"level": 1, "weight": "1000", "cooldownBlocks": "2"},
{"level": 2, "weight": "3000", "cooldownBlocks": "4"}
]
},
"mining": {
"settledThroughRound": "295",
"currentRound": "297",
"completedBlockHeight": "2614",
"processedThroughRound": "295",
"lastActivationRound": "5",
"totalWeight": "100000"
},
"summary": {
"positionCount": "100",
"activeWeight": "100000",
"targetWeight": "100000",
"claimableBaseUnits": "13618528000000000000000000",
"earnedBaseUnits": "13624800000000000000000000",
"earnedSevenDayBaseUnits": "13624800000000000000000000"
},
"earnings": [
{"date": "2026-10-14", "earnedBaseUnits": "6636000000000000000000000"},
{"date": "2026-10-15", "earnedBaseUnits": "1243200000000000000000000"}
],
"positions": [
{
"tokenId": "8889",
"level": 1,
"activeWeight": "1000",
"targetWeight": "1000",
"pendingRound": null,
"pendingActivationSource": null,
"mergeState": "ready",
"nextMergeBlock": "2",
"blocksUntilMerge": "0",
"claimableBaseUnits": "129976000000000000000000",
"earnedBaseUnits": "136248000000000000000000",
"earnedSevenDayBaseUnits": "136248000000000000000000",
"ownershipStartedAt": "2026-10-13T00:09:00.000Z",
"metadataStatus": "available"
}
],
"nextCursor": "eyJ2ZXJzaW9uIjoyLCJraW5kIjoicG9zaXRpb25zIiwib3duZXIiOiIweDgyOGNiMDRkYmYwYmRkOGViMzVkMTkwNDU2MzhhMWFmNmUzZDE3ZTgiLCJyZWxlYXNlSWQiOiJzcXVlZWtzLXNlcG9saWEtY29yZTMtbWluaW5nNi0wMDEiLCJzYWZlVGhyb3VnaEJsb2NrIjoiMTE5MTY5ODIiLCJzYWZlQmxvY2tIYXNoIjoiMHg0NGNlMGNkMzI1OGE2NjY4YmE4YTllMTljMDYxNTNhNTNkY2EyMWU2OGJkY2RlZDUxODlhYjk1MWZmOTllMDE5IiwibGFzdFRva2VuSWQiOiI4ODkwIn0"
}
| Field | Type | Description |
|---|---|---|
owner |
string |
The owner, lowercase, whatever casing the request used |
configuration |
object |
SqueekMining's settings: genesisTimestamp, roundDuration, maximumLevel, claimLimit, maxCheckpointActivations, rewardPerBlock, supplyCap, token symbol and decimals |
configuration.levels[] |
object |
Per level: level, weight (power) and cooldownBlocks |
mining |
object |
Global progress: settledThroughRound, currentRound, completedBlockHeight, processedThroughRound, lastActivationRound, totalWeight |
summary |
object |
Across all the owner's Squeeks, not just this page: positionCount, activeWeight, targetWeight, claimableBaseUnits, earnedBaseUnits, earnedSevenDayBaseUnits |
earnings[] |
object |
Seven entries, oldest first: date (UTC) and earnedBaseUnits |
positions[].tokenId |
string |
The Squeek's token ID |
positions[].level |
integer |
Level, 1–10 |
positions[].activeWeight |
string |
Power earning now |
positions[].targetWeight |
string |
Power once a pending change activates |
positions[].pendingRound |
string or null |
The round a pending change activates in |
positions[].pendingActivationSource |
string or null |
mint or merge |
positions[].mergeState |
string |
The first that applies: pending (a change is waiting to activate), terminal (maximum level), cooldown or ready |
positions[].nextMergeBlock |
string |
The Squeek block from which it can merge again |
positions[].blocksUntilMerge |
string |
Squeek blocks until then; 0 when ready |
positions[].claimableBaseUnits |
string |
SQK claimable now, at the safe block |
positions[].earnedBaseUnits |
string |
SQK earned since the current owner took it, including what a merged-in donor had earned for that owner |
positions[].earnedSevenDayBaseUnits |
string |
SQK earned in the last seven days |
positions[].ownershipStartedAt |
string |
When the current owner received it |
positions[].metadataStatus |
string |
Whether /v1/squeeks/{tokenId}/metadata can serve it: available or unavailable |
nextCursor |
string or null |
The next page; null at the end |
claimableBaseUnits is a display value 12 blocks old. Before preparing a claim, read claimable at your own block; see Build owner actions.
Freshness
Computed per request at the safe block. A cursor pins the owner, release, safe block and that block's hash. Unavailable reasons: indexer_disabled, not_yet_safe, indexer_unavailable, indexer_mismatch, unsupported_contract_version, projection_rebuilding.
Errors
| Status | Code | Cause |
|---|---|---|
| 400 | invalid_address |
address is malformed, has a wrong checksum or is the zero address |
| 400 | invalid_cursor |
The cursor can't be decoded or was issued for another route; start again from the first page |
| 409 | cursor_invalidated |
The page's block was reorganized away, or the cursor belongs to another owner or release. Restart from the first page |
Owner activity · GET /v1/owners/{address}/activityLink to this section
An address's history with its Squeeks, newest first: mints, merges, claims and transfers. Use it for an account history.
Path and query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
address |
string |
Yes | The owner's address, lowercase or checksummed, as for Owner's Squeeks |
limit |
integer |
No | Entries per page, 1–100; default 25 |
cursor |
string |
No | nextCursor from the previous page, with the same address |
Example request
curl -i "https://api.squeekchain.com/v1/owners/0x828cb04dbf0bdd8eb35d19045638a1af6e3d17e8/activity?limit=25"
Response
{
"schemaVersion": 1,
"installationId": "hamster-sepolia-core3-mining6-001",
"status": "available",
"generatedAt": "2026-10-15T00:56:14.556Z",
"owner": "0x828cb04dbf0bdd8eb35d19045638a1af6e3d17e8",
"chain": {
"target": "sepolia",
"chainId": "11155111",
"confirmations": "12",
"deploymentBlock": "11902282",
"economyDeploymentBlock": "11902290",
"indexedThroughBlock": "11916986",
"safeThroughBlock": "11916975",
"safeBlockHash": "0x6a4cec14952c737210721a03d40772a52d05650cd173cb627744be69cec18db6",
"safeBlockTimestamp": "2026-10-15T00:53:48.000Z"
},
"release": {
"id": "squeeks-sepolia-core3-mining6-001",
"protocolRevision": "mining-6",
"rewardModelRevision": "q128-round-fixed-1"
},
"identities": {
"core": "0x74665daeca35a2303e767e76a2ff1fb6f93e119f",
"mining": "0x3bee588fc20de788bac17d33b41da7346cb27ec4",
"token": "0x6872bfa5ccc3e9e440c6c16e5ffdabb8dba4cc76",
"collection": "0x0eaf3e0d40a0a8e5a6ac030b2459e9fb0b7905c6",
"miningImplementation": "0x08890b360c65fd878344bf6e23d1c36358433b4e",
"miningImplementationVersion": "6",
"miningStorageLayoutDigest": "0xace564e9c052f30122779a32fdf3333ebce7cc708eae9c01cb7875b4f6ad37a6"
},
"activity": [
{
"id": "179185251600000000111551110000000011902583000000000000009350000000000000132",
"kind": "claim",
"tokenIds": ["8889"],
"amountBaseUnits": "6272000000000000000000",
"from": null,
"to": null,
"level": null,
"effectiveRound": null,
"nextMergeBlock": null,
"source": {
"blockNumber": "11902583",
"blockHash": "0xefbeeed403baf747669d24a95bca2230b1389b2ac7180868722a812d8135eb78",
"blockTimestamp": "2026-10-13T00:48:36.000Z",
"transactionHash": "0x4e21ce566ec8a4eb3fb9e1a49a58faf6acd87d677764740a41f5b18e44fe94d8",
"transactionIndex": "93",
"logIndex": "132",
"confirmationStatus": "safe"
}
}
],
"total": "101",
"nextCursor": "eyJ2ZXJzaW9uIjoxLCJzYWZlVGhyb3VnaEJsb2NrIjoiMTE5MTY5NzUiLCJibG9ja051bWJlciI6IjExOTAyMzg3IiwidHJhbnNhY3Rpb25JbmRleCI6Ijk0IiwibG9nSW5kZXgiOiI0NzMifQ"
}
| Field | Type | Description |
|---|---|---|
activity[].id |
string |
Stable, unique entry ID |
activity[].kind |
string |
mint, merge, claim or transfer |
activity[].tokenIds |
string[] |
The Squeeks involved; for a merge, the survivor and the donor |
activity[].amountBaseUnits |
string or null |
SQK claimed; null except for claims |
activity[].from, activity[].to |
string or null |
Transfer parties; null except for transfers |
activity[].level |
integer or null |
The survivor's new level after a merge |
activity[].nextMergeBlock |
string or null |
When the Squeek can merge again, after a mint or merge |
activity[].effectiveRound |
string or null |
The round new power activates in, after a mint or merge |
activity[].source |
object |
blockNumber, blockHash, blockTimestamp, transactionHash, transactionIndex, logIndex, confirmationStatus: "safe" |
total |
string |
Entries in the owner's whole history. May be absent |
nextCursor |
string or null |
The next page; null at the end |
Freshness
Computed per request at the safe block; an entry is final once listed, at 12 confirmations. A cursor keeps reading at the first page's safe block, so pages are consistent. Unavailable reasons: indexer_disabled, not_yet_safe, indexer_unavailable, indexer_mismatch, unsupported_contract_version, projection_rebuilding.
Errors
| Status | Code | Cause |
|---|---|---|
| 400 | invalid_address |
address is malformed, has a wrong checksum or is the zero address |
| 400 | invalid_cursor |
The cursor can't be decoded or was issued for another route; start again from the first page |
Squeek metadata · GET /v1/squeeks/{tokenId}/metadataLink to this section
A Squeek's name, description, traits and image, rendered onchain by the DotGrid renderer. Use it to show a Squeek without calling tokenURI yourself.
Path and query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
tokenId |
string |
Yes | Token ID, 1–9999, without leading zeros |
release |
string |
No | The release ID from release.id. With it, the response may give a cached raster image (cardImageUrl) instead of the inline SVG. Any other value returns 400 invalid_query |
Example request
curl -i https://api.squeekchain.com/v1/squeeks/8889/metadata
Response
{
"schemaVersion": 1,
"installationId": "hamster-sepolia-core3-mining6-001",
"status": "available",
"generatedAt": "2026-10-15T00:56:15.076Z",
"tokenId": "8889",
"chain": {
"target": "sepolia",
"chainId": "11155111",
"confirmations": "12",
"deploymentBlock": "11902282",
"economyDeploymentBlock": "11902290",
"indexedThroughBlock": "11916986",
"safeThroughBlock": "11916975",
"safeBlockHash": "0x6a4cec14952c737210721a03d40772a52d05650cd173cb627744be69cec18db6",
"safeBlockTimestamp": "2026-10-15T00:53:48.000Z"
},
"identities": {
"core": "0x74665daeca35a2303e767e76a2ff1fb6f93e119f",
"mining": "0x3bee588fc20de788bac17d33b41da7346cb27ec4",
"token": "0x6872bfa5ccc3e9e440c6c16e5ffdabb8dba4cc76",
"collection": "0x0eaf3e0d40a0a8e5a6ac030b2459e9fb0b7905c6",
"miningImplementation": "0x08890b360c65fd878344bf6e23d1c36358433b4e",
"miningImplementationVersion": "6",
"miningStorageLayoutDigest": "0xace564e9c052f30122779a32fdf3333ebce7cc708eae9c01cb7875b4f6ad37a6"
},
"release": {
"id": "squeeks-sepolia-core3-mining6-001",
"protocolRevision": "mining-6",
"rewardModelRevision": "q128-round-fixed-1"
},
"collection": "0x0eaf3e0d40a0a8e5a6ac030b2459e9fb0b7905c6",
"name": "Squeek #8889",
"description": "Squeek is a dot-grid character rendered fully onchain from an immutable art page.",
"imageDataUri": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciLz4=",
"attributes": [
{"traitType": "Palette", "value": "Spectral Acid Lime"},
{"traitType": "Color Pattern", "value": "Vertical Split"},
{"traitType": "Body Glyph", "value": "Circle"}
]
}
| Field | Type | Description |
|---|---|---|
tokenId |
string |
The token ID |
collection |
string |
The SqueekNFT address |
name, description |
string |
As in the onchain metadata |
imageDataUri |
string |
The image as an SVG data URI (up to about 240 KB). Present unless cardImageUrl is |
cardImageUrl |
string |
An HTTPS raster image, only for requests that name release when one exists |
attributes[] |
object |
Traits: traitType and value |
Freshness
Read at the safe block for the current metadata epoch. Responses are no-store, except a release-scoped response with cardImageUrl, which is private, max-age=300. Unavailable reasons: indexer_disabled, not_yet_safe, indexer_unavailable, indexer_mismatch, unsupported_contract_version, projection_rebuilding.
Errors
| Status | Code | Cause |
|---|---|---|
| 400 | invalid_token_id |
Not a token ID from 1 to 9999 |