Nukez

Docs · HTTP

HTTP API

any language

Reference

Endpoint reference

Gateway Reference

Authenticated locker and file endpoints carry two headers: X-Nukez-Envelope and X-Nukez-Signature. The envelope binds method, path, body_sha256, receipt_id, locker_id, nonce, iat/exp, and the required ops array. POST bodies hash the exact bytes sent; authenticated GETs sign body_sha256 of empty bytes. The envelope itself is canonical JSON — sorted keys, compact separators, and ensure_ascii disabled — serialized to UTF-8 bytes, and the gateway rejects any envelope whose lifetime (exp minus iat) exceeds 300 seconds. See /docs/http/helpers for portable signers.

Discovery

MethodPathAuthDescription
GET/.well-known/nukez.jsonnoneService capabilities, supported networks, signed-envelope ops by endpoint, and real-world failure-mode hints.

Storage payment (x402 v2)

MethodPathAuthDescription
POST/v1/storage/requestnoneReturns HTTP 402 with x402 v2 accepts[] (8 legs at present: Solana SOL/USDC/USDT/WETH and Monad USDC/USDT0/MON/WETH). Quote TTL is 300s.
POST/v1/storage/confirmX402-TXBody carries pay_req_id, pay_network, and pay_asset for the SELECTED accepts[] leg. X402-TX header carries the on-chain tx signature. Returns receipt + receipt_id.

Locker provisioning + record

MethodPathAuthDescription
POST/v1/storage/signed_provisionX-Nukez-Envelope · locker:provisionProvisions the locker bound to the receipt. locker_id is deterministic — sha256(receipt_id).hex()[:12].
GET/v1/lockers/{locker_id}/recordX-Nukez-Envelope · locker:readCold-path locker ownership document (locker_record_v4) — owner_id, operator_ids, provider, bucket, path_prefix.
GET/v1/storage/metadata/{locker_id}X-Nukez-Envelope · locker:readLocker metadata (locker_metadata_v1) including paid_amount, paid_raw, pay_asset, tx_hash, units, unit_price_usd. result_hash populates after attest.
POST/v1/storage/refreshX-Nukez-Envelope · locker:refreshRefreshes the locker manifest with a fresh ts and returns the file_api block.

Files

MethodPathAuthDescription
POST/v1/lockers/{locker_id}/filesX-Nukez-Envelope · locker:writeCreate a file entry. Returns upload_url, download_url, confirm_url. urls_expire_in_sec is 1800.
POST/v1/lockers/{locker_id}/files/batchX-Nukez-Envelope · locker:writeCreate entries for multiple files in one signed envelope. Returns per-file upload_url + a single confirm_batch_url.
GET/v1/lockers/{locker_id}/filesX-Nukez-Envelope · locker:listList files in the locker. Authenticated GETs still sign body_sha256 of empty bytes.
GET/v1/lockers/{locker_id}/files/{filename}X-Nukez-Envelope · locker:readRe-mint upload_url + download_url for an existing file (?ttl_min=30 default).
DELETE/v1/lockers/{locker_id}/files/{filename}X-Nukez-Envelope · locker:writeTombstone the file in the manifest.
PUT{upload_url}URL tokenDirect PUT to the short upload URL from create_file. Short-URL tokens are bound to one HTTP method, so an upload token only authorizes PUT. The default path answers with a 307 redirect to storage that carries X-Nukez-Confirm-Required: true — a redirected upload still needs the confirm call afterward. A proxied PUT (?proxy=1) instead streams through the gateway, which hashes the bytes and records the hash in the manifest (X-Nukez-Content-Hash-Recorded response header). Anything potentially over 30 MB needs the resolve-redirect pattern (Cloud Run hard 32 MB body cap).
GET{download_url}URL tokenDirect GET from the GCS signed URL. Time-limited; for sharing prefer the receipt proxy below.
POST/v1/files/confirm?receipt_id={rid}&filename={f}X-Nukez-Envelope · locker:writeConfirm a single file upload; the gateway re-reads the stored bytes and records size_bytes + content_hash. Sign the envelope at confirm time, after the upload completes: it binds POST, the confirm path, the exact query string, and the canonical "{}" body, and its receipt_id must match the query receipt_id. Enforcement is staged (CONFIRM_AUTH_MODE), but signed usage is the contract; a missing envelope under enforcement returns 401 SIGNED_ENVELOPE_REQUIRED.
POST/v1/files/confirm-batchX-Nukez-Envelope · locker:writeConfirm a batch upload with one signed locker:write envelope bound to the full query string (every repeated filenames pair included). Re-confirm individual files via /v1/files/confirm if a single member fails (UPLOAD_VERIFY_MISSING_AFTER_WRITE).
GET/v1/r/{receipt_id}/f/{filename}nonePublic, stable receipt-based file proxy. 307-redirects to a fresh signed storage URL on every request — never expires, no GCS bucket-path leakage.

Attestation + verification

MethodPathAuthDescription
POST/v1/storage/attest?receipt_id={rid}X-Nukez-Envelope · locker:attestSigned-envelope attestation: computes the merkle root over confirmed files and pushes the att_code to a Switchboard PullFeed on Solana. The default call is asynchronous (202 + the managed background queue); ?sync=true enqueues through the same managed queue path and then polls the persisted attestation server-side, returning the terminal result or a 202-style in-flight response pointing at /v1/storage/verify if the poll ceiling (90 seconds by default) expires. Status moves pending → computed → pushing → complete; pollers should treat a truthy merkle_root as the completion signal. The gateway also auto-attests after every successful file confirm, so explicit calls are only needed to force a fresh anchor immediately. Note the error-code split for missing envelope headers: attest returns 422 VALIDATION_ERROR when both headers are absent (401 is reserved for present-but-invalid envelopes), while /v1/files/confirm deliberately returns 401 SIGNED_ENVELOPE_REQUIRED.
GET/v1/attest-code?receipt_id={rid}noneThe nine-digit integer att_code derived from result_hash (never from merkle_root), plus switchboard_slot/switchboard_tx for the latest anchor.
GET/v1/storage/recompute-verify?receipt_id={rid}X-Nukez-Envelope · locker:readByte-level integrity audit: re-downloads every stored file, re-hashes the bytes, rebuilds the merkle tree, and compares against the persisted attestation. Strictly read-only — it never overwrites the stored attestation. Requires a payer-signed locker:read envelope whose receipt_id matches the query receipt_id, because it causes the backend to retrieve file bytes. The routine attest path, by contrast, is a presence-and-consistency proof over the manifest's recorded hashes.
GET/v1/storage/merkle-proof?receipt_id={rid}&filename={f}nonePer-file Merkle inclusion proof: leaf_hash, proof[] (sibling+position), merkle_root, tree_depth, file_count, switchboard anchor.
POST/v1/storage/verifynonePublic verification snapshot. Body: {receipt_id}. On confirmed lockers the response carries the populated content_proof + on_chain_anchor (auto-reattest runs after every file confirm). Empty or pre-attest lockers return verified=false with an attestation_hint pointer.
GET/v1/storage/verification-bundle?receipt_id={rid}noneSelf-contained portable proof: payment_proof + content_proof (merkle_root, files) + on_chain_anchor + merkle_algorithm + verify_yourself + verify_page_url.
GET/specs/nukez-merkle-v1.jsonnoneMachine-readable canonical Merkle V1 specification for agents, auditors, SDKs, and external verifiers.
GET/v1/receipts/{rid}noneStored receipt object with receipt_hash, full payment metadata, and the signature fields receipt_sig and receipt_signer_pubkey. Both are hex-encoded Ed25519 values: the public key is 64 hex characters and signatures are 128 hex characters.
GET/v1/receipts/{rid}/verifynoneServer-recomputed receipt_hash for tamper-evidence cross-check.