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 security: - AppSession: [] paths: /marketplace/offers: get: summary: List active offers (launcher/app surface) 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: securitySchemes: AppSession: type: http scheme: bearer bearerFormat: EDUT-APP-SESSION 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, internal_use_only, multi_tenant] properties: member_only: type: boolean workspace_bound: type: boolean transferable: type: boolean internal_use_only: type: boolean multi_tenant: 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 org_root_id: type: string description: Economic boundary identifier for suite entitlement checks. principal_id: type: string description: Human principal requesting checkout. principal_role: type: string enum: [workspace_member, org_root_owner] workspace_id: type: string ownership_proof: type: string description: Optional ownership-wallet signature proving entitlement recipient approval when payer differs. include_membership_if_missing: type: boolean default: true description: If true, quote may bundle first-time membership fee into total. CheckoutQuoteResponse: type: object required: [quote_id, wallet, offer_id, currency, amount_atomic, total_amount_atomic, policy_hash, expires_at] properties: quote_id: type: string wallet: type: string payer_wallet: type: string offer_id: type: string org_root_id: type: string principal_id: type: string principal_role: type: string enum: [workspace_member, org_root_owner] currency: type: string amount: type: string amount_atomic: type: string description: License amount component only. total_amount: type: string description: Total payable amount for this checkout quote. total_amount_atomic: type: string decimals: type: integer membership_activation_included: type: boolean line_items: type: array items: $ref: '#/components/schemas/QuoteLineItem' policy_hash: type: string expires_at: type: string format: date-time tx: type: object additionalProperties: true access_class: type: string enum: [connected, sovereign] availability_state: type: string enum: [active, grace, continuity, parked] QuoteLineItem: type: object required: [kind, amount_atomic, decimals, currency, label] properties: kind: type: string enum: [license, membership, network_estimate] label: type: string amount: type: string amount_atomic: type: string decimals: type: integer currency: type: string 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 org_root_id: type: string principal_id: type: string principal_role: type: string enum: [workspace_member, org_root_owner] workspace_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 org_root_id: type: string principal_id: type: string principal_role: type: string enum: [workspace_member, org_root_owner] wallet: type: string tx_hash: type: string policy_hash: type: string activated_at: type: string format: date-time access_class: type: string enum: [connected, sovereign] availability_state: type: string enum: [active, grace, continuity, parked] 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 org_root_id: type: string state: type: string enum: [active, suspended, revoked, expired] access_class: type: string enum: [connected, sovereign] availability_state: type: string enum: [active, grace, continuity, parked] policy_hash: type: string issued_at: type: string format: date-time