payaion-transfer

Transfer files via the Payaion REST API, set USDC per-download pricing on Base mainnet, and list on the marketplace. Use for agent-to-human, agent-to-agent, and agent-to-marketplac…

jan | defdone

@jan-blockbites

Install

$ openclaw skills install @jan-blockbites/payaion-transfer

Payaion Transfer (ClawHub / OpenClaw)

Audience: OpenClaw agents installed from ClawHub. This skill is curl/REST-only. For Cursor or Claude Code, use the separate payaion-agent skill (MCP-first).

Previously published as AgentVee Transfer, which passed 600+ downloads during the testnet phase. This is the production release: Base mainnet, live USDC, and PAYAION_API_KEY in place of AGENTVEE_API_KEY.

Transfer files between agents and humans. Upload from URL or local disk, set per-download pricing in USD (settled in USDC on Base mainnet), list on the Payaion marketplace, and share download links — all via the Payaion REST API.

APIhttps://payaion-api.fly.dev
Webhttps://payaion.com
ChainBase mainnet · USDC
Auth headerX-Aion-Key: $PAYAION_API_KEY

No API key needed to transfer. Omit the X-Aion-Key header entirely and the upload runs as a guest: 100 MB per file, 24-hour link, no account. A key raises the limits (500 MB, 2 GB stored, 28-day links). You can sell without a key too — see X-Payout-Address below.

Get one at payaion.com/dashboard, or have the agent mint its own by signing a message with a wallet it holds locally — three requests, no browser: payaion.com/docs/agent-flow.

Earnings go to a payout address set in the dashboard. No API key can read or change it, so a compromised agent key costs uploads, not money.

Three supported flows:

FlowDescription
Agent → HumanUpload a file, share the download link
Agent → AgentUpload + share the uploadId or download URL
Agent → MarketplaceUpload with pricing, list publicly for paid downloads

Authentication

Optional for transfers. Send the header when a key is set, omit it entirely when it is not — the upload then runs as a guest.

X-Aion-Key: $PAYAION_API_KEY      # omit this line if PAYAION_API_KEY is unset

Listing on the marketplace and buying still require a key. Both fail with 403 insufficient_scope or forbidden without one.

Base URL (production): https://payaion-api.fly.dev


One-Shot API (recommended — single request does everything)

Upload + wait for ready + set price + list on marketplace — all in ONE curl call. The server handles polling internally and returns the final result.

Upload a local file with pricing and marketplace listing

curl -s -X POST https://payaion-api.fly.dev/v1/aion/upload \
  -H "X-Aion-Key: $PAYAION_API_KEY" \
  -H "X-Wait-For-Ready: true" \
  -H "X-Price-Per-Download: 0.25" \
  -H 'X-Listing-Intent: {"title":"My Report","description":"Market analysis","category":"reports","tags":["market","analysis"]}' \
  -F "file=@/path/to/file.pdf"

Upload from URL with pricing and marketplace listing

curl -s -X POST https://payaion-api.fly.dev/v1/aion/upload-url \
  -H "X-Aion-Key: $PAYAION_API_KEY" \
  -H "X-Wait-For-Ready: true" \
  -H "X-Price-Per-Download: 0.25" \
  -H 'X-Listing-Intent: {"title":"My Report","description":"Market analysis","category":"reports","tags":["market","analysis"]}' \
  -H "Content-Type: application/json" \
  -d '{"url": "URL_HERE"}'

Response (200 — everything done)

{
  "uploadId": "up_a1b2c3d4e5f6g7h8",
  "status": "READY",
  "ready": true,
  "downloadUrl": "https://payaion.com/d/abc123xyz789",
  "expiresAt": "2026-04-10T12:00:00.000Z",
  "pricePerDownload": "0.25",
  "url": "https://payaion.com/m/abc123xyz789"
}

If you get 202 instead of 200

202 means the file was accepted but is still processing — the server either had no wait slot free or wait mode is off ("waitUnavailable": true). This is the only case where polling is allowed: call the status endpoint below every few seconds until ready is true (give up after ~2 minutes and report the last status).

Headers explained

HeaderRequiredDescription
X-Aion-KeyNoAPI key. Omit it to upload as a guest; required to list or buy
X-Wait-For-ReadyAlways sendtrue — server waits until the file is READY (up to ~120s) and returns 200
X-Price-Per-DownloadNoPrice in USD (e.g. 0.25). Omit for free downloads. Above 0 requires a connected wallet
X-Listing-IntentNoJSON string with marketplace listing data. Server auto-lists after READY. Needs a key with the marketplace:list scope — a keyless caller is refused with 403
X-Payout-AddressNoKeyless sellers only: the wallet a priced download pays out to (0x…, 40 hex characters). This is what lets an agent sell with no account. Ignored when a key is sent, because that account's payout address is a dashboard setting

X-Listing-Intent format

{
  "title": "string (3–120 chars, required)",
  "description": "string (40–500 chars, REQUIRED — what the buyer gets)",
  "category": "reports|datasets|code|media|models|prompts|other",
  "tags": ["tag1", "tag2"]
}
  • description is required and must be at least 40 characters. A shorter or missing description fails the whole request with 422. Write a real sentence or two about what the buyer gets — never a placeholder.
  • Tags: max 8, alphanumeric + hyphens only, max 30 chars each.
  • A price above 0 needs somewhere to pay: a wallet on the account, or X-Payout-Address when uploading without a key. Otherwise the request fails with 400 wallet_required.
  • Selling without a key gives the file a 14-day window rather than 24 hours — nobody can buy inside a day — and is capped to a few such uploads per day per network address.

If the user doesn't specify title/description/category/tags, generate them from the filename and context.


Browse marketplace

curl -s "https://payaion-api.fly.dev/v1/aion/marketplace/browse" \
  -H "X-Aion-Key: $PAYAION_API_KEY"

With filters:

curl -s "https://payaion-api.fly.dev/v1/aion/marketplace/browse?q=oil&category=reports&page=1&pageSize=10" \
  -H "X-Aion-Key: $PAYAION_API_KEY"

Query parameters

ParamTypeDefaultDescription
qstring—Search title and description (max 100 chars)
categorystring—Filter: reports, datasets, code, media, models, prompts, other
pageint1Page number (1–100)
pageSizeint20Results per page (1–100)

Response (200)

{
  "listings": [
    {
      "uploadId": "up_a1b2c3d4e5f6g7h8",
      "title": "Oil Market Analysis",
      "description": "Crude oil trends",
      "category": "reports",
      "tags": ["oil", "market"],
      "fileName": "oil-market-analysis.pdf",
      "mimeType": "application/pdf",
      "sizeBytes": 51200,
      "pricePerDownload": "0.25",
      "sellerAddress": "0x7811…ac55",
      "listedAt": "2026-03-27T01:30:00.000Z",
      "url": "https://payaion.com/m/BiMHwpOqTrxa"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 20
}
  • url — the market listing page (/m/<hash>), where a buyer sees the description and price

Other operations (use only when needed)

Check upload status

curl -s https://payaion-api.fly.dev/v1/upload/UPLOAD_ID/status \
  -H "X-Aion-Key: $PAYAION_API_KEY"

Get a fresh download URL

curl -s -X POST https://payaion-api.fly.dev/v1/upload/UPLOAD_ID/download-url \
  -H "X-Aion-Key: $PAYAION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Delete an upload

curl -s -X DELETE https://payaion-api.fly.dev/v1/upload/UPLOAD_ID/delete \
  -H "X-Aion-Key: $PAYAION_API_KEY"

Storage folders

Folders group what the account already holds. They are metadata, not storage: a move never touches the file, and deleting a folder keeps every file inside it — the files drop back to the storage root with their share link, price and expiry unchanged. Deleting a file is the separate call above.

Nesting stops at 8 levels, sibling names must be unique and cannot contain slashes, and folders count against no quota. A key is required — a keyless (guest) caller has no storage to organise.

See what is there

# every folder with its full path and file count, the files at the root,
# and bytes used against the plan limit
curl -s https://payaion-api.fly.dev/v1/storage \
  -H "X-Aion-Key: $PAYAION_API_KEY"

# the files inside one folder
curl -s "https://payaion-api.fly.dev/v1/storage?folderId=FOLDER_ID" \
  -H "X-Aion-Key: $PAYAION_API_KEY"

Create a folder

curl -s -X POST https://payaion-api.fly.dev/v1/folders \
  -H "X-Aion-Key: $PAYAION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Clients","parentId":null}'

Rename or move a folder

# name, parentId, or both. "parentId": null moves it to the top level.
curl -s -X PATCH https://payaion-api.fly.dev/v1/folders/FOLDER_ID \
  -H "X-Aion-Key: $PAYAION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Clients 2026"}'

Delete a folder (files are kept)

curl -s -X DELETE https://payaion-api.fly.dev/v1/folders/FOLDER_ID \
  -H "X-Aion-Key: $PAYAION_API_KEY"

File an upload into a folder

# "folderId": null puts it back at the storage root
curl -s -X POST https://payaion-api.fly.dev/v1/files/UPLOAD_ID/move \
  -H "X-Aion-Key: $PAYAION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"folderId":"FOLDER_ID"}'

Errors worth reading rather than retrying: 409 a sibling already has that name, 422 the name is invalid, the nesting cap is reached, or the move would put a folder inside itself, 404 the folder is not yours.


Idempotency (safe retries)

-H "Idempotency-Key: my-unique-key-12345"

Key: 8–64 chars, alphanumeric + hyphens + underscores. Same key → cached response, no duplicate upload.

Requires an API key. The cache is per-caller, and a keyless caller has no stable identity to key it to, so for guest uploads the header is ignored and a retry creates a second upload. Retrying without a key? Check the first attempt's status instead of resending.


Execution model — CRITICAL

You MUST complete the entire flow in a SINGLE curl call. The One-Shot API handles upload + waiting + listing server-side. Do NOT poll manually (the only exception is a 202 response — see above). Do NOT make multiple API calls. Do NOT stop to ask the user mid-flow.

  1. Build ONE curl command with all headers (X-Wait-For-Ready, X-Price-Per-Download, X-Listing-Intent)
  2. Execute it
  3. Parse the JSON response
  4. Report the result to the user

If the user doesn't provide title/description/category/tags, generate them from the filename.

Final report format

✓ Transfer complete
  - Upload ID: up_xxxxx
  - Price: $0.25/download
  - URL: https://payaion.com/d/...        # downloadUrl — share this to send the file
  - Market: https://payaion.com/m/...     # url — only when listed on the marketplace
  - Status: READY

If the response contains "ready": false or an error, report the failure with the exact error message.


Error handling

{ "error": { "code": "error_code", "message": "Human-readable message" } }
StatusCodeAction
400wallet_requiredA price above 0 needs a wallet connected to the account. Tell the user to connect one in the dashboard, or retry with no price
400invalid_priceX-Price-Per-Download must be a non-negative number in USD, and at least 0.000001 — anything smaller rounds to zero USDC
400invalid_payout_addressX-Payout-Address must be a 0x-prefixed 40-character EVM address
403password_requiredThe asset is password-protected. Send the user to its /d/<hash> page, which prompts for the password
429priced_upload_limitDaily cap on priced uploads without an account. Sign in to sell more
429rate_limit_exceeded (reason abuse)The key tripped limits repeatedly and is blocked for retryAfterSec. Stop — do not keep retrying
401 / 403unauthorizedCheck the API key
403insufficient_scopeThe key lacks a scope (marketplace:list to sell, marketplace:purchase to buy). Keys minted by wallet signature carry upload scopes only — price files from the dashboard instead
403storage_limit_exceededThe account's total storage is full (Basic 2 GB / Pro 20 GB). Tell the user to delete files or upgrade — do NOT retry, and do not split the file into parts
403file_count_limit_exceededThe account holds too many live files (Basic 200 / Pro 2,000). Tell the user to delete files or upgrade — do NOT retry
413size_limit_exceededFile exceeds the per-file limit for the account's plan (Basic 500 MB / Pro 1 GB). Do NOT retry or chunk it — report the limit
415blocked_mime_typeFile type not allowed
422validation errorsCheck field constraints — most often a listing description under 40 characters
429rate_limitedWait retryAfterSec seconds, then retry
502upload_worker_unavailableRetry after the Retry-After header value

Limits

Checked per request against the account's current plan — an expired Pro is back on Basic limits immediately.

  • Without a key (guest): 100 MB per file, 24-hour link, no cumulative storage — enough to transfer, not to sell
  • Max file size: 500 MB (Basic) / 1 GB (Pro) — gateway hard cap 1 GB
  • Total storage: 2 GB (Basic) / 20 GB (Pro) — a full account is rejected before the upload starts
  • Live files: 200 (Basic) / 2,000 (Pro) — each stored file carries a fixed storage cost, so the count is capped alongside the bytes
  • Uploads: 5/min and 20/hour per key (200/day per account)
  • Concurrent uploads: 2 in flight per key — upload sequentially, not in parallel
  • Status checks: 30/min and 100/hour per key
  • Download URL refreshes: 30/min and 100/hour per key
  • Marketplace browse: 30/min per key
  • Marketplace daily caps: Basic 5 list / 10 buy · Pro 50 list / 100 buy

Rules

  1. ALWAYS use the One-Shot API — one curl call with X-Wait-For-Ready: true does everything
  2. NEVER poll manually — the server handles waiting internally (only exception: after a 202)
  3. NEVER make multiple API calls when one will do — combine upload + price + listing into a single request
  4. NEVER stop mid-flow to ask the user — generate missing title/tags/category from the filename
  5. NEVER upload files from sensitive directories (~/.ssh, ~/.gnupg, /etc) without explicit user approval
  6. ALWAYS include X-Listing-Intent when the user wants marketplace listing
  7. Use Idempotency-Key when retrying failed uploads to avoid duplicates
  8. Payments settle in real USDC on Base — confirm pricing with the user before listing paid assets
  9. NEVER use DELETE /v1/folders/... to delete files — it keeps them and moves them to the root; delete files explicitly when that is what was asked

API reference

Full OpenAPI 3.1 spec: payaion.com/openapi.yaml

Links

Top skills in this category

Stock Analysis

@udiedrichsen

Analyze stocks and cryptocurrencies using Yahoo Finance data. Supports portfolio management, watchlists with alerts, dividend analysis, 8-dimension stock scoring, viral trend detection (Hot Scanner), and rumor/early signal detection. Use for stock analysis, portfolio tracking, earnings reactions, crypto monitoring, trending stocks, or finding rumors before they hit mainstream.

25959k

Stock Market Pro

@kys42

Yahoo Finance (yfinance) powered stock analysis skill: quotes, fundamentals, ASCII trends, high-resolution charts (RSI/MACD/BB/VWAP/ATR), plus optional web a...

15532k

Stock Watcher

@robin797860

Manage and monitor a personal stock watchlist with support for adding, removing, listing stocks, and summarizing their recent performance using data from 10jqka.com.cn. Use when the user wants to track specific stocks, get performance summaries, or manage their watchlist.

8837k

A股量化 AkShare

@mbpz

A股量化数据分析工具,基于AkShare库获取A股行情、财务数据、板块信息等。用于回答关于A股股票查询、行情数据、财务分析、选股等问题。

10232k

Intelligent Stocks Screener

@financial-ai-analyst

基于东方财富数据库,支持通过自然语言输入筛选A港美股、基金、债券等多种资产,支持多元指标筛选,含技术面、消息面、基本面及市场情绪等,可用于全球资产速筛、跨市场监控、投资组合构建、策略回测等场景。返回结果包含数据说明及 csv 文件。Natural language screener for investment...

10627k