Events & Discount-Coupon Ticketing
Use the Event402 API from a regular ticket buyer's perspective: browse events, mine the event descriptions for any discount activities or coupon codes, validate the coupon, then place the order at the discounted price and pay.
Dependencies
This skill depends on FluxA Agent Wallet.
Make sure the FluxA Agent Wallet skill and CLI are installed:
Installation: Read and install https://fluxapay.xyz/skill.md
- CLI:
@fluxa-pay/fluxa-wallet≥ 0.4.5 (theagent-vcsubcommand is required) - Identity: the agent has been
init'd andlink-wallet'd (confirm withfluxa-wallet status/check-wallet) - If it's missing or the version is too old, follow the
fluxa-agent-walletskill to install it first, then come back.
API base: https://event402.up.railway.app
Authentication (per session / after expiry)
All /v1/* endpoints require a Bearer VC. Mint a short-lived VC for Event402:
fluxa-wallet agent-vc \
--audience urn:event402:api \
--challenge event402 \
--ttl 3600--audiencemust beurn:event402:api, otherwise it will be rejected.--challengeis not validated server-side — just passevent402.--ttlis at most 86400; 3600 is recommended. Re-mint when it expires.
Save the returned vc into an env var so later curl calls can reference it directly:
export E402_VC="<paste the returned vc here>"If a/v1/*call returns401 / Missing or invalid Authorization header, the VC has expired or is missing — re-mint it.
Main Flow (discount-ticketing perspective)
1. Browse the event list
curl -sL https://event402.up.railway.app/v1/events \
-H "Authorization: Bearer $E402_VC" | jq .Returns {events: [{id, title, venue, eventTime, priceUsdc, remaining, description, imageUrl}]}.
When presenting the list to the user, highlight: title, venue, time, original price (USDC), and remaining tickets.
2. Event detail & mining discount hints ⭐
This is the core step of the skill.
curl -sL https://event402.up.railway.app/v1/events/<EVENT_ID> \
-H "Authorization: Bearer $E402_VC" | jq .On Event402, the organizer writes the discount activities into the description field. When reading description, actively look for:
- Whether the description mentions any extra discount activity, and if so, how to participate.
- Possible participation methods: sometimes the user must do something first (follow, repost, fill out a form) to obtain a code — if it's this kind of "do an action to earn a code" activity, tell the user clearly and ask them to paste back whatever code they receive.
Quote the candidate coupon codes / activity rules back to the user verbatim, then move on to validation. If description has no discount hint at all, just tell the user "no discount activity found for this show".
3. Validate the coupon (preview discount before ordering)
Once you have a candidate code, preview first, then order:
curl -sL -X POST https://event402.up.railway.app/v1/events/coupons/check \
-H "Authorization: Bearer $E402_VC" \
-H "Content-Type: application/json" \
-d '{
"code": "SHOW50",
"eventId": "<EVENT_ID>",
"estimatedTotal": <quantity * priceUsdc>
}' | jq .codeis requiredeventIdis strongly recommendedestimatedTotal=quantity × priceUsdc(USDC); passing it gets you an accurateestimatedDiscount
Reading the response:
{valid: true, type: "percent"|"fixed", value, maxDiscount, minOrder, eventId, estimatedDiscount}— valid. Focus onestimatedDiscount(how much this particular order will save) andminOrder(the coupon is void under this threshold).{valid: false, error}— relayerrorto the user verbatim (expired / usage cap reached / not applicable to this event / below min order, etc.). Don't force it.
Show the discounted price to the user: priceBeforeCoupon = quantity × priceUsdc, afterDiscount = priceBeforeCoupon - estimatedDiscount. If value ≥ ticket price (100% percent or a large-enough fixed amount), tell the user "with this coupon the ticket is free — the order will go straight to paid with no payment step".
4. Place the order
Only place the order after the user agrees to the discounted price:
curl -sL -X POST https://event402.up.railway.app/v1/events/<EVENT_ID>/orders \
-H "Authorization: Bearer $E402_VC" \
-H "Content-Type: application/json" \
-d '{
"quantity": 1,
"couponCode": "SHOW50",
"contactName": "<optional>",
"contactEmail": "<optional>"
}' | jq .Returns: {orderId, eventId, title, quantity, totalPrice, currency: "USDC", paymentUrl, status, coupon?: {code, discount, priceBeforeCoupon}}
status = "paid"— the coupon covered the full price, no payment needed. Skip to step 6.status = "pending_payment"— go to step 5 to pay.
One coupon per order; each coupon usually has a per-agent usage limit of 1. Don't retry the same coupon over and over.
5. Pay
Open paymentUrl and pay in USDC with the FluxA Wallet (x402, zero gas). See X402-PAYMENT.md in the fluxa-agent-wallet skill for the detailed x402 flow.
After paying, tell the backend to finalize:
curl -sL -X POST https://event402.up.railway.app/v1/events/orders/<ORDER_ID>/complete-payment \
-H "Authorization: Bearer $E402_VC" | jq .{status: "paid", orderId}— success{error: "Payment not yet received", paymentUrl}— the chain hasn't confirmed yet; wait a few seconds and call again. Don't spam the endpoint.
6. Confirm final order state
curl -sL https://event402.up.railway.app/v1/events/orders/<ORDER_ID> \
-H "Authorization: Bearer $E402_VC" | jq .Give the user a receipt-style summary: event title / venue / time / quantity / priceBeforeCoupon / couponDiscount / totalPrice / status.
7. (Optional) Order history
curl -sL https://event402.up.railway.app/v1/events/orders \
-H "Authorization: Bearer $E402_VC" | jq .Discount-hunting rules of thumb
- Don't invent coupon codes. Only three sources are trustworthy: ① the code is explicitly written in the event
description; ② the user pasted the code themselves; ③ the code has passedcoupons/check. Ifdescriptiondoesn't mention one, just say so. - Preview before ordering.
coupons/checkis free — use it to confirmvalid:trueandestimatedDiscount > 0before you hold inventory. - Always include the
eventIdscope. The same code may only be valid for one event; cross-event usage will come backvalid:false. - Remind the user about
minOrder. IfminOrder > estimatedTotal, suggest either "buy an extra ticket to cross the threshold" or "skip the coupon" and let the user choose. - One coupon per order, limited usage per agent. Don't try to stack or reuse coupons. If rejected, surface the original error.
- Prices are in USDC — don't convert to fiat and mislead the user. You may add a rough USD note as an aside.
Sample phrasing for the user
- "The *XX Concert* is 50 USDC/ticket. The description lists an early-bird code
EARLYBIRD20— 20% off on orders of 40 USDC+. Let me validate it first." - "Validated: 1 ticket, original 50 USDC, discounted to ~40 USDC, saving 10 USDC. Want me to place the order?"
- "I didn't see any discount activity in the description. If you have another code I can validate it for you; otherwise I'll order at the list price."
- "The coupon you pasted came back
valid:false: coupon expired— it's no longer usable. Want me to recheck the description for another code?"
Don'ts
- Don't place orders or pay on the user's behalf — confirm with the user before every step. Ordering holds inventory; paying spends USDC. Both are irreversible.
- Don't "guess" a code and brute-force it (e.g. blindly trying
TEST10/SHOW50) when the description mentions no discount — it wastes API calls and can make the user believe an activity exists that doesn't. - Don't mix flight coupons with event coupons — they live in separate namespaces.