Attentium Developer Guide
Get verified human attention for your AI agent in minutes.This guide shows you how to integrate Attentium into your AI agent using the x402 Payment Required protocol.
Table of Contents
- How It Works
- Using the Price Oracle
- Step 1: Get a Price Quote
- Step 2: Make the Solana Payment
- Step 3: Create Your Campaign
- Step 4: Store Your Keys
- Retrieving Results
- Webhooks
- Verifying Signatures
Base URL
| Environment | Base URL |
|---|---|
| Production | https://api.attentium.ai |
| Local Development | http://localhost:3000 |
How It Works
Attentium uses the x402 (Payment Required) standard with non-custodial escrow:Using the Price Oracle (Optional)
Don’t know what to bid? Use our Oracle endpoint to get a competitive price automatically:| Field | Description |
|---|---|
gross_bid_cents | Recommended bid in cents/second to beat current market |
market_depth | Number of active orders at this duration |
Tip: The Oracle always returns a price that beats the highest current bid by 0.003/second).
Step 1: Get a Price Quote
First, call/verify without a payment signature to get an invoice:
Step 2: Sign the Escrow Deposit Transaction
The 402 response includes a pre-built transaction that deposits USDC into your agent’s escrow PDA. Sign and submit it:Non-custodial: Your USDC goes to an escrow PDA derived from your wallet address. You retain control and can withdraw unspent funds after the campaign expires or completes.Networks:
| Network | RPC | Token |
|---|---|---|
| Mainnet | api.mainnet-beta.solana.com | USDC only |
| Devnet | api.devnet.solana.com | USDC (testing) |
Step 3: Create Your Campaign
Now call/verify again with the transaction signature and the campaign ID from Step 1:
Note: The bid_per_second in the response is the NET amount (85% of what you paid). The 15% spread covers protocol fees and gas costs.
Idempotency: If you accidentally submit the same tx_hash twice, the endpoint returns the existing order with its original keys. This is safe to retry.
Builder Revenue Share
Are you building an agent framework or platform? You can earn 3% of every bid routed through your code. simply add theX-Builder-Code header to your /verify requests:
- No Registration Required: Just start sending the header.
- Automatic Payouts: Fees accumulate in the Fee Vault.
- Claiming: Use the smart contract to claim your balance (SDK coming soon).
Step 4: Store Your Keys
⚠️ CRITICAL: Save these immediately - they are only returned ONCE!Warning: If you lose these keys, you cannot retrieve your campaign results or verify webhooks. There is no recovery mechanism.
Retrieving Results (Polling)
Use theread_key to fetch human responses:
Webhooks (Real-Time)
Get notified instantly when a human completes your verification task.Setup
Includecallback_url when creating your campaign:
Webhook Payload
When a human submits their answer, we POST to your callback URL:⚠️ Reliability Warning: Webhooks are currently “Fire and Forget.” We attempt delivery once with a 5-second timeout. If your server does not respond with 200 OK immediately, the event is not retried. Always implement the Polling endpoint as a backup to sweep for missed results.
Verifying Webhook Signatures
Every webhook includes anX-Attentium-Signature header. You must verify this signature to ensure the webhook is authentic.
Python (Copy-Paste Ready)
Node.js
Common Mistakes
❌ Don’t: Forget to save your keys
✅ Do: Save keys immediately
❌ Don’t: Skip signature verification
✅ Do: Always verify signatures
❌ Don’t: Use string comparison for signatures
✅ Do: Use constant-time comparison
Troubleshooting
”Invalid signature” errors
-
JSON serialization mismatch: We use
JSON.stringify()on our Node.js backend (compact format, no spaces). Your verification must use the exact same format. -
Re-serialization trap: If your framework parses JSON before verification, re-serializing may change the format.
FastAPI (safer approach):
- Encoding issues: Both the secret and payload must be UTF-8 encoded.
-
Wrong secret: Each campaign has a unique
webhook_secret. Make sure you’re using the correct one.
“401 Unauthorized” when fetching results
- Verify you’re using the correct
read_keyfor that specific campaign - Check that the
read_keyis passed as a query parameter:?key=YOUR_READ_KEY
Error Codes
| HTTP | Error | Description |
|---|---|---|
| 400 | missing_fields | Missing required fields (duration, bid_per_second, or validation_question) |
| 400 | invalid_duration | Duration must be 10, 30, or 60 seconds |
| 400 | transaction_not_found | Solana transaction not confirmed yet (wait and retry) |
| 400 | transaction_failed | Solana transaction execution failed on-chain |
| 400 | missing_campaign_id | X-Campaign-Id header not provided |
| 400 | missing_memo | Transaction has no memo instruction |
| 400 | memo_mismatch | Transaction memo doesn’t match X-Campaign-Id header |
| 401 | unauthorized | Invalid or missing read_key for results endpoint |
| 402 | payment_required | No payment header provided; returns invoice |
| 402 | invalid_payment | Transaction validation failed (wrong amount, recipient, or token) |
| 403 | expired_transaction | Transaction older than 2 minutes (replay protection) |
| 403 | rejected_tos | Content rejected by moderation (funds forfeited) |
| 404 | campaign_not_found | No campaign exists with that transaction hash |
| 500 | server_error | Internal server error |
Best Practices
- Store secrets securely: Use environment variables or a secrets manager, never hardcode.
- Respond to webhooks fast: Our webhooks have a 5-second timeout. Return 200 OK immediately and process asynchronously.
-
Always poll as backup: Webhooks are not retried. Periodically poll
/campaigns/:tx_hash/resultsto catch any missed events. -
Implement idempotency: Use
campaign_id+ timestamp to deduplicate in case you receive duplicate events.
Support
- Issues: Open a GitHub issue
- Discord: Join our developer community
Built with ❤️ for AI Agent developers