Agent API Quickstart
Starship exposes a small paid API for trading agents that need Base token and wallet intelligence during scanner loops. The API is read-only: it does not execute trades, place orders, trigger backfills, or mutate indexing jobs.
Use it as a decision input, not as trading advice or execution infrastructure.
Base URL
https://api.strshp.ai/v1/agentPayment Model
Paid production requests use x402 exact EVM payments on Base mainnet (eip155:8453). Requests without payment receive 402 Payment Required with x402 payment requirements. A paying client signs the quoted payment and retries the same HTTP request with a PAYMENT-SIGNATURE header.
Every paid request must include a stable x402 extension named payment-identifier. Generate one id per logical request and reuse it only when retrying that exact request.
Prices
| Endpoint | Price |
|---|---|
GET /token/{address}/analysis | $0.05 |
GET /wallet/{address}/quality | $0.025 |
GET /alerts/recent | $0.005 |
GET /token/{address}/top-wallets | $0.10 |
POST /batch/analyze | Per item: $0.05 for token_analysis, $0.025 for wallet_quality |
batch/analyze accepts up to 20 items and is charged as the sum of item prices.
Recommended Agent Flow
- Poll
GET /alerts/recentevery 10 minutes. The endpoint accepts no query parameters and returns public alerts from the last 10 minutes. - Ignore stale alerts and low-confidence alerts before paying for deeper checks.
- For candidate tokens, call
GET /token/{address}/analysis. - Skip tokens with
has_critical_flags: true, weakdecision_grade, low confidence, poor liquidity, or unacceptable holder concentration. - If the token still passes, call
GET /token/{address}/top-wallets. - Call
GET /wallet/{address}/qualityonly for wallets that affect your policy, such as large smart buyers, top holders, recent sellers, or bad-wallet clusters. - Log the request URL, payment id, settlement response, response payload, policy decision, and simulated or real trade outcome.
Python x402 Example
Install:
pip install "x402[httpx]" eth-accountimport asyncio
import os
import uuid
from eth_account import Account
from x402 import x402Client
from x402.http import x402HTTPClient
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact.register import register_exact_evm_client
API_BASE = os.environ["STARSHIP_AGENT_API_BASE"].rstrip("/")
MAX_PRICE_USD = 0.10
def payment_extensions(payment_id: str) -> dict:
return {"payment-identifier": payment_id}
async def paid_get(path: str, *, max_price_usd: float) -> dict:
if max_price_usd > MAX_PRICE_USD:
raise ValueError("max_price_usd exceeds local agent spend policy")
client = x402Client()
account = Account.from_key(os.environ["EVM_PRIVATE_KEY"])
register_exact_evm_client(client, EthAccountSigner(account))
payment_id = f"starship:{uuid.uuid4()}"
http_client = x402HTTPClient(client)
async with x402HttpxClient(client) as http:
response = await http.get(
f"{API_BASE}{path}",
extensions=payment_extensions(payment_id),
timeout=20,
)
response.raise_for_status()
await response.aread()
settlement = http_client.get_payment_settle_response(
lambda name: response.headers.get(name)
)
print({"payment_id": payment_id, "settlement": settlement})
return response.json()
async def main() -> None:
token = "0x0000000000000000000000000000000000000000"
analysis = await paid_get(
f"/token/{token}/analysis",
max_price_usd=0.05,
)
if analysis["has_critical_flags"] or analysis["decision_grade"] not in ("A", "B"):
return
top_wallets = await paid_get(
f"/token/{token}/top-wallets",
max_price_usd=0.10,
)
print(top_wallets)
asyncio.run(main())TypeScript x402 Example
Install:
npm install @x402/fetch @x402/evm viemimport { x402Client, wrapFetchWithPayment, x402HTTPClient } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
import { randomUUID } from "node:crypto";
const apiBase = process.env.STARSHIP_AGENT_API_BASE!.replace(/\/$/, "");
const maxPriceUsd = 0.10;
type AgentAnalysis = {
has_critical_flags: boolean;
decision_grade: "A" | "B" | "C" | "D" | "F" | null;
confidence: number | null;
};
function paymentExtensions(paymentId: string) {
return { "payment-identifier": paymentId };
}
async function paidGet<T>(path: string, priceCapUsd: number): Promise<T> {
if (priceCapUsd > maxPriceUsd) {
throw new Error("price cap exceeds local agent spend policy");
}
const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`);
const client = new x402Client();
registerExactEvmScheme(client, { signer });
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const paymentId = `starship:${randomUUID()}`;
const response = await fetchWithPayment(`${apiBase}${path}`, {
method: "GET",
extensions: paymentExtensions(paymentId),
} as RequestInit);
if (!response.ok) {
throw new Error(`Starship request failed: ${response.status} ${await response.text()}`);
}
const httpClient = new x402HTTPClient(client);
const settlement = httpClient.getPaymentSettleResponse((name) =>
response.headers.get(name)
);
console.log({ paymentId, settlement });
return response.json() as Promise<T>;
}
const token = "0x0000000000000000000000000000000000000000";
const analysis = await paidGet<AgentAnalysis>(`/token/${token}/analysis`, 0.05);
if (!analysis.has_critical_flags && ["A", "B"].includes(analysis.decision_grade ?? "")) {
const wallets = await paidGet(`/token/${token}/top-wallets`, 0.10);
console.log(wallets);
}Retry And Idempotency
Treat payment-identifier as the idempotency key for paid requests.
- Reuse the same
payment-identifieronly when retrying the exact same method, path, query string, and JSON body. - If the first request settled and the response was cached, the same request and payment id returns the cached response without re-running the protected handler or settling again.
- If the same payment id is reused with a different route, query, path, or body, the API rejects it before handler execution.
- If the idempotency store is unavailable, paid requests fail closed with
503before handler execution. - Generate a new payment id for every new logical request, even if the URL is similar.
cache_status describes the response cache for live data (hit, miss, error, or unknown). It is separate from paid x402 idempotency replay.
Endpoint Reference
GET /alerts/recent
Use this as the discovery endpoint. It accepts no query parameters and returns public alerts created in the last 10 minutes.
Supported public alert types are strong_launch and dormant_buy.
{
"alerts": [
{
"id": 120944,
"chain": "base",
"token_address": "0x1111111111111111111111111111111111111111",
"alert_type": "strong_launch",
"severity": "high",
"confidence": 0.91,
"payload": {
"reason": "smart_wallet_cluster",
"smart_buyers": 6
},
"created_at": "2026-06-21T10:31:04Z"
}
],
"page": {
"limit": 1,
"returned": 1,
"next_cursor": null,
"since": "2026-06-21T10:21:04Z"
},
"data_freshness_ms": 2400,
"cache_status": "miss"
}GET /token/{address}/analysis
Use this for the main token decision. The response intentionally excludes internal lifecycle and raw score fields.
{
"chain": "base",
"token_address": "0x1111111111111111111111111111111111111111",
"symbol": "SHIP",
"name": "Starship",
"source": "uniswap_v4",
"deployer": "0x2222222222222222222222222222222222222222",
"first_seen_at": "2026-06-21T09:58:17Z",
"age_hours": 0.55,
"price_usd": 0.000012,
"fdv_usd": 1200000,
"fdv_confidence": 0.86,
"liquidity_depth_eth": 18.4,
"volume_24h_eth": 92.3,
"buy_count_24h": 421,
"sell_count_24h": 138,
"total_holders": 812,
"top_10_pct": 24.8,
"top_50_pct": 51.2,
"dev_status": "sold_partial",
"confidence": 0.88,
"buyer_summary": {
"elite_count": 3,
"good_count": 9,
"neutral_count": 72,
"bad_count": 2,
"elite_volume_pct": 18.5,
"good_volume_pct": 31.4
},
"has_critical_flags": false,
"reason_codes": [
{
"code": "smart_buyer_cluster",
"severity": "info",
"detail": "Multiple quality wallets bought in the launch window"
}
],
"recent_alerts": [
{
"id": 120944,
"chain": "base",
"token_address": "0x1111111111111111111111111111111111111111",
"alert_type": "strong_launch",
"severity": "high",
"confidence": 0.91,
"payload": {
"smart_buyers": 6
},
"created_at": "2026-06-21T10:31:04Z"
}
],
"decision_grade": "B",
"data_freshness_ms": 6100,
"cache_status": "miss"
}GET /token/{address}/top-wallets
Use this after a token passes analysis. It returns bounded decision-relevant groups, not a full holder export.
{
"chain": "base",
"token_address": "0x1111111111111111111111111111111111111111",
"top_holders": [
{
"wallet": "0x3333333333333333333333333333333333333333",
"group": "top_holder",
"quality_tier": "good",
"quality_score": 74,
"pct_supply": 2.8,
"balance": 28000000,
"realized_pnl_eth": 12.4,
"lifetime_pnl_eth": 84.2,
"playstyle": "early_accumulator",
"first_buy_at": "2026-06-21T10:03:30Z",
"last_trade_at": "2026-06-21T10:22:10Z",
"flags": []
}
],
"smart_buyers": [],
"recent_sellers": [],
"bad_wallets": [],
"data_freshness_ms": 8800,
"cache_status": "miss"
}GET /wallet/{address}/quality
Use this only when a wallet changes the decision. Example: a top holder is also an elite profitable wallet, or a recent seller has a scam-heavy profile.
{
"chain": "base",
"wallet": "0x3333333333333333333333333333333333333333",
"tier": "good",
"score": 74,
"win_rate": 0.61,
"lifetime_pnl_eth": 84.2,
"total_tokens_sold": 143,
"scam_victim_count": 1,
"quality_updated_at": "2026-06-21T10:20:00Z",
"quality_confidence": 0.83,
"quality_confidence_reason": "sufficient_realized_trade_history",
"playstyle_updated_at": "2026-06-21T10:21:00Z",
"playstyle": "early_accumulator",
"notable_trades": [
{
"token_address": "0x1111111111111111111111111111111111111111",
"token_symbol": "SHIP",
"approx_profit_eth": 6.7
}
],
"decision_grade": "B",
"data_freshness_ms": 31000,
"cache_status": "hit"
}POST /batch/analyze
Use this for scanner loops that already have a small bounded candidate set. Each item must be token_analysis or wallet_quality.
{
"chain": "base",
"items": [
{
"kind": "token_analysis",
"address": "0x1111111111111111111111111111111111111111"
},
{
"kind": "wallet_quality",
"address": "0x3333333333333333333333333333333333333333"
}
]
}{
"chain": "base",
"items": [
{
"kind": "token_analysis",
"address": "0x1111111111111111111111111111111111111111",
"status": "ok",
"token_analysis": {
"chain": "base",
"token_address": "0x1111111111111111111111111111111111111111",
"symbol": "SHIP",
"buyer_summary": {
"elite_count": 3,
"good_count": 9,
"neutral_count": 72,
"bad_count": 2,
"elite_volume_pct": 18.5,
"good_volume_pct": 31.4
},
"has_critical_flags": false,
"reason_codes": [],
"recent_alerts": [],
"decision_grade": "B",
"data_freshness_ms": 6100,
"cache_status": "miss"
},
"wallet_quality": null
},
{
"kind": "wallet_quality",
"address": "0x3333333333333333333333333333333333333333",
"status": "ok",
"token_analysis": null,
"wallet_quality": {
"chain": "base",
"wallet": "0x3333333333333333333333333333333333333333",
"tier": "good",
"score": 74,
"lifetime_pnl_eth": 84.2,
"total_tokens_sold": 143,
"scam_victim_count": 1,
"notable_trades": [],
"decision_grade": "B",
"data_freshness_ms": 31000,
"cache_status": "miss"
}
}
],
"cache_status": "miss"
}Response Interpretation
decision_grade: compact grade for automated policies. TreatAandBas candidates,Cas manual-review or low-size, andD/Fas skip unless your strategy explicitly accepts high risk.confidence: model confidence for the token or wallet signal. Do not use grade without confidence.has_critical_flags: hard risk indicator. Most agents should skip when true.reason_codes: machine-readable explanation for policy logs and audits.data_freshness_ms: age of the newest underlying data used by the response.cache_status: live response cache status.errormeans cache access failed and the API returned live data where possible.
Limits And Errors
- Addresses must be EVM addresses matching
0xplus 40 hex characters. alerts/recentreturns all public alerts from the last 10 minutes and rejects query parameters.top-walletsreturns bounded groups of decision-relevant wallets.batch/analyzeaccepts 1 to 20 items.- Expensive endpoints have concurrency limits and may return
429. - Guardrail timeouts return
504. - Missing, malformed, mismatched, or rejected payment returns
402. - Idempotency store failures return
503.