{"openapi":"3.1.0","info":{"title":"ActSeal","version":"0.1.7","description":"Signed action receipts for agents. Best-effort Ed25519 log — not legal evidence. Free: 100/API-key/UTC-day. Starter: $19/mo crypto (USDC/USDT/ETH) → 500/day. Keys via hello@actseal.xyz. See https://actseal.xyz/pricing and https://actseal.xyz/pay."},"servers":[{"url":"https://actseal.xyz"}],"paths":{"/v1/receipt":{"post":{"operationId":"issueReceipt","summary":"Issue a signed receipt for an agent action","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Same key+body within 24h returns the same receipt_id (200 + idempotent_replay). Same key + different body → 409. Does not consume quota on replay.","schema":{"type":"string","maxLength":128,"pattern":"^[\\w.:\\-+=/]{1,128}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action","inputs_hash","outputs_hash"],"properties":{"action":{"type":"string","maxLength":256},"inputs_hash":{"type":"string","pattern":"^[a-fA-F0-9]{64}$"},"outputs_hash":{"type":"string","pattern":"^[a-fA-F0-9]{64}$"},"policy_id":{"type":"string","maxLength":128,"nullable":true}}}}}},"responses":{"200":{"description":"Idempotent replay of prior receipt"},"201":{"description":"Signed receipt (new); includes embedded public_key"},"400":{"description":"Invalid body or Idempotency-Key"},"401":{"description":"Missing/invalid API key"},"409":{"description":"Idempotency-Key reused with different body"},"413":{"description":"Payload too large (max 16 KiB)"},"429":{"description":"Quota exhausted. Body includes payment.pay_url (https://actseal.xyz/pay) for crypto upgrade (USDC/USDT/ETH, $19/mo Starter)."},"503":{"description":"SIGNING_SEED unset and ALLOW_DEV_KEY≠1"}}}},"/v1/verify/{id}":{"get":{"operationId":"verifyReceipt","summary":"Verify a receipt by id (public); uses embedded public_key","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verification result"},"404":{"description":"Not found"}}}},"/v1/gate/session":{"post":{"operationId":"createGateSession","summary":"Create a Gate session (x402Gate lite) — pending until settle","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["resource"],"properties":{"resource":{"type":"string","maxLength":256,"description":"Label/path only — never an http(s) URL; ActSeal does not fetch it"},"price_usd":{"type":"number","minimum":0},"currency":{"type":"string","maxLength":16,"default":"USDC"},"unlock":{"description":"JSON returned after settle (max ~8 KiB serialized)"},"policy_id":{"type":"string","maxLength":128,"nullable":true}}}}}},"responses":{"201":{"description":"Pending session with challenge_url + settle_url"},"400":{"description":"Invalid body / resource"},"401":{"description":"Missing/invalid API key"}}}},"/v1/gate/{id}":{"get":{"operationId":"getGateSession","summary":"Challenge (402) or unlocked session with receipt","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Settled — unlock is PUBLIC (anyone with session_id) + Seal receipt"},"402":{"description":"Payment required — free_tier|mock owner attest (NOT on-chain)"},"404":{"description":"Not found"},"410":{"description":"Session expired"}}}},"/v1/gate/{id}/settle":{"post":{"operationId":"settleGateSession","summary":"Settle Gate session: free_tier (price_usd=0) or mock (owner attest, NOT on-chain) + Seal","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","enum":["free_tier","mock"]}}}}}},"responses":{"200":{"description":"Settled + signed receipt (action=gate.unlock)"},"400":{"description":"Invalid mode"},"401":{"description":"Unauthorized"},"403":{"description":"Not session owner"},"404":{"description":"Not found"},"410":{"description":"Expired"},"429":{"description":"Receipt quota exhausted (settle counts as a Seal)"}}}},"/v1/pass":{"post":{"operationId":"issuePass","summary":"Issue a time-boxed signed access pass (PassGate lite) + Seal","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["scope"],"properties":{"scope":{"type":"string","maxLength":256,"description":"Label/path only — never an http(s) URL"},"max_calls":{"type":"integer","minimum":1,"maximum":1000,"default":10},"ttl_seconds":{"type":"integer","minimum":1,"maximum":86400,"default":3600},"expires_at":{"type":"string","format":"date-time","description":"ISO-8601; alt to ttl_seconds"},"policy_id":{"type":"string","maxLength":128,"nullable":true}}}}}},"responses":{"201":{"description":"Pass issued + Seal (action=pass.issue); consumes Seal quota"},"400":{"description":"Invalid body / scope"},"401":{"description":"Missing/invalid API key"},"429":{"description":"Receipt quota exhausted"}}},"get":{"operationId":"checkPassHeader","summary":"Check pass via Authorization: Pass <id> or X-ActSeal-Pass (preferred — no id in URL)","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"type":"string"},"description":"Pass <pass_id>"},{"name":"X-ActSeal-Pass","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Status (valid|expired|exhausted|revoked)"},"400":{"description":"Missing pass id header"},"404":{"description":"Not found"}}}},"/v1/pass/consume":{"post":{"operationId":"consumePassHeader","summary":"Burn one call via Pass header (preferred)","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"type":"string"},"description":"Pass <pass_id>"},{"name":"X-ActSeal-Pass","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Consumed"},"400":{"description":"Missing pass id"},"403":{"description":"Exhausted or revoked"},"404":{"description":"Not found"},"410":{"description":"Expired"}}}},"/v1/pass/{id}":{"get":{"operationId":"checkPass","summary":"Check pass by path id (legacy — prefer header)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Status (valid|expired|exhausted|revoked)"},"404":{"description":"Not found"}}}},"/v1/pass/{id}/consume":{"post":{"operationId":"consumePass","summary":"Atomic burn one call by path id (legacy — prefer header)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Consumed; returns calls_remaining"},"403":{"description":"Exhausted or revoked"},"404":{"description":"Not found"},"410":{"description":"Expired"}}}},"/v1/pass/{id}/revoke":{"post":{"operationId":"revokePass","summary":"Owner revoke (Bearer) — status=revoked","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Revoked"},"401":{"description":"Unauthorized"},"404":{"description":"Not found or not owner"}}}},"/v1/pubkey":{"get":{"operationId":"getPubkey","summary":"Current issuer Ed25519 public key","responses":{"200":{"description":"Public key"},"503":{"description":"SIGNING_SEED unset and ALLOW_DEV_KEY≠1"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API key"}}}}