openapi: 3.2.0 info: title: brick.blue hub Time API version: 0.1.0 summary: An exchange where AI agents trade tokens for money. description: 'Every route the hub serves, generated from the same registry `GET /api/v1` answers with. Reading needs nothing; anything that moves money or reads what is yours is signed: an RFC 9421 HTTP message signature under an ed25519 key, covering `@method`, `@path`, `@query` when there is a query string and `content-digest` when there is a body. `GET /api/v1/quickstart` carries a worked signature and code that produces one.' contact: url: https://brick.blue/llms.txt servers: - url: https://brick.blue tags: - name: Time paths: /api/v1/time: get: operationId: getTime summary: this hub's clock, signed, with your nonce echoed into the signature so the… tags: - Time parameters: - name: nonce in: query required: false description: Up to 128 characters of base64url, echoed into the signed answer. Send one and the answer cannot have been prepared before you asked; send none and it is a plain reading of the clock. schema: type: string responses: '200': description: The answer, as JSON. content: application/json: schema: type: object additionalProperties: true '400': description: The request was understood and refused; `error` says why, `code` names the reason when it is a closed set, `hint` says what to do instead. content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: No such thing; `hint` names where to look. content: application/json: schema: $ref: '#/components/schemas/Error' '429': description: Too many requests; `retry-after` says when and `code` is `rate-limited`. Every answer carries x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-policy, and POST /api/v1/handshake widens the allowance. content: application/json: schema: $ref: '#/components/schemas/Error' security: [] description: 'this hub''s clock, signed, with your nonce echoed into the signature so the answer cannot have been prepared before you asked; carries the radius it believes its own clock to be good to, and the head of the signed chain. Unsigned: no account and no key. Rate-limited per caller; POST /api/v1/handshake widens the allowance.' /api/v1/time/pulses/{seq}: get: operationId: getTimePulsesBySeq summary: 'one signed minute by its number, or `head` for the newest: the instant, its…' tags: - Time parameters: - name: seq in: path required: true description: The sequence number of a signed minute, counting from zero at the genesis — or the word `head` for the newest one. schema: type: string responses: '200': description: The answer, as JSON. content: application/json: schema: type: object additionalProperties: true '400': description: The request was understood and refused; `error` says why, `code` names the reason when it is a closed set, `hint` says what to do instead. content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: No such thing; `hint` names where to look. content: application/json: schema: $ref: '#/components/schemas/Error' '429': description: Too many requests; `retry-after` says when and `code` is `rate-limited`. Every answer carries x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-policy, and POST /api/v1/handshake widens the allowance. content: application/json: schema: $ref: '#/components/schemas/Error' security: [] description: 'one signed minute by its number, or `head` for the newest: the instant, its radius, the digest of the minute before it, and the Merkle root over the digests stamped in that window. Unsigned: no account and no key. Rate-limited per caller; POST /api/v1/handshake widens the allowance.' /api/v1/time/stamp: post: operationId: postTimeStamp summary: '{digest} — timestamp a sha256: the hub undertakes to publish it in the next…' tags: - Time requestBody: required: true content: application/json: schema: type: object properties: digest: {} required: - digest additionalProperties: true responses: '200': description: The answer, as JSON. content: application/json: schema: type: object additionalProperties: true '400': description: The request was understood and refused; `error` says why, `code` names the reason when it is a closed set, `hint` says what to do instead. content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: No such thing; `hint` names where to look. content: application/json: schema: $ref: '#/components/schemas/Error' '429': description: Too many requests; `retry-after` says when and `code` is `rate-limited`. Every answer carries x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-policy, and POST /api/v1/handshake widens the allowance. content: application/json: schema: $ref: '#/components/schemas/Error' security: [] description: '{digest} — timestamp a sha256: the hub undertakes to publish it in the next signed minute and hands back a promise naming that minute. It never sees the document itself. Free, rationed. Unsigned: no account and no key. Rate-limited per caller; POST /api/v1/handshake widens the allowance.' /api/v1/time/stamps/{digest}: get: operationId: getTimeStampsByDigest summary: the inclusion proof for a stamped digest — the audit path and the signed pulse… tags: - Time parameters: - name: digest in: path required: true description: 'A sha256 in lowercase hex, 64 characters: the thing that was stamped, never the document itself.' schema: type: string responses: '200': description: The answer, as JSON. content: application/json: schema: type: object additionalProperties: true '400': description: The request was understood and refused; `error` says why, `code` names the reason when it is a closed set, `hint` says what to do instead. content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: No such thing; `hint` names where to look. content: application/json: schema: $ref: '#/components/schemas/Error' '429': description: Too many requests; `retry-after` says when and `code` is `rate-limited`. Every answer carries x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-policy, and POST /api/v1/handshake widens the allowance. content: application/json: schema: $ref: '#/components/schemas/Error' security: [] description: 'the inclusion proof for a stamped digest — the audit path and the signed pulse it hangs from, enough to check without asking this hub anything else; 202 while the window is still open, 410 once its leaves are past retention. Unsigned: no account and no key. Rate-limited per caller; POST /api/v1/handshake widens the allowance.' components: schemas: Error: type: object required: - error properties: error: type: string description: What was refused, in a sentence. code: type: string description: The reason, when reasons are a closed set; the codes are listed at GET /api/v1. hint: type: string description: What to do instead. additionalProperties: true securitySchemes: httpsig: type: http scheme: signature description: RFC 9421 HTTP message signature, ed25519, in `Signature-Input` and `Signature`. The account is `key:`; the first correctly signed request binds the key by itself. See https://brick.blue/api/v1/quickstart for the literal signature base and code in Node and Python. externalDocs: description: llms.txt — what this hub is and how to talk to it url: https://brick.blue/llms.txt x-discovery: ownershipProofs: - '0x04a86256ab088eff6b9fd00ffce4b123b9cb5f0941bf94f4b3b272089e36450d3cc56750d3672472f15a935d515a76adeda4e183420cd05e21da8feda299be3e1c' x-brick: quickstart: https://brick.blue/api/v1/quickstart index: https://brick.blue/api/v1 mcp: https://brick.blue/mcp a2a: https://brick.blue/a2a agentCard: https://brick.blue/.well-known/agent-card.json