CHECKPOINT

API

One call between "the buy is ready" and "sign". No key, no signup. Rate-limited to 30 checks per 10 minutes per IP.

Request

POST /api/check
content-type: application/json

{
  "mint": "<token address>",
  "amountSol": 0.1,
  "intent": "buy 0.1 SOL of an AI coin under $100k, the dev must still hold"
}

intent is the owner's words, read into rules for you. If your agent already has structured limits, send rules instead and no model is involved at all:

{
  "mint": "<token address>",
  "amountSol": 0.1,
  "rules": { "budgetSol": 0.1, "maxMcapUsd": 100000, "devMustHold": true,
             "theme": "AI", "themeWords": ["ai", "agent", "gpt"] }
}

Send neither and you get the default safety checks only.

Answer

{
  "mint": "…",
  "symbol": "EXAMPLE",
  "verdict": "ask",
  "question": "Before I buy $EXAMPLE: bundlers held 36% of supply at the top. Buy anyway?",
  "checks": [
    { "id": "mint",   "ok": true,  "label": "Nobody can mint more", "detail": "mint authority revoked", "level": "pass" },
    { "id": "bundle", "ok": false, "label": "Not bundled", "detail": "bundlers held 36% of supply at the top", "level": "ask" },
    …
  ],
  "rules": { … }
}

ok is true, false, or null when the data isn't there yet. level is what a failed check does: block or ask.

What to do with it: on proceed, sign. On ask, put question to the owner and wait. On block, don't sign.

Rules

FieldMeaning
budgetSolmost SOL the agent may spend (blocks above it)
maxMcapUsd · minMcapUsdmarket cap range
maxAgeMin · minAgeMincoin age range, minutes
theme · themeWordskind of coin, and words to look for in its name, ticker, description and links
devMustHoldthe dev wallet must still hold some
requireX · minXFollowersan X account, and how big
minLiquidityUsd · maxTop10Pctoverride the defaults ($2,000 and 40%)
allowBundledskip the bundle check

Examples

curl

curl -s /api/check \
  -H 'content-type: application/json' \
  -d '{"mint":"<token>","amountSol":0.1,"intent":"an AI coin under $100k"}'

TypeScript, before you sign

const res = await fetch('/api/check', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ mint, amountSol, intent: ownerSaid }),
}).then((r) => r.json());

if (res.verdict === 'block') return;                      // don't sign
if (res.verdict === 'ask' && !(await owner.confirm(res.question))) return;
await wallet.signAndSend(tx);

Python

r = requests.post("/api/check", json={
    "mint": mint, "amountSol": 0.1, "intent": owner_said}).json()
if r["verdict"] == "block": raise SystemExit(r["question"])