Agent flow
An agent can transfer a file with no account, no wallet and no key. Add the MCP server and the transfer tools work immediately — a key only raises the limits. This page covers both paths and the three details that cause almost every failed integration.
Without a key
Install and go. Uploads run under guest limits: 100 MB per file and a 24-hour link.
npx -y @payaion/mcp # or: pip install payaion-mcp && payaion-mcpStraight HTTP works the same way — one request, whole file, link back:
curl -X POST https://payaion-api.fly.dev/v1/aion/upload \
-F "file=@report.csv"
# {"uploadId":"up_…","downloadUrl":"https://payaion.com/d/…","status":"PENDING_UPLOAD"}Browsing the marketplace needs no key either. Uploading, checking status and fetching a download URL all work anonymously; listing a file for sale and buying one do not.
Getting a key without a browser
An agent mints its own key by signing a message with a wallet it holds locally. No MetaMask, no dashboard, three requests.
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(generatePrivateKey()); // a dedicated agent wallet
// 1. nonce
const { nonce } = await (await fetch("https://payaion.com/api/auth/nonce")).json();
// 2. sign locally
const message = [
"payaion.com wants you to sign in with your Ethereum account:",
account.address,
"",
"Create a Payaion API key",
"",
"URI: https://payaion.com",
"Version: 1",
"Chain ID: 8453",
`Nonce: ${nonce}`,
`Issued At: ${new Date().toISOString()}`,
].join("\n");
const signature = await account.signMessage({ message });
// 3. mint
const { apiKey } = await (await fetch("https://payaion.com/api/aion-keys/siwe", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message, signature }),
})).json(); // av_…Three things that will reject your signature
- The domain must be exactly
payaion.com. The first line of the message is checked against this site's host. A message built forlocalhostor a preview URL is rejected here. - The statement must read
Create a Payaion API key. It sits on its own line, wrapped in blank lines, exactly as shown. A message signed to log in is deliberately not accepted for minting, and vice versa — one signature must not authorise two different things. - Chain ID must be 8453 (Base). Other chains are refused even though the signature would verify on them.
The nonce is single-use and the message expires five minutes after Issued At. Fetch a fresh nonce per mint.
What a minted key can and cannot do
Keys minted this way carry upload scopes only — upload:create, upload:status, upload:download. They cannot list a file for sale. Pricing is a human action taken in the dashboard, because the wallet an agent generated for itself lives in an environment file on a server, and money should not follow it.
Where the money goes
Earnings are paid to the payout address on your account, set in the dashboard under Earnings. It is deliberately independent of whichever wallet signed an upload, and no API key can read or change it. Use a cold address.
Until you set one, payouts fall back to the wallet you first signed in with — which is correct for a human account and wrong for an agent that minted its own key. Set it before you price anything.
Guest identity is tied to your IP
A keyless caller is identified by a hash of its address. That is what keeps one guest's uploads separate from another's without asking anyone to sign up — but it means an agent that changes network loses access to get_upload_status and get_download_url for files it uploaded earlier.
The share link keeps working: it is public and belongs to the file, not to the caller. Hold on to the downloadUrl from the upload response and nothing is lost. If an agent needs durable access to its own uploads, give it a key.