openapi: 3.0.3 info: title: EDUT Marketplace API version: v1 description: Membership-gated offer and entitlement commerce endpoints. servers: - url: https://api.edut.ai paths: /marketplace/offers: get: summary: List active offers responses: '200': description: Offer list content: application/json: schema: type: object required: [offers] properties: offers: type: array items: $ref: '#/components/schemas/Offer' /marketplace/offers/{offer_id}: get: summary: Get offer by id parameters: - in: path name: offer_id required: true schema: type: string responses: '200': description: Offer record content: application/json: schema: $ref: '#/components/schemas/Offer' '404': description: Not found /marketplace/checkout/quote: post: summary: Create checkout quote (membership required) requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CheckoutQuoteRequest' responses: '200': description: Quote created content: application/json: schema: $ref: '#/components/schemas/CheckoutQuoteResponse' '403': description: Membership not active /marketplace/checkout/confirm: post: summary: Confirm checkout transaction and mint entitlement requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CheckoutConfirmRequest' responses: '200': description: Entitlement active content: application/json: schema: $ref: '#/components/schemas/CheckoutConfirmResponse' /marketplace/entitlements: get: summary: List entitlements for wallet parameters: - in: query name: wallet required: true schema: type: string pattern: '^0x[a-fA-F0-9]{40}$' responses: '200': description: Entitlements list content: application/json: schema: type: object required: [entitlements] properties: entitlements: type: array items: $ref: '#/components/schemas/Entitlement' components: schemas: Offer: type: object required: [offer_id, issuer_id, title, status, pricing, policies] properties: offer_id: type: string issuer_id: type: string title: type: string summary: type: string status: type: string enum: [draft, active, paused, retired] pricing: type: object required: [currency, amount_atomic, decimals] properties: currency: type: string enum: [USDC, ETH] amount_atomic: type: string decimals: type: integer chain_id: type: integer policies: type: object required: [member_only, workspace_bound, transferable] properties: member_only: type: boolean workspace_bound: type: boolean transferable: type: boolean CheckoutQuoteRequest: type: object required: [wallet, offer_id] properties: wallet: type: string pattern: '^0x[a-fA-F0-9]{40}$' description: Ownership wallet that will receive entitlement. payer_wallet: type: string pattern: '^0x[a-fA-F0-9]{40}$' description: Optional wallet paying the quote transaction when different from ownership wallet. offer_id: type: string workspace_id: type: string ownership_proof: type: string description: Optional ownership-wallet signature proving entitlement recipient approval when payer differs. CheckoutQuoteResponse: type: object required: [quote_id, wallet, offer_id, currency, amount_atomic, policy_hash, expires_at] properties: quote_id: type: string wallet: type: string payer_wallet: type: string offer_id: type: string currency: type: string amount: type: string amount_atomic: type: string decimals: type: integer policy_hash: type: string expires_at: type: string format: date-time tx: type: object additionalProperties: true CheckoutConfirmRequest: type: object required: [quote_id, wallet, offer_id, tx_hash, chain_id] properties: quote_id: type: string wallet: type: string pattern: '^0x[a-fA-F0-9]{40}$' description: Ownership wallet bound to entitlement. payer_wallet: type: string pattern: '^0x[a-fA-F0-9]{40}$' description: Optional payment wallet for tx provenance when different from ownership wallet. offer_id: type: string tx_hash: type: string pattern: '^0x[a-fA-F0-9]{64}$' chain_id: type: integer CheckoutConfirmResponse: type: object required: [status, entitlement_id, offer_id, wallet, tx_hash] properties: status: type: string enum: [entitlement_active] entitlement_id: type: string offer_id: type: string wallet: type: string tx_hash: type: string policy_hash: type: string activated_at: type: string format: date-time Entitlement: type: object required: [entitlement_id, offer_id, wallet_address, state] properties: entitlement_id: type: string offer_id: type: string wallet_address: type: string workspace_id: type: string state: type: string enum: [active, suspended, revoked, expired] policy_hash: type: string issued_at: type: string format: date-time