{"openapi":"3.1.0","info":{"title":"Nukez — Permissionless Storage for Autonomous Agents","version":"1.0.0"},"paths":{"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/price":{"get":{"summary":"Get Price","operationId":"get_price_v1_price_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/storage/attest":{"post":{"summary":"Storage Attest","description":"Compute content attestation.\n\nAUTH: Requires a payer-signed envelope (X-Nukez-Envelope + X-Nukez-Signature)\nwith the `locker:attest` operation. The envelope's receipt_id must match the\nquery-param receipt_id (belt-and-suspenders binding). Attestation computes\nthe locker's merkle fingerprint over confirmed files and persists it; when\nSB_AUTO_PUSH=true the gateway also pushes the att_code on-chain via\nSwitchboard (server-held SOL), so this endpoint must be authenticated to\nthe receipt's payer.\n\nDefault (sync=false): Returns 202. Attestation computes via Cloud Tasks.\nLegacy (sync=true): Blocks until complete. Use for scripts, PTK, debugging.\n\nIMPORTANT: ?sync=true MUST be preserved. PTK tests, store_source.py, and\nmanual debugging depend on it. Do not remove the sync path.\n\nQuery params:\n  receipt_id: The receipt ID bound to the locker\n  sync: If true, block until attestation is complete (legacy behavior)","operationId":"storage_attest_v1_storage_attest_post","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","title":"Receipt Id"}},{"name":"sync","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Sync"}},{"name":"X-Nukez-Envelope","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/storage/verify":{"get":{"summary":"Verify Locker Get","description":"Unified verification: returns payment proof + content proof together.\n\nThis is the endpoint that powers the green checkmark on nukez.xyz/verify/{id}.\nIt does NOT compute attestations — call POST /v1/storage/attest first.\n\nResponse includes:\n  - receipt: the payment proof (always present if receipt exists)\n  - attestation: the content proof (null if not yet computed)\n  - attestation_hint: how to compute attestation (if null)\n  - verified: true if both receipt and attestation exist\n  - verify_url: public verification URL","operationId":"verify_locker_get_v1_storage_verify_get","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Verify Locker Post","description":"Backward-compatible POST version of verify.\n\nAccepts { \"receipt_id\": \"...\" } in body.\nReturns same unified response as GET /v1/storage/verify.","operationId":"verify_locker_post_v1_storage_verify_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/retrieve":{"get":{"summary":"Retrieve Attestation","description":"Oracle callback target — returns attestation in Switchboard-expected shape.\n\nAUTH MODEL:\n  Reading existing attestations is open — agents, clients, verifiers,\n  and the oracle can all read without credentials.\n\n  Lazy computation (when no attestation exists yet) requires the\n  X-Oracle-Secret header. This prevents unauthenticated parties from\n  triggering compute_fingerprint() on arbitrary receipts.\n\n  When ORACLE_CALLBACK_SECRET is NOT set, lazy compute is allowed\n  for anyone (backward compat / dev mode).\n\nQuery params:\n  receipt_id: The receipt ID to retrieve attestation for\n\nReturns: Oracle-shaped response with att_code, result_hash, manifest","operationId":"retrieve_attestation_v1_retrieve_get","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/retrieve/payment":{"get":{"summary":"Retrieve Payment Attestation","description":"Oracle callback target for payment attestation feed (ADR-1).\n\nReturns payment data in Switchboard-expected shape. The oracle job\n(payment/402job.json) calls this endpoint, extracts $.att_code,\nand writes it to the payment PullFeed account on-chain.\n\nAUTH MODEL:\n  Same as /v1/retrieve — reading existing data is open.\n  When ORACLE_CALLBACK_SECRET is set, unauthenticated callers\n  still get the response (no lazy compute needed for payments —\n  the receipt must already exist from confirm).\n\nQuery params:\n  receipt_id: The receipt ID to retrieve payment data for\n\nReturns: Oracle-shaped response with att_code derived from\n         payment fields (chain, tx_hash, amount_raw, asset).","operationId":"retrieve_payment_attestation_v1_retrieve_payment_get","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attest-code":{"get":{"summary":"Get Attest Code","description":"Look up the attestation code for a receipt.\n\nChecks three sources in order:\n  1. receipt.result_hash (legacy — usually empty for storage receipts)\n  2. Persisted attestation object (Phase 5)\n  3. Returns 400 with hint to compute attestation","operationId":"get_attest_code_v1_attest_code_get","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attest/simulate":{"post":{"summary":"Attest Simulate","description":"Simulate the Switchboard on-demand feed for a given receipt.\n\nThe oracle independently calls Nukez's /v1/retrieve endpoint,\nextracts the attestation code, and returns the oracle-verified result.\n\nThis does NOT write on-chain — use /v1/attest/push for that.","operationId":"attest_simulate_v1_attest_simulate_post","requestBody":{"content":{"application/json":{"schema":{"title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attest/push":{"post":{"summary":"Attest Push","description":"Push an attestation on-chain via Switchboard PullFeed write + SPL Memo.\n\nAUTH: Requires a payer-signed envelope (X-Nukez-Envelope + X-Nukez-Signature)\nwith the `locker:attest` operation. The envelope's receipt_id must match the\nbody's receipt_id (belt-and-suspenders binding). This endpoint causes the\ngateway to spend server-held SOL on Switchboard PullFeed write + oracle\nquote + SPL Memo, so it must be authenticated to the receipt's payer.\n\nThe transaction contains:\n  - PullFeed update instruction writing att_code to the Switchboard feed account\n  - Signature verification precompile instruction for the oracle quote\n  - SPL Memo with the full merkle_root, receipt_id, file_count, and schema\n\nThe PullFeed account is resolved at runtime from ATTEST_FEED by scanning\nSwitchboard program accounts. No separate env var needed.\n\nAfter this call, the attestation is verifiable on-chain by any party:\n  - Read the PullFeed account on Solana for the oracle-verified att_code\n  - Read the SPL Memo from the transaction for the full merkle_root\n  - Verify the oracle quote signature from the verification precompile\nNo trust in Nukez required.\n\nBody: { \"receipt_id\": \"...\" }\n\nThis endpoint:\n  1. Loads the attestation for the receipt\n  2. Calls switchboard.mjs push — oracle resolves job, writes to feed account, appends memo\n  3. Records switchboard_slot and switchboard_tx in attestation\n  4. Returns push result\n\nIf attestation doesn't exist yet, returns 409 with hint.\nIf ATTEST_FEED is missing, returns graceful skip.","operationId":"attest_push_v1_attest_push_post","parameters":[{"name":"X-Nukez-Envelope","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/attest-code/jwt":{"get":{"summary":"Attest Code Jwt","description":"Full attestation flow:\n1. Verify JWT bearer token\n2. Load receipt\n3. Compute attestation code\n4. Run Switchboard oracle simulation\n5. Return combined result with oracle verification","operationId":"attest_code_jwt_v1_attest_code_jwt_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/receipts/{receipt_id}":{"get":{"summary":"Read Receipt","operationId":"read_receipt_v1_receipts__receipt_id__get","parameters":[{"name":"receipt_id","in":"path","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"summary":"Head Receipt","operationId":"head_receipt_v1_receipts__receipt_id__head","parameters":[{"name":"receipt_id","in":"path","required":true,"schema":{"title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/receipts/{receipt_id}/verify":{"get":{"summary":"Verify Receipt Endpoint","operationId":"verify_receipt_endpoint_v1_receipts__receipt_id__verify_get","parameters":[{"name":"receipt_id","in":"path","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/receipts/{receipt_id}/verify-payment":{"get":{"summary":"Verify Payment Binding","description":"Trust Boundary 2 — Receipt ↔ Payment Binding Verification.\n\nIndependently verifies that a receipt's payment claims match the\non-chain transaction. Public endpoint, no auth required.\n\nCurrently supports Solana on-chain verification. EVM verification\nwill be added when multi-chain receipts are live.\n\nChecks:\n    - Treasury received funds (balance delta > 0)\n    - received_amount >= receipt.paid_amount\n    - Payer pubkey matches receipt.payer_pubkey\n    - Slot matches receipt.slot (Solana)\n\nReturns:\n    200: Verification result with per-field match booleans\n    400: Receipt has no tx_hash (cannot verify)\n    404: Receipt not found\n    502: Transaction not found on-chain (RPC failure or pruned)","operationId":"verify_payment_binding_v1_receipts__receipt_id__verify_payment_get","parameters":[{"name":"receipt_id","in":"path","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/storage/provision":{"post":{"summary":"Storage Provision","description":"Provision a storage locker for a previously confirmed receipt_id.\n\nIMPORTANT (security):\n  - In production (Cloud Run), this endpoint requires a payer-signed envelope.\n  - For local dev ONLY, you may enable public provisioning by setting:\n        NUKEZ_ALLOW_PUBLIC_PROVISION=1\n    (and only when not running on Cloud Run).","operationId":"storage_provision_v1_storage_provision_post","parameters":[{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/storage/signed_provision":{"post":{"summary":"Signed Storage Provision","operationId":"signed_storage_provision_v1_storage_signed_provision_post","parameters":[{"name":"X-Nukez-Envelope","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/storage/refresh":{"post":{"summary":"Storage Refresh","description":"Refresh locker info — returns locker record with file_api hints.\n\nRequires signed envelope with locker:refresh operation.","operationId":"storage_refresh_v1_storage_refresh_post","parameters":[{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/storage/metadata/{locker_id}":{"get":{"summary":"Storage Metadata","description":"Return locker metadata. Requires signed envelope with locker:read.","operationId":"storage_metadata_v1_storage_metadata__locker_id__get","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/storage/request":{"post":{"summary":"Storage Request","description":"Start an x402 payment flow for provisioning storage data locker.\n\nMulti-chain support (CAIP-2 network identifiers):\n  - Solana (default): omit pay_network/pay_asset or set pay_network=\"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1\"\n  - EVM/Monad: set pay_network=\"eip155:10143\", pay_asset=\"USDC\" (or MON)\n  - Legacy friendly names (\"solana-devnet\", \"monad-testnet\") still accepted on input\n\n- Supports request idempotency via Idempotency-Key header\n- Persists the *price-quote* on the pay request so /confirm uses the same terms\n- Provider-aware pricing: MongoDB is cheaper than GCS for structured data\n- Includes terms for transparent garbage collection / TTL\n\n1) Read {\"units\": N, \"provider\": \"...\", \"pay_network\": \"...\", \"pay_asset\": \"...\"} from JSON body\n2) Compute total_usd = unit_price_usd * units (provider-specific)\n3) Compute chain-specific payment amount (SOL lamports or EVM token units)\n4) Create pay_req_id and stash {units, quote, terms}\n5) Return x402 payment challenge with quote details and terms","operationId":"storage_request_v1_storage_request_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/storage/confirm":{"post":{"summary":"Storage Confirm","description":"Confirm an x402 payment (multi-chain: Solana + EVM/Monad)\n\n1) Read {\"pay_req_id\": \"...} from the JSON body.\n2) Read signature/tx_hash from X402-TX header.\n3) Look up pending = get_pending(pay_req_id)\n4) Check quote expiry (410 Gone if expired)\n5) Determine payment chain from pending quote (network field)\n6) Dispatch to chain-specific verifier:\n   - Solana: verify_sol_payment(sig, min_sol)\n   - EVM:    verify_evm_payment(tx_hash, amount, asset, network, treasury)\n7) save_receipt(...) -> receipt_id.\n8) mark_paid(pay_req_id, receipt_id)\n9) return {\"ok\": True, \"receipt_id\": receipt_id}\n\nIdempotency behavior:\n    - If the pay request is already confirmed, returns the existing receipt.\n    - Receipt IDs are deterministic for a given (pay_req_id, tx_sig).\nTransaction signature sources (in priority order):\n    1. X402-TX header (canonical, spec-compliant)\n    2. tx_sig field in JSON body (fallback for constrained HTTP clients)","operationId":"storage_confirm_v1_storage_confirm_post","parameters":[{"name":"X402-TX","in":"header","required":false,"schema":{"type":"string","title":"X402-Tx"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/attest":{"post":{"tags":["internal"],"summary":"Internal Attest","description":"Execute attestation computation. Called by Cloud Tasks queue.\n\nRuns compute_fingerprint() and optionally push_attestation().\nReturns result to Cloud Tasks (200 = success, 5xx = retry).","operationId":"internal_attest_v1_internal_attest_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttestRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/attest-payment":{"post":{"tags":["internal"],"summary":"Internal Attest Payment","description":"Execute payment attestation. Called by Cloud Tasks queue (ADR-1).\n\nLoads the receipt, pushes payment data to the Switchboard payment feed,\nand records the result in the attestation object's payment_attestation\nsub-record.\n\nReturns result to Cloud Tasks (200 = success, 5xx = retry).","operationId":"internal_attest_payment_v1_internal_attest_payment_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentAttestRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/bridge-retry":{"post":{"tags":["internal"],"summary":"Internal Bridge Retry","description":"Retry a failed bridge operation. Called by Cloud Tasks with backoff.","operationId":"internal_bridge_retry_v1_internal_bridge_retry_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BridgeRetryRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/jobs/finalize-upload":{"post":{"tags":["internal"],"summary":"Internal Finalize Upload Job","description":"Execute a persistent upload-finalization job.\n\nCalled by Cloud Tasks. Returns 200 on success and 5xx for retryable failures.","operationId":"internal_finalize_upload_job_v1_internal_jobs_finalize_upload_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizeUploadJobRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/cron-attest":{"post":{"tags":["internal"],"summary":"Internal Cron Attest","description":"Periodic re-attestation of active lockers via Cloud Scheduler.\n\nProves data integrity over time — both for data that changed\n(caught by auto-reattest) and data that didn't change (cron's\nunique value: \"this locker's contents haven't changed since X\").\n\nCalled by Cloud Scheduler on a configurable interval.\nAuthenticated via _verify_internal() (same as Cloud Tasks).\n\nEnv vars:\n  CRON_ATTEST_ENABLED       — master toggle (true/false)\n  CRON_ATTEST_PUSH          — also push on-chain (true/false)\n  CRON_ATTEST_BATCH_SIZE    — max lockers per run (default 50)\n  CRON_ATTEST_MIN_AGE_HOURS — skip if attested within N hours (default 24)\n  CRON_ATTEST_FILTER        — all | unchanged | opted_in | tier\n  CRON_ATTEST_TIERS         — comma-separated qualifying tiers (for filter=tier)\n\nReturns summary of what was processed.","operationId":"internal_cron_attest_v1_internal_cron_attest_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/internal/attest-health":{"get":{"tags":["internal"],"summary":"Internal Attest Health","description":"Scan attestations and report push-pipeline health.\n\nReturns per-status counts and the oldest non-final attestation's age.\nA \"complete\" status — or a legacy record with a switchboard_tx and no\nstatus field — is final; pending/computed/pushing are in flight.\nEntries with no parseable attested_at (e.g. the bare \"pending\" stub the\nasync attest route writes at enqueue time) are counted separately as\nnonfinal_unknown_age rather than skewing the age figure.","operationId":"internal_attest_health_v1_internal_attest_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/internal/treasury/summary":{"get":{"tags":["internal"],"summary":"Internal Treasury Summary","description":"Return treasury balance summary across chains.\n\nOperator-facing endpoint for cross-chain accounting visibility.\nShows EVM payment totals, SOL attestation costs, and net position.\n\nGuarded by Cloud Tasks / internal-only auth.\nIn development mode, accessible without auth.","operationId":"internal_treasury_summary_v1_internal_treasury_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/storage/merkle-proof":{"get":{"summary":"Merkle Proof","description":"Get a merkle inclusion proof for a single file in an attested locker.\n\nThe proof consists of sibling hashes from the target leaf to the root.\nA verifier can walk the proof to reconstruct the merkle root and confirm\nit matches the on-chain attested root.\n\nProof verification algorithm:\n  1. Compute leaf_hash = SHA256(\"{filename}:{size_bytes}:{content_hash}\")\n  2. Walk the proof path:\n     - If sibling.position == \"right\": current = SHA256(current + sibling.hash)\n     - If sibling.position == \"left\":  current = SHA256(sibling.hash + current)\n  3. Final current must equal merkle_root\n\nQuery params:\n  receipt_id: Receipt ID for the locker\n  filename: Name of the file to prove inclusion for\n\nReturns:\n  JSON with proof path, leaf details, tree metadata, and verification data","operationId":"merkle_proof_v1_storage_merkle_proof_get","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","description":"Receipt ID for the locker","title":"Receipt Id"},"description":"Receipt ID for the locker"},{"name":"filename","in":"query","required":true,"schema":{"type":"string","description":"Filename to get proof for","title":"Filename"},"description":"Filename to get proof for"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/storage/sponsored-confirm":{"post":{"tags":["sponsored"],"summary":"Sponsored Confirm","description":"Sponsored provisioning: verify payment + create receipt + provision locker.\n\nThe sponsor (NukezAgent front-door) calls this after the developer pays\nthe gateway treasury directly. The locker is owned by the developer.\nNo operator is added — NukezAgent orchestrates via unsigned envelope\nconstruction, the developer signs everything.\n\nIdempotency:\n  - Deterministic receipt_id from (pay_req_id, tx_sig).\n  - If receipt exists but locker doesn't, provisions the locker.\n  - If both exist, returns them.\n\nRequest body:\n  pay_req_id: str      — from /v1/storage/request (402 response)\n  tx_sig: str           — developer's on-chain payment tx signature/hash\n  owner_identity: str   — developer's pubkey (must match on-chain payer)","operationId":"sponsored_confirm_v1_storage_sponsored_confirm_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/storage/sponsored-confirm-batch":{"post":{"tags":["sponsored"],"summary":"Sponsored Confirm Batch","description":"Batch sponsored provisioning: verify ONE payment, provision N lockers.\n\nThe single on-chain payment must cover the sum of all quotes.\nAll pay_req_ids must be on the same network.\nAll lockers are owned by owner_identity with no operators.\n\nIdempotency:\n  - Per-position receipt_id: _stable_receipt_id(pay_req_ids[i], tx_sig)\n  - Full retry: all exist → returns them as \"already_provisioned\"\n  - Partial retry: resumes from where it left off\n\nRequest body:\n  pay_req_ids: list[str]  — from N calls to /v1/storage/request\n  tx_sig: str              — single on-chain payment covering the total\n  owner_identity: str      — developer's pubkey (must match on-chain payer)\n  tags: list[str]          — optional tags for all lockers","operationId":"sponsored_confirm_batch_v1_storage_sponsored_confirm_batch_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/record":{"get":{"tags":["lockers_v1"],"summary":"Locker Record","operationId":"locker_record_v1_lockers__locker_id__record_get","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/urls":{"get":{"tags":["lockers_v1"],"summary":"Locker Urls","operationId":"locker_urls_v1_lockers__locker_id__urls_get","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/files":{"post":{"tags":["files"],"summary":"Create File","operationId":"create_file_v1_lockers__locker_id__files_post","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFileRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["files"],"summary":"List Files","operationId":"list_files_v1_lockers__locker_id__files_get","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/files/batch":{"post":{"tags":["files"],"summary":"Create Files Batch","description":"Create multiple file entries and return signed URL pairs in one call.\n\nThis is the canonical bulk primitive for SDK/MCP upload workflows.","operationId":"create_files_batch_v1_lockers__locker_id__files_batch_post","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateFileRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/files/{filename}":{"get":{"tags":["files"],"summary":"Get File","operationId":"get_file_v1_lockers__locker_id__files__filename__get","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}},{"name":"ttl_min","in":"query","required":false,"schema":{"type":"integer","maximum":1440,"minimum":1,"default":30,"title":"Ttl Min"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["files"],"summary":"Delete File","operationId":"delete_file_v1_lockers__locker_id__files__filename__delete","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/files/confirm":{"post":{"tags":["files"],"summary":"Confirm Upload","description":"Confirm a file upload by computing its content hash.\n\nCall this after uploading content to the signed URL returned by\nPOST /v1/lockers/{locker_id}/files.\n\nDownloads the content from storage, computes SHA256, and updates\nthe manifest with content_hash, size_bytes, and hash_recorded_at.\n\nIf expected_hash was provided during create_file(), verifies the\ncomputed hash matches. Raises 409 on mismatch.\n\nPhase N-7: If AUTO_REATTEST=true, also triggers re-attestation\nso the merkle root stays current after every upload.\n\nQuery params:\n    receipt_id: The receipt ID bound to the locker\n    filename: Name of the file to confirm","operationId":"confirm_upload_v1_files_confirm_post","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","title":"Receipt Id"}},{"name":"filename","in":"query","required":true,"schema":{"type":"string","title":"Filename"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/files/confirm-batch":{"post":{"tags":["files"],"summary":"Confirm Upload Batch","description":"Confirm multiple file uploads in a single operation.\n\nOne manifest read-modify-write, one re-attestation.\nErrors on individual files don't fail the batch.\n\nUsage:\n    POST /v1/files/confirm-batch?receipt_id=abc123&filenames=a.txt&filenames=b.txt\n\nReturns per-file results with content_hash and batch summary.","operationId":"confirm_upload_batch_v1_files_confirm_batch_post","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","description":"Receipt ID bound to the locker","title":"Receipt Id"},"description":"Receipt ID bound to the locker"},{"name":"filenames","in":"query","required":true,"schema":{"type":"array","items":{"type":"string"},"description":"Filenames to confirm (repeat param for multiple)","title":"Filenames"},"description":"Filenames to confirm (repeat param for multiple)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/files/fetch-and-store":{"post":{"tags":["files"],"summary":"Fetch And Store","description":"Fetch a file from an external HTTPS URL and store it in the locker.\n\nZero bytes flow through the LLM context — the gateway fetches the content\nserver-side and stores it directly.  SSRF prevention blocks private/reserved\nnetworks, metadata endpoints, and non-HTTPS URLs.\n\nAuth: Signed envelope with locker:write scope.\nThe locker_id and receipt_id are extracted from the signed envelope.","operationId":"fetch_and_store_v1_files_fetch_and_store_post","parameters":[{"name":"X-Nukez-Envelope","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":true,"schema":{"type":"string","title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FetchAndStoreRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/manifest":{"get":{"tags":["files"],"summary":"Get Manifest","description":"Return the full locker manifest — all file metadata in one call.\n\nUseful for:\n- Context management (agent knows what's stored without listing + fetching each)\n- Fast state sync (one call vs N calls)\n- Debugging (see full internal state)\n\nRequires locker:read authority (same as file download).","operationId":"get_manifest_v1_lockers__locker_id__manifest_get","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/files/urls":{"post":{"tags":["files"],"summary":"Batch Download Urls","description":"Generate signed download URLs for multiple files in one call.\n\nOne signed envelope, one API round-trip, N download URLs back.\nDesigned for batch download workflows where per-file URL generation\nwould trigger rate limits.\n\nAuth: Signed envelope or cap token with locker:read.\n\nBody:\n    filenames: [\"a.txt\", \"b.txt\", ...]\n    ttl_min: 30  (optional, default 30)\n\nResponse:\n    {\n        \"locker_id\": \"locker_abc123\",\n        \"urls\": [\n            {\n                \"filename\": \"a.txt\",\n                \"download_url\": \"https://...\",\n                \"content_type\": \"text/plain\",\n                \"content_hash\": \"sha256:...\",\n                \"size_bytes\": 1234\n            },\n            ...\n        ],\n        \"found\": 3,\n        \"not_found\": [\"missing.txt\"],\n        \"urls_expire_in_sec\": 1800\n    }","operationId":"batch_download_urls_v1_lockers__locker_id__files_urls_post","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchUrlsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/operators":{"post":{"tags":["operators"],"summary":"Add Operator","operationId":"add_operator_v1_lockers__locker_id__operators_post","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddOperatorRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/operators/{pubkey}":{"delete":{"tags":["operators"],"summary":"Remove Operator","operationId":"remove_operator_v1_lockers__locker_id__operators__pubkey__delete","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"pubkey","in":"path","required":true,"schema":{"type":"string","title":"Pubkey"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/short-url/verify-key":{"get":{"tags":["short-url"],"summary":"Get Short Url Verify Key","description":"Return the Ed25519 public key used to sign short URL tokens.\n\nAnyone can use this key to independently verify that a short URL\ntoken was issued by this Nukez gateway — no shared secret,\nno trust required.\n\nResponse:\n  {\n    \"verify_key_hex\": \"a1b2c3...\",   (64 hex chars = 32 bytes)\n    \"algorithm\": \"ed25519\",\n    \"usage\": \"short_url_token_verification\"\n  }","operationId":"get_short_url_verify_key_v1_short_url_verify_key_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/f/{token}":{"delete":{"tags":["short-url"],"summary":"Resolve Short Url","description":"Resolve a short URL token to the underlying storage operation.","operationId":"resolve_short_url_f__token__delete","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["short-url"],"summary":"Resolve Short Url","description":"Resolve a short URL token to the underlying storage operation.","operationId":"resolve_short_url_f__token__delete","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"head":{"tags":["short-url"],"summary":"Resolve Short Url","description":"Resolve a short URL token to the underlying storage operation.","operationId":"resolve_short_url_f__token__delete","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["short-url"],"summary":"Resolve Short Url","description":"Resolve a short URL token to the underlying storage operation.","operationId":"resolve_short_url_f__token__delete","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/self-verify":{"get":{"tags":["nukez"],"summary":"Self Verify","description":"Self-verification: proves the running code matches what was attested.\n\nFlow:\n  1. Resolve code attestation pointer (GCS marker or env var)\n  2. Walk SOURCE_DIR, hash every source file\n  3. Build merkle tree (MUST use identical algorithm to compute_fingerprint)\n  4. Fetch stored attestation by receipt_id\n  5. Compare merkle roots\n  6. Return result with all evidence — never contents\n\nReturns:\n  - self_verified: true if roots match\n  - verification: running vs attested roots, file count, bytes\n  - attestation: receipt_id, attested_at, verify_url\n  - switchboard: feed_hash, att_code, on_chain status\n  - mismatched_files: list of files that differ (if any)\n  - independent_verification: three paths to verify without trusting us","operationId":"self_verify_v1_self_verify_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/storage/recompute-verify":{"get":{"summary":"Recompute Verify","description":"Trust Boundary 5 — Independent Attestation Recompute.\n\nRecomputes the merkle root from current locker contents (bypass cache)\nand compares against the persisted attestation object.\n\nNo auth required — this is a public verification endpoint.\n\nReturns:\n    200: { match: bool, computed: \"sha256:...\", stored: \"sha256:...\", ... }\n    400: Missing receipt_id\n    404: Receipt not found\n    409: Locker not ready (no files or no attestation to compare against)","operationId":"recompute_verify_v1_storage_recompute_verify_get","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/auth/challenge":{"post":{"tags":["owner-viewer"],"summary":"Owner Auth Challenge","operationId":"owner_auth_challenge_v1_owner_auth_challenge_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerAuthChallengeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/auth/login":{"post":{"tags":["owner-viewer"],"summary":"Owner Auth Login","operationId":"owner_auth_login_v1_owner_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerAuthLoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/lockers":{"get":{"tags":["owner-viewer"],"summary":"Owner Lockers","operationId":"owner_lockers_v1_owner_lockers_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/files":{"get":{"tags":["owner-viewer"],"summary":"Owner Files","operationId":"owner_files_v1_owner_files_get","parameters":[{"name":"locker_id","in":"query","required":true,"schema":{"type":"string","minLength":1,"title":"Locker Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"include_text","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Text"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/files/viewer-token":{"post":{"tags":["owner-viewer"],"summary":"Owner Viewer Token","operationId":"owner_viewer_token_v1_owner_files_viewer_token_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViewerTokenRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/file/view":{"get":{"tags":["owner-viewer"],"summary":"Owner File View","operationId":"owner_file_view_v1_owner_file_view_get","parameters":[{"name":"locker_id","in":"query","required":true,"schema":{"type":"string","minLength":1,"title":"Locker Id"}},{"name":"filename","in":"query","required":true,"schema":{"type":"string","minLength":1,"title":"Filename"}},{"name":"t","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"T"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/file/text":{"get":{"tags":["owner-viewer"],"summary":"Owner File Text","operationId":"owner_file_text_v1_owner_file_text_get","parameters":[{"name":"locker_id","in":"query","required":true,"schema":{"type":"string","minLength":1,"title":"Locker Id"}},{"name":"filename","in":"query","required":true,"schema":{"type":"string","minLength":1,"title":"Filename"}},{"name":"t","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"T"}},{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/viewer/auth/passkey/register/options":{"post":{"tags":["viewer-auth"],"summary":"Register Options","description":"Generate WebAuthn registration (creation) options.\n\nRequires a valid registration token (Bearer header) obtained from\nPOST /v1/owner/auth/login. The token contains the pubkey that will\nbe bound to the new passkey credential.","operationId":"register_options_v1_viewer_auth_passkey_register_options_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/viewer/auth/passkey/register/complete":{"post":{"tags":["viewer-auth"],"summary":"Register Complete","description":"Complete WebAuthn registration: verify the credential and store it.\n\nStores credential at _meta/passkey_credentials/{b64url_id}.json\nand updates the per-owner reverse index.\nMints an owner session token (same as /v1/owner/auth/login).","operationId":"register_complete_v1_viewer_auth_passkey_register_complete_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterCompleteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/viewer/auth/passkey/login/options":{"post":{"tags":["viewer-auth"],"summary":"Login Options","description":"Generate WebAuthn assertion options for passkey login.\n\nNo auth required. Uses discoverable credentials (empty allowCredentials)\nso the authenticator presents all passkeys registered for this RP.","operationId":"login_options_v1_viewer_auth_passkey_login_options_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/viewer/auth/passkey/login/complete":{"post":{"tags":["viewer-auth"],"summary":"Login Complete","description":"Complete WebAuthn login: verify the assertion and mint a session.\n\nLooks up the credential from _meta/passkey_credentials/{b64url_id}.json,\nextracts the bound pubkey, verifies the assertion with py-webauthn,\nand mints an owner session JWT.","operationId":"login_complete_v1_viewer_auth_passkey_login_complete_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginCompleteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/jobs/finalize-upload":{"post":{"tags":["jobs"],"summary":"Create Finalize Upload","description":"Create and dispatch a persistent upload-finalization job.\n\nJob flow:\n  1) confirm_upload_batch on provided filenames\n  2) optional attestation\n  3) terminal status persisted at /v1/jobs/{job_id}","operationId":"create_finalize_upload_v1_lockers__locker_id__jobs_finalize_upload_post","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizeUploadCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/jobs/{job_id}":{"get":{"tags":["jobs"],"summary":"Get Finalize Upload","description":"Fetch current state for a previously created upload-finalization job.","operationId":"get_finalize_upload_v1_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/upload-sessions":{"post":{"tags":["sandbox-ingest"],"summary":"Start Upload Session","operationId":"start_upload_session_v1_lockers__locker_id__upload_sessions_post","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Execution-Mode","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Execution-Mode"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSessionCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/upload-sessions/{session_id}":{"get":{"tags":["sandbox-ingest"],"summary":"Get Upload Session","operationId":"get_upload_session_v1_upload_sessions__session_id__get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"X-Upload-Token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Upload-Token"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/upload-sessions/{session_id}/files/{file_id}/parts":{"post":{"tags":["sandbox-ingest"],"summary":"Append Upload Session Part","operationId":"append_upload_session_part_v1_upload_sessions__session_id__files__file_id__parts_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}},{"name":"X-Upload-Token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Upload-Token"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxIngestPartRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/upload-sessions/{session_id}/finalize":{"post":{"tags":["sandbox-ingest"],"summary":"Finalize Upload Session","operationId":"finalize_upload_session_v1_upload_sessions__session_id__finalize_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"X-Upload-Token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Upload-Token"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/SandboxIngestCompleteRequest"},{"type":"null"}],"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/upload-sessions/{session_id}/viewer":{"get":{"tags":["sandbox-ingest"],"summary":"Get Upload Session Viewer","operationId":"get_upload_session_viewer_v1_upload_sessions__session_id__viewer_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"filename","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"}},{"name":"X-Upload-Token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Upload-Token"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/viewer":{"get":{"tags":["sandbox-ingest"],"summary":"Get Locker Viewer","operationId":"get_locker_viewer_v1_lockers__locker_id__viewer_get","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"receipt_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Receipt Id"}},{"name":"filename","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/lockers/{locker_id}/ingest/jobs":{"post":{"tags":["sandbox-ingest"],"summary":"Create Ingest Job","operationId":"create_ingest_job_v1_lockers__locker_id__ingest_jobs_post","parameters":[{"name":"locker_id","in":"path","required":true,"schema":{"type":"string","title":"Locker Id"}},{"name":"X-Nukez-Execution-Mode","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Execution-Mode"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxIngestCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ingest/jobs/{job_id}/files/{file_id}/parts":{"post":{"tags":["sandbox-ingest"],"summary":"Upload Ingest Part","operationId":"upload_ingest_part_v1_ingest_jobs__job_id__files__file_id__parts_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxIngestPartRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ingest/jobs/{job_id}/complete":{"post":{"tags":["sandbox-ingest"],"summary":"Complete Ingest Job","operationId":"complete_ingest_job_v1_ingest_jobs__job_id__complete_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"X-Nukez-Envelope","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Envelope"}},{"name":"X-Nukez-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Nukez-Signature"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/SandboxIngestCompleteRequest"},{"type":"null"}],"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/r/{receipt_id}/f/{filename}":{"get":{"tags":["public-file"],"summary":"Public File Proxy","description":"Serve file content using receipt_id as auth.\n\nThis is the stable, non-expiring alternative to short URL tokens.\nThe receipt_id proves locker ownership — if you have it, you can\naccess the files.\n\nPass ?download=1 to force attachment disposition (triggers browser\ndownload even for images, PDFs, and other inline-viewable types).\n\nResponse includes proper CORS headers (via middleware), Content-Type,\nand Content-Disposition.","operationId":"public_file_proxy_v1_r__receipt_id__f__filename__get","parameters":[{"name":"receipt_id","in":"path","required":true,"schema":{"type":"string","title":"Receipt Id"}},{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}},{"name":"download","in":"query","required":false,"schema":{"type":"boolean","description":"Force Content-Disposition: attachment for browser download","default":false,"title":"Download"},"description":"Force Content-Disposition: attachment for browser download"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/storage/verification-bundle":{"get":{"summary":"Verification Bundle","description":"Self-contained verification bundle for a receipt.\n\nReturns everything needed to independently verify data integrity:\n  - Payment proof with Solana explorer link\n  - Content proof (merkle root, file manifest with download URLs)\n  - On-chain anchor (Switchboard tx/feed with explorer links)\n  - Merkle algorithm specification (formal, machine-readable)\n  - DIY verification steps and endpoint links\n\nNo auth required — verification is permissionless.","operationId":"verification_bundle_v1_storage_verification_bundle_get","parameters":[{"name":"receipt_id","in":"query","required":true,"schema":{"type":"string","title":"Receipt Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AddOperatorRequest":{"properties":{"pubkey":{"type":"string","maxLength":64,"minLength":1,"title":"Pubkey"}},"type":"object","required":["pubkey"],"title":"AddOperatorRequest"},"AttestRequest":{"properties":{"receipt_id":{"type":"string","title":"Receipt Id"},"push":{"type":"boolean","title":"Push","default":false}},"type":"object","required":["receipt_id"],"title":"AttestRequest"},"BatchCreateFileItem":{"properties":{"filename":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Filename"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"expected_hash":{"anyOf":[{"type":"string","maxLength":128,"minLength":1},{"type":"null"}],"title":"Expected Hash","description":"Optional sha256 precommit hash (with or without 'sha256:' prefix)"}},"type":"object","title":"BatchCreateFileItem","description":"Single file spec for batch URL creation."},"BatchCreateFileRequest":{"properties":{"files":{"items":{"$ref":"#/components/schemas/BatchCreateFileItem"},"type":"array","maxItems":100,"minItems":1,"title":"Files","description":"Files to create and mint upload/download URLs for"},"ttl_min":{"anyOf":[{"type":"integer","maximum":1440.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Min","description":"Signed URL lifetime in minutes (default: 30)","default":30}},"type":"object","required":["files"],"title":"BatchCreateFileRequest","description":"Request body for batch create_file operation."},"BatchUrlsRequest":{"properties":{"filenames":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":1,"title":"Filenames","description":"List of filenames to generate download URLs for"},"ttl_min":{"anyOf":[{"type":"integer","maximum":1440.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Min","description":"Signed URL lifetime in minutes (default: 30)","default":30}},"type":"object","required":["filenames"],"title":"BatchUrlsRequest","description":"Request body for batch download URL generation."},"BridgeRetryRequest":{"properties":{"receipt_id":{"type":"string","title":"Receipt Id"},"attestation_type":{"type":"string","title":"Attestation Type"},"attempt":{"type":"integer","title":"Attempt","default":0}},"type":"object","required":["receipt_id","attestation_type"],"title":"BridgeRetryRequest"},"CreateFileRequest":{"properties":{"filename":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Filename"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"ttl_min":{"anyOf":[{"type":"integer","maximum":1440.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Min"}},"type":"object","title":"CreateFileRequest","description":"Request body for create_file.\n\nNotes:\n  - filename is optional (server can auto-generate).\n  - ttl_min controls the signed URL lifetime."},"FetchAndStoreRequest":{"properties":{"source_url":{"type":"string","title":"Source Url","description":"HTTPS URL to fetch content from"},"filename":{"type":"string","maxLength":255,"minLength":1,"title":"Filename"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type","description":"MIME type (auto-inferred from filename if not provided)"}},"type":"object","required":["source_url","filename"],"title":"FetchAndStoreRequest","description":"Request body for fetch-and-store (URL mode upload)."},"FinalizeUploadCreateRequest":{"properties":{"receipt_id":{"type":"string","minLength":1,"title":"Receipt Id","description":"Receipt ID bound to the locker"},"filenames":{"items":{"type":"string"},"type":"array","maxItems":1000,"minItems":1,"title":"Filenames","description":"Filenames to confirm and finalize in one async job"},"auto_attest":{"type":"boolean","title":"Auto Attest","description":"If true, run attestation after confirm-batch completes","default":false},"attest_sync":{"type":"boolean","title":"Attest Sync","description":"Reserved for compatibility; currently attestation runs synchronously inside the worker","default":false},"push_attestation":{"type":"boolean","title":"Push Attestation","description":"If true and auto_attest=true, push attestation on-chain","default":false},"run_inline":{"type":"boolean","title":"Run Inline","description":"Run job immediately in request thread (debug/dev only)","default":false}},"type":"object","required":["receipt_id","filenames"],"title":"FinalizeUploadCreateRequest"},"FinalizeUploadJobRequest":{"properties":{"job_id":{"type":"string","title":"Job Id"}},"type":"object","required":["job_id"],"title":"FinalizeUploadJobRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LoginCompleteRequest":{"properties":{"challenge_token":{"type":"string","minLength":10,"title":"Challenge Token"},"id":{"type":"string","minLength":1,"title":"Id"},"rawId":{"type":"string","minLength":1,"title":"Rawid"},"response":{"additionalProperties":true,"type":"object","title":"Response"},"type":{"type":"string","title":"Type","default":"public-key"}},"type":"object","required":["challenge_token","id","rawId","response"],"title":"LoginCompleteRequest"},"OwnerAuthChallengeRequest":{"properties":{"pubkey":{"type":"string","maxLength":64,"minLength":32,"title":"Pubkey"}},"type":"object","required":["pubkey"],"title":"OwnerAuthChallengeRequest"},"OwnerAuthLoginRequest":{"properties":{"pubkey":{"type":"string","maxLength":64,"minLength":32,"title":"Pubkey"},"challenge":{"type":"string","maxLength":128,"minLength":16,"title":"Challenge"},"signature":{"type":"string","minLength":64,"title":"Signature"},"sig_alg":{"type":"string","title":"Sig Alg","default":"ed25519"}},"type":"object","required":["pubkey","challenge","signature"],"title":"OwnerAuthLoginRequest"},"PaymentAttestRequest":{"properties":{"receipt_id":{"type":"string","title":"Receipt Id"}},"type":"object","required":["receipt_id"],"title":"PaymentAttestRequest"},"ProvisionRequest":{"properties":{"receipt_id":{"type":"string","minLength":1,"title":"Receipt Id"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"operator_pubkey":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operator Pubkey"}},"type":"object","required":["receipt_id"],"title":"ProvisionRequest"},"RefreshRequest":{"properties":{"locker_id":{"type":"string","minLength":1,"title":"Locker Id"}},"type":"object","required":["locker_id"],"title":"RefreshRequest"},"RegisterCompleteRequest":{"properties":{"challenge_token":{"type":"string","minLength":10,"title":"Challenge Token"},"id":{"type":"string","minLength":1,"title":"Id"},"rawId":{"type":"string","minLength":1,"title":"Rawid"},"response":{"additionalProperties":true,"type":"object","title":"Response"},"type":{"type":"string","title":"Type","default":"public-key"}},"type":"object","required":["challenge_token","id","rawId","response"],"title":"RegisterCompleteRequest"},"SandboxIngestCompleteRequest":{"properties":{"file_ids":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":100},{"type":"null"}],"title":"File Ids"}},"type":"object","title":"SandboxIngestCompleteRequest"},"SandboxIngestCreateRequest":{"properties":{"receipt_id":{"type":"string","minLength":1,"title":"Receipt Id"},"files":{"items":{"$ref":"#/components/schemas/SandboxIngestFileSpec"},"type":"array","maxItems":100,"minItems":1,"title":"Files"},"execution_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Execution Mode","description":"Must be 'sandbox' for this endpoint"}},"type":"object","required":["receipt_id","files"],"title":"SandboxIngestCreateRequest"},"SandboxIngestFileSpec":{"properties":{"filename":{"type":"string","maxLength":255,"minLength":1,"title":"Filename"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"expected_size_bytes":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Expected Size Bytes"},"expected_sha256":{"anyOf":[{"type":"string","maxLength":71,"minLength":64},{"type":"null"}],"title":"Expected Sha256"}},"type":"object","required":["filename"],"title":"SandboxIngestFileSpec"},"SandboxIngestPartRequest":{"properties":{"part_no":{"type":"integer","minimum":0.0,"title":"Part No"},"payload_b64":{"type":"string","minLength":1,"title":"Payload B64"},"is_last":{"type":"boolean","title":"Is Last","default":false}},"type":"object","required":["part_no","payload_b64"],"title":"SandboxIngestPartRequest"},"UploadSessionCreateRequest":{"properties":{"receipt_id":{"type":"string","minLength":1,"title":"Receipt Id"},"files":{"items":{"$ref":"#/components/schemas/SandboxIngestFileSpec"},"type":"array","maxItems":100,"minItems":1,"title":"Files"},"execution_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Execution Mode","description":"Must be 'sandbox' for this endpoint","default":"sandbox"},"upload_token_ttl_sec":{"anyOf":[{"type":"integer","maximum":86400.0,"minimum":60.0},{"type":"null"}],"title":"Upload Token Ttl Sec"}},"type":"object","required":["receipt_id","files"],"title":"UploadSessionCreateRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"ViewerTokenRequest":{"properties":{"locker_id":{"type":"string","minLength":1,"title":"Locker Id"},"filename":{"type":"string","maxLength":255,"minLength":1,"title":"Filename"},"ttl_minutes":{"type":"integer","maximum":120.0,"minimum":1.0,"title":"Ttl Minutes","default":30}},"type":"object","required":["locker_id","filename"],"title":"ViewerTokenRequest"}}}}