Inference API¶
The inference API enables pay-per-use AI inference via the x402 protocol.
Endpoint¶
Request Flow¶
Step 1: Initial Request (No Payment)¶
POST /api/inference/1
Content-Type: application/json
{
"input": "Bitcoin price surges to new all-time high amid ETF approval"
}
Step 2: Receive Payment Requirements (HTTP 402)¶
{
"x402Version": 1,
"accepts": [
{
"scheme": "exact",
"network": "avalanche-fuji",
"maxAmountRequired": "10000",
"resource": "https://wasiai.io/api/inference/1",
"description": "AI inference on Crypto Sentiment Analyzer",
"payTo": "0x1234567890abcdef1234567890abcdef12345678",
"asset": "0x5425890298aed601595a70AB815c96711a31Bc65",
"maxTimeoutSeconds": 60
}
],
"error": "X-PAYMENT header is required",
"_info": {
"model": "Crypto Sentiment Analyzer",
"agentId": 1,
"priceFormatted": "$0.0100",
"currency": "USDC"
}
}
Step 3: Retry with Payment¶
POST /api/inference/1
Content-Type: application/json
X-PAYMENT: eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiYXZhbGFuY2hlLWZ1amkiLCJwYXlsb2FkIjp7InNpZ25hdHVyZSI6IjB4Li4uIiwiYXV0aG9yaXphdGlvbiI6ey4uLn19fQ==
{
"input": "Bitcoin price surges to new all-time high amid ETF approval",
"agentId": 1
}
Step 4: Receive Result (HTTP 200)¶
{
"ok": true,
"result": {
"task": "sentiment-analysis",
"input_text": "Bitcoin price surges to new all-time high amid ETF approval",
"sentiment": "positive",
"confidence": 0.9234,
"all_scores": [
{ "label": "positive", "score": 0.9234 },
{ "label": "neutral", "score": 0.0612 },
{ "label": "negative", "score": 0.0154 }
],
"model": "ProsusAI/finbert",
"model_name": "Crypto Sentiment Analyzer",
"agent": "agent-1",
"timestamp": "2024-12-11T12:00:00.000Z"
},
"latencyMs": 1250,
"payment": {
"txHash": "0xabc123def456789...",
"payer": "0xUserWallet...",
"amount": "10000",
"amountFormatted": "$0.0100",
"currency": "USDC",
"verified": true
},
"agent": {
"id": 1,
"name": "Crypto Sentiment Analyzer"
}
}
Request Parameters¶
Path Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
modelId | number | Yes | The model ID to run inference on |
Headers¶
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | Must be application/json |
X-PAYMENT | Conditional | Base64-encoded payment payload (required after 402) |
Body Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
input | string/object | Yes | Input data for the model |
agentId | number | No | Agent ID for reputation tracking |
labels | string[] | No | Custom labels for classification models |
Response Headers¶
On Success (200)¶
| Header | Description |
|---|---|
X-PAYMENT-RESPONSE | Base64-encoded payment result |
Payment Response Decoded¶
{
"success": true,
"transaction": "0xabc123...",
"network": "avalanche-fuji",
"payer": "0xUserWallet...",
"errorReason": null
}
Model Types¶
Sentiment Analysis¶
Input:
Output:
{
"task": "sentiment-analysis",
"sentiment": "positive",
"confidence": 0.89,
"all_scores": [
{ "label": "positive", "score": 0.89 },
{ "label": "neutral", "score": 0.08 },
{ "label": "negative", "score": 0.03 }
]
}
Zero-Shot Classification¶
Input:
Output:
{
"task": "zero-shot-classification",
"labels": ["DeFi", "Governance", "Security", "NFT"],
"scores": [0.72, 0.15, 0.08, 0.05],
"top_label": "DeFi",
"top_score": 0.72
}
Text Generation¶
Input:
Output:
{
"task": "text2text-generation",
"generated_text": "Smart contracts are self-executing programs..."
}
Error Responses¶
Payment Required (402)¶
Payment Failed (402)¶
Model Not Found (404)¶
Rate Limited (429)¶
X-PAYMENT Header Format¶
The X-PAYMENT header contains a base64-encoded JSON payload:
{
"x402Version": 1,
"scheme": "exact",
"network": "avalanche-fuji",
"payload": {
"signature": "0x...",
"authorization": {
"from": "0xUserWallet...",
"to": "0xSplitterAddress...",
"value": "10000",
"validAfter": "1702300000",
"validBefore": "1702300060",
"nonce": "0x..."
}
}
}
Code Examples¶
JavaScript/TypeScript¶
async function runInference(modelId: number, input: string) {
// Step 1: Get payment requirements
const res1 = await fetch(`/api/inference/${modelId}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ input })
})
if (res1.status !== 402) {
return res1.json()
}
const { accepts } = await res1.json()
const requirement = accepts[0]
// Step 2: Build and sign payment
const payment = await buildPayment(requirement)
const xPayment = btoa(JSON.stringify(payment))
// Step 3: Retry with payment
const res2 = await fetch(`/api/inference/${modelId}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-PAYMENT': xPayment
},
body: JSON.stringify({ input })
})
return res2.json()
}
Python¶
import requests
import base64
import json
def run_inference(model_id: int, input_text: str, payment: dict):
url = f"https://wasiai.io/api/inference/{model_id}"
# Step 1: Get requirements
res1 = requests.post(url, json={"input": input_text})
if res1.status_code != 402:
return res1.json()
# Step 2: Retry with payment
x_payment = base64.b64encode(json.dumps(payment).encode()).decode()
res2 = requests.post(
url,
json={"input": input_text},
headers={"X-PAYMENT": x_payment}
)
return res2.json()
Rate Limits¶
| Limit | Value |
|---|---|
| Requests per minute | 10 |
| Max input size | 10KB |
| Timeout | 30 seconds |