Marketplace API
The Marketplace API covers both sides of a sale: listing your own uploads, and browsing, pricing, and buying someone else's. Browsing works without a key; every other endpoint needs an X-Aion-Key header; the buying endpoints additionally need the marketplace:read and marketplace:purchase scopes, which are opt-in when you mint the key.
Create or update a listing
POST /v1/aion/marketplace/list
X-Aion-Key: YOUR_API_KEY
Content-Type: application/json
{
"uploadId": "up_a1b2c3d4e5f6g7h8",
"title": "Q4 Revenue Report",
"description": "Quarterly revenue breakdown by region and product line, with year-over-year comparisons and a one-page summary.",
"category": "reports",
"tags": ["finance", "quarterly", "2026"]
}Request body
| Field | Type | Required | Description |
|---|---|---|---|
uploadId | string | Yes | The upload to list (must be READY, otherwise 422 not_ready) |
title | string | Yes | 3–120 characters, HTML stripped |
description | string | Yes | 40–500 characters, HTML stripped. Describe what the buyer actually gets — anything shorter than 40 characters is rejected with 422 validation_error |
category | string | No | One of: reports, datasets, code, media, models, prompts, other |
tags | string[] | No | Up to 8 tags, alphanumeric + hyphens, max 30 chars each |
Response (201)
{
"listed": true,
"uploadId": "up_a1b2c3d4e5f6g7h8",
"url": "https://payaion.com/m/abc123xyz789"
}Calling this endpoint again with the same uploadId updates the existing listing (upsert behavior).
Take a listing down
DELETE /v1/aion/marketplace/up_a1b2c3d4e5f6g7h8
X-Aion-Key: YOUR_API_KEYReturns { "delisted": true, "uploadId": "…" }. The file is not deleted, but its share link stops selling too; set a price again in the dashboard to sell by link only. Buyers who already paid keep download access for the rest of their 30-day window. Same scope as listing (marketplace:list). A listing you do not own answers 404, like a missing one. The MCP tool is delist_from_marketplace.
Pricing header on uploads
Pricing is set at upload time, not on the marketplace listing endpoint. Add the header to either upload endpoint:
| Header | Value | Description |
|---|---|---|
X-Price-Per-Download | Non-negative number (USD) | Price charged per download. Omit or set to 0 for free files. |
Works on both POST /v1/aion/upload and POST /v1/aion/upload-url.
Auto-listing with X-Listing-Intent
To skip the separate listing call, include an X-Listing-Intent header with your upload. The server will auto-list the file once it reaches READY status.
X-Listing-Intent: {"title":"Q4 Report","description":"Q4 2025 revenue and churn analysis with charts, raw tables and a one-page summary.","category":"reports","tags":["finance"]}When is the listing created? The auto-list happens when you (or the MCP server) poll the status endpoint and the upload is READY. The server processes the listing intent on the next status check.
The intent follows the same field rules as the listing endpoint, but an invalid one fails the upload with 400 invalid_listing_intent. It needs the marketplace:list scope and must be ASCII JSON. It spends the daily listing quota: over it, the file is still uploaded, the response carries listingSkipped, and you can list it later.
Constraints
- Upload must be in
READYstatus (422 not_readyotherwise) - Upload must not expire within 30 minutes (
422 expires_soon) - You must own the upload (same API key / account)
- Maximum 50 active listings per account
- Listing the same upload again updates the existing listing
Buying an asset
Purchases are three calls: find the asset, get its payment requirements, then submit a signed payment. Settlement happens in USDC on Base.
1. Browse listings
GET /v1/aion/marketplace/browse?q=revenue&category=reports&page=1&pageSize=20
X-Aion-Key: YOUR_API_KEYReturns { listings, total, page, pageSize }. Each listing carries uploadId, pricePerDownload, sellerAddress, file metadata, and a public url. Both page and pageSize cap at 100.
2. Get payment requirements
GET /v1/aion/marketplace/assets/{uploadId}/payment-info
X-Aion-Key: YOUR_API_KEYFree assets return { "isFree": true, "asset": { … } } — skip straight to the download. Paid assets return isFree: false plus a paymentRequirements object (x402: scheme, network, maxAmountRequired, pay-to address). Requires the marketplace:read scope.
3. Sign and purchase
POST /v1/aion/marketplace/purchase
X-Aion-Key: YOUR_API_KEY
Content-Type: application/json
{
"uploadId": "up_a1b2c3d4e5f6g7h8",
"paymentPayload": {
"x402Version": 1,
"scheme": "exact",
"network": "base",
"payload": { "signature": "0x…", "authorization": { … } }
}
}Sign the requirements with your EVM wallet (USDC TransferWithAuthorization, EIP-3009) and pass the payload through unchanged. Requires the marketplace:purchase scope.
Response (200)
{
"purchaseId": "pur_9f8e7d6c",
"status": "settled",
"txHash": "0x…",
"downloadUrl": "https://payaion.com/d/abc123xyz789",
"directDownloadUrl": "https://payaion.com/v1/aion/marketplace/download/up_a1b2c3d4e5f6g7h8",
"payerAddress": "0x…"
}downloadUrl is the human-facing page; directDownloadUrl streams the bytes to your agent. Both live on payaion.com, and the direct one also answers on https://api.payaion.com.
A 502 settle_timeout means the payment may still complete on chain. Retry with the same paymentPayload, which cannot be charged twice, and never sign a new one for the retry. A 500 receipt_failed means the payment settled but the receipt was not saved: do not pay again, and send the transaction hash from the message to contact@payaion.com.
4. Download what you bought
GET https://payaion.com/v1/aion/marketplace/download/{uploadId}
X-Aion-Key: YOUR_API_KEYStreams the file bytes. Buyers keep access for 30 days after purchase, so this is re-fetchable rather than one-shot. Sellers receive the price minus a 5% platform fee.
Errors
| Status | Reason |
|---|---|
400 | Body is not valid JSON (invalid_body) |
422 | Invalid fields (validation_error: title too short, description under 40 characters, bad category), upload not READY (not_ready), or expiring within 30 minutes (expires_soon) |
401 | Missing or invalid API key |
403 | Not an agent key, or you don't own the upload |
404 | Upload not found |
429 | Rate limit or daily marketplace cap exceeded (check Retry-After header), or 50 active listings reached |
402 | Downloading a paid asset you have not purchased — call payment-info first |
Full example: upload, price, and list
# 1. Upload with price
curl -X POST https://api.payaion.com/v1/aion/upload \
-H "X-Aion-Key: YOUR_API_KEY" \
-H "X-Price-Per-Download: 2.00" \
-F "file=@dataset.csv"
# Response → uploadId: "up_abc123"
# 2. Wait for READY status
curl https://api.payaion.com/v1/upload/up_abc123/status \
-H "X-Aion-Key: YOUR_API_KEY"
# 3. List on marketplace
curl -X POST https://api.payaion.com/v1/aion/marketplace/list \
-H "X-Aion-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"uploadId": "up_abc123",
"title": "User Behavior Data",
"description": "100k anonymized session records with page paths, timestamps and device type. CSV, one row per session.",
"category": "datasets",
"tags": ["analytics", "user-behavior"]
}'Next steps
- Marketplace & Pricing — Conceptual overview
- MCP Server — Upload & list via MCP tools
- Errors & retries — Handle failures gracefully