# Event402 > Event ticket sales API for AI agents. Browse concerts, shows, and other events, then buy tickets using USDC payments via the FluxA x402 protocol. ## Prerequisites Before using this API, you must install the **FluxA Agent Wallet skill (≥ 0.4.5)** and the **`fluxa-wallet` CLI (≥ 0.4.5)**. Older versions do not support the `agent-vc` subcommand that this API requires for authentication. Read and install the skill from: https://fluxapay.xyz/skill.md This gives you an `agent_id`, a FluxA Wallet for USDC payments via the x402 protocol, and the ability to mint short-lived Agent Verifiable Credentials (VCs) for third-party services like Event402. Verify your CLI version: ``` fluxa-wallet --version # must be >= 0.4.5 ``` ## Authentication All `/v1/*` endpoints require a **FluxA Agent Verifiable Credential (VC)**. A VC is scoped by `typ=agent-vc`, `aud`, `challenge`, and short `exp`, so it is safe to hand to third-party services. Mint a VC bound to this API with the FluxA wallet CLI: ``` fluxa-wallet agent-vc \ --audience urn:event402:api \ --challenge event402 \ --ttl 3600 ``` - `--audience` **must** be `urn:event402:api`; VCs with any other audience are rejected. - `--challenge` is required by the CLI but the service does not validate it — pass any non-empty string (the example above uses the literal `event402`). - `--ttl` is seconds; max 86400. A short TTL (e.g. 3600) is recommended — re-mint when it expires. Send the returned `vc` in the Authorization header: ``` Authorization: Bearer ``` The service verifies the VC locally against FluxA's JWKS (`https://agentid.fluxapay.xyz/.well-known/jwks.json`): RS256 signature, `typ=agent-vc` header, `aud=urn:event402:api`, and unexpired `exp`. The verified agent id is taken from the VC's `sub` claim. ## API Endpoints ### List Events `GET /v1/events` Browse the public catalog of active events. Sold-out and inactive events are hidden. Response: `{ events: [{ id, title, venue, eventTime, priceUsdc, remaining, description, imageUrl }] }` ### Get Event Detail `GET /v1/events/{id}` Fetch a single event's detail. Response: `{ id, title, venue, eventTime, priceUsdc, remaining, description, imageUrl }` ### Check Coupon `POST /v1/events/coupons/check` Preview an event coupon before ordering. Request body: - `code` (string, required): Coupon code, e.g. "SHOW50" - `eventId` (string, optional): If the coupon is scoped to a specific event, pass the event id to validate the scope - `estimatedTotal` (number, optional): Estimated order total in USDC for an accurate discount preview Response: `{ valid: true, code, type: "fixed"|"percent", value, maxDiscount, minOrder, eventId, estimatedDiscount }` or `{ valid: false, error }` ### Purchase Tickets `POST /v1/events/{id}/orders` Buy tickets for an event. Quota is reserved atomically. If a coupon fully covers the price, the order is marked paid immediately and no payment link is created. Request body: - `quantity` (integer, required): Number of tickets (must be >= 1) - `couponCode` (string, optional): Coupon code for discount - `contactName` (string, optional): Contact name for the order - `contactEmail` (string, optional): Contact email for the order Response: `{ orderId, eventId, title, quantity, totalPrice, currency: "USDC", paymentUrl, status, coupon?: { code, discount, priceBeforeCoupon } }` When `status` is `pending_payment`, open `paymentUrl` and pay with your FluxA Wallet. When `status` is `paid` (coupon covered the full price), no payment is needed. ### Complete Payment `POST /v1/events/orders/{orderId}/complete-payment` Call this after paying the `paymentUrl` from the order response. The system verifies your USDC payment was received and flips the order to `paid`. Response: `{ status: "paid", orderId }` on success, or `{ error: "Payment not yet received", paymentUrl }` if payment has not arrived. ### Query Order `GET /v1/events/orders/{orderId}` Check order status and details. Response: `{ orderId, status, eventId, eventTitle, eventVenue, eventTime, quantity, unitPriceUsdc, priceBeforeCoupon, couponDiscount, totalPrice, currency, paymentUrl?, contactName, contactEmail, createdAt }` `paymentUrl` is included only when `status` is `pending_payment`. Order statuses: `pending_payment` → `paid` ### List My Orders `GET /v1/events/orders` List the calling agent's event orders, newest first. Response: `{ orders: [{ orderId, eventId, quantity, totalPrice, currency, status, createdAt }] }` ## Coupons Coupon rules: - One coupon per order - Each coupon has a per-agent usage limit (typically 1) - Coupons have a total quota, optional validity window, and optional minimum order amount - Coupons may be scoped to a specific event (non-null `eventId`) or apply to all events - Event coupons are a separate namespace from flight coupons — the same code may exist on both services without collision - Setting type=percent with value=100, or type=fixed with value >= the ticket price, makes tickets effectively free (the order is auto-marked `paid` with no payment link) ## Discount Promotions A bulletin board where the platform announces ongoing discount campaigns and the coupon codes they hand out. Browsing is purely informational — to claim a discount, take the coupon code from a promotion's `description` and apply it via `POST /v1/events/coupons/check` and `POST /v1/events/{id}/orders`. ### List Promotions `GET /v1/promotions` Query parameters: - `scope` (string, optional, default `current`): `current` returns only promotions whose start/end window covers right now; `upcoming` also includes ones that haven't started yet; `all` includes already-expired entries. Response: `{ promotions: [{ id, title, description, startsAt, endsAt, active }] }` ### Get Promotion Detail `GET /v1/promotions/{id}` Response: `{ id, title, description, startsAt, endsAt, active }` ## Typical Flow 1. `GET /v1/events` — browse upcoming events 2. (Optional) `GET /v1/events/{id}` — view detail 3. (Optional) `POST /v1/events/coupons/check` — verify a coupon 4. `POST /v1/events/{id}/orders` — create the order and receive `paymentUrl` 5. Pay USDC at the `paymentUrl` using your FluxA Wallet (skip if `status` was already `paid`) 6. `POST /v1/events/orders/{orderId}/complete-payment` — confirm payment 7. `GET /v1/events/orders/{orderId}` — verify final status ## Payment All prices are in USDC. Payments use FluxA Payment Links: - When you create an order with a non-zero total, you receive a `paymentUrl` - Open the URL and pay with your FluxA Wallet (x402 protocol, zero gas fees) - After payment, call `complete-payment` to confirm ## Admin API Platform admins can manage events, event coupons, and admin users via the Admin API. See: `GET /admin/llms.txt`