ticktape
v0.1.0
Published
Official JS SDK for TickTape - independent pre-flight verdicts for Polymarket orders and copy-trading (OK/CAUTION/VETO), paid via x402 or prepaid credits. Zero dependencies, no build step.
Maintainers
Readme
ticktape
Official JS SDK for TickTape - independent pre-flight for Polymarket. Your agent can trade; TickTape tells it when not to: OK / CAUTION / VETO verdicts on orders, COPY / WATCH / VETO ratings on wallets, always with reasons and numbers. Deterministic arithmetic on live order books - no model, no prediction, no custody, no execution.
Zero dependencies. No build step. Plain ESM + hand-written TypeScript types. Works in Node >= 18, Deno, Bun, Cloudflare Workers, and browsers.
Install
npm install ticktapeUsage
1. Sandbox - free, no payment, no account
Every endpoint has a deterministic sandbox response with the exact live field shapes. Use it to integration-test before spending a cent.
import { TickTape } from "ticktape";
const tt = new TickTape();
const verdict = await tt.preflightTrade(
{ slug: "will-x-happen-in-2026", outcome: "Yes", side: "BUY", usd: 250 },
{ sandbox: true },
);
console.log(verdict.verdict, verdict.reasons);
// "CAUTION" [ "slippage 1.2c per share - consider ~$740 instead", ... ]
const profile = await tt.preflightCopy("0x0000000000000000000000000000000000000000", { sandbox: true });
const board = await tt.leaderboard({ sandbox: true });
const red = await tt.redList({ sandbox: true });2. Prepaid credits - bearer token, ~0.4s per call
Buy a credit pack once ($5 USDC on Base via x402 = 500 credits, see auth.md), then every call is fast header auth. No account, no signup - the wallet is the identity, the token is the secret.
import { TickTape } from "ticktape";
const tt = new TickTape({ token: process.env.TICKTAPE_TOKEN }); // tk_...
// live verdict on a real order (1 credit)
const check = await tt.preflightTrade({ slug: "nba-lal-bos-2026-07-15", outcome: "Lakers", usd: 500 });
if (check.verdict === "VETO") throw new Error(`do not send: ${check.reasons.join("; ")}`);
console.log(check.paid); // { credits_used: 1, credits_remaining: 499 }
// copy-trading verdict on a wallet (5 credits)
const copy = await tt.preflightCopy("0x1234567890abcdef1234567890abcdef12345678");
if (copy.verdict === "QUEUED") {
// uncovered wallet - free response, profile ready in ~1h; do NOT tight-loop
console.log(`retry in ${copy.retry_after_seconds}s`);
}
const { balance } = await tt.creditsBalance();3. x402 - pay per call, zero setup
Without a token, live calls throw a PaymentRequiredError carrying the
exact payment terms (x402 v1 terms on .terms, raw v2 PAYMENT-REQUIRED
header on .paymentRequiredHeader). Pay per call by wrapping fetch with an
x402 client such as @x402/fetch
and a funded USDC wallet on Base:
import { TickTape, PaymentRequiredError } from "ticktape";
import { wrapFetchWithPayment } from "@x402/fetch"; // or x402-fetch, version-adaptive
const fetchWithPay = wrapFetchWithPayment(fetch, walletClient); // your Base wallet
const tt = new TickTape({ fetch: fetchWithPay });
const check = await tt.preflightTrade({ token_id: "1234...", usd: 1000 });
console.log(check.paid); // { price_paid_usdc: "0.02", transaction: "0x...", receipt: "https://basescan.org/tx/..." }Or catch the 402 and inspect the terms yourself:
try {
await new TickTape().leaderboard();
} catch (e) {
if (e instanceof PaymentRequiredError) {
console.log(e.terms); // { asset, payTo, maxAmountRequired, network, ... }
}
}Pricing
| Tool | Method | Price (x402) | Credits |
|------|--------|--------------|---------|
| preflightTrade() | GET /api/preflight_trade | $0.02 | 1 |
| leaderboard() | GET /api/leaderboard | $0.02 | 1 |
| redList() | GET /api/red_list | $0.02 | 1 |
| preflightCopy() | GET /api/preflight_copy | $0.10 | 5 |
| creditsBalance() | GET /api/credits | free | free |
Credit pack: POST /api/credits with one $5 x402 payment = 500 credits (12-month validity). Sandbox and QUEUED responses are always free. Canonical pricing: ticktape.cc/pricing.md.
Retry safety
This SDK never retries on its own. Never auto-retry POST /api/credits with a fresh payment authorization - each new signed authorization is a new $5 charge. Buying credits is deliberately not wrapped by the SDK; do it once, explicitly. Honest retries of any paid call must re-send the SAME signed authorization: the server's replay cache returns the identical body without double-charging.
Freshness
Leaderboard, red list, and copy profiles recompute nightly. Responses carry
next_refresh_at - do not re-buy unchanged data before that timestamp.
Links
- Agent guide: ticktape.cc/llms.txt
- Machine manifest: ticktape.cc/agent.json
- Payment and auth: ticktape.cc/auth.md
- Verify us yourself (self-serve audit runbook): ticktape.cc/why.md
- OpenAPI 3.1 spec: ticktape.cc/openapi.json
Verdicts are deterministic arithmetic on public data - not investment advice. TickTape never trades, never takes custody, never executes.
License
MIT
