Pre-flight API

Ask before you sign.

One POST tells an agent whether the transaction it is about to sign breaks its published spec.

The watchdog judges transactions after they land. Pre-flight moves the same rules in front of the signature. Haltr reads the agent's spec and halt state from the registry, checks the token's mint and a Jupiter sell-back, and simulates the transaction on mainnet when you send it. Every check served is logged on this page.

Checks served10from 3 client labels
Cleared to sign9ok was true
Stopped1ok was false
Average latency2093msmeasured at Haltr

Endpoint

JSON in, JSON out. CORS is open, so an agent can call it from anywhere. Limits: 30 checks a minute per agent and 240 per IP, a transaction of up to 2,400 base64 characters, and 4s for each external read. A read that times out marks its check as warn. It never passes silently.

POSThttps://haltr.xyz/api/preflight

Request

FieldTypeRequiredMeaning
agentstringRequiredRegistry id, such as haltr-demo-agent, or the agent's wallet address.
clientstringOptionalLabel shown in the public log below. Trimmed to 60 characters.
intent.dexstringRequiredVenue the trade routes through: Raydium, ClawPump, Jupiter, Orca, Meteora or PumpSwap. Any other name is evaluated as Other. When the sent programs call a different known venue, that venue is evaluated instead.
intent.side"buy" | "sell"RequiredDirection of the trade.
intent.assetMintstringRequiredMint of the token bought or sold. Use So11111111111111111111111111111111111111112 for SOL. SOL, USDC and USDT are named by their mint. Any other mint that calls itself one of those is named by its short address, so it cannot pass an asset allowlist.
intent.sizeSolnumberRequiredSOL notional of the trade. At least one lamport, 0.000000001.
intent.slippageBpsnumberRequiredSlippage tolerance the agent will sign with, 0 to 10000.
intent.programIdsstring[]OptionalTop-level programs the transaction calls. Ignored when a transaction is sent. Without either, Haltr infers the venue's usual programs and only warns about them.
intent.transactionstringOptionalBase64 transaction, legacy or v0, up to 2,400 characters. Send it unsigned. Signatures are not needed because Haltr simulates with signature checks off. The agent wallet must be one of its signers. Haltr reads its programs and simulates it on mainnet.
intent.projectedPnlSolnumberOptionalExpected PnL in SOL, negative for a loss. Feeds the drawdown rule. Defaults to 0.

Response

FieldTypeMeaning
okbooleanTrue only when the agent is armed, no spec rule breaks, the honeypot check does not fail and the simulation does not fail. Sign only on true.
agentIdstringRegistry id the request resolved to.
agentStatus"active" | "halted" | "flattened"Registry status at the time of the check.
specVersionnumberThe published spec version that was applied.
certifiedbooleanTrue when that spec version is certified with a $ANSEM burn.
violationsViolation[]Broken rules, most severe first. Each has rule, severity, title, detail, observed and limit.
checksobjectSeven named checks, each { status, detail }. Status is pass, warn, fail or skipped.
evaluatedMsnumberWall time Haltr spent on the check, in milliseconds.
checkIdnumber | nullRow id in the public log.
docsstringLink to this page.
resolvedobjectHow the intent was read: dex, asset, programIds, programSource and roundTripPct.

Checks

ok is false when the agent is not armed, any spec rule breaks, or the honeypot or simulation check fails. Warnings are for the agent's own judgment and never flip ok on their own.

CheckWhat Haltr looks atWhen it fails or warns
haltedRegistry status of the agent.Fails when the agent is halted or flattened. A halted agent must not trade.
specThe same deterministic rules the watchdog applies to landed transactions: size, drawdown, venue, asset list, slippage, programs, rate and honeypot.Fails on any violation.
honeypotFor buys, a Jupiter quote from SOL to the token, then back to SOL for exactly what the buy returns. For every mint, its Token-2022 extensions.Fails with no sell route, a round trip under 50%, a non-transferable mint, a permanent delegate, a transfer fee over 10%, or an address that is not a token mint. Warns on a transfer hook, a fee over 1%, or a read that did not answer.
tokenAuthoritiesMint and freeze authority on the mint.Warns only. USDC has both and never fails here.
programsTop-level programs against the spec allowlist. Read from the transaction, else intent.programIds, else inferred from the venue.Fails on a sent or declared program outside the allowlist. Inferred programs are a guess, so they only warn and never fail.
simulationsimulateTransaction on mainnet with signature checks off and a fresh blockhash. Inner programs are listed from the logs. The agent wallet must be one of the transaction's signers.Fails when the transaction errors, when the RPC rejects it as malformed, or when the agent wallet does not sign it. Warns when the RPC cannot be reached. Skipped without a transaction.
rateLimitActions the watchdog observed from the wallet in the last 60 seconds, plus this one.Fails above the spec's trades per minute.

Status codes

200A PreflightResponse. Read ok.
400Bad input. The error names the field.
404No registered agent matches agent.
413Body over 16,384 bytes, or a transaction over 2,400 base64 characters.
429Over 30 checks a minute for one agent, or 240 from one IP. Wait for Retry-After.
500, 503Haltr could not evaluate. Treat it as not ok.

Examples

curl
curl -s -X POST https://haltr.xyz/api/preflight \
  -H 'content-type: application/json' \
  -d '{"agent":"haltr-demo-agent","client":"my-bot/1.0","intent":{"dex":"Raydium","side":"buy","assetMint":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","sizeSol":0.004,"slippageBps":50}}'
TypeScriptfetch
import type { VersionedTransaction } from "@solana/web3.js";

/** Ask Haltr before signing. Send tx unsigned; sign only on true. */
export async function preflight(tx: VersionedTransaction): Promise<boolean> {
  const res = await fetch("https://haltr.xyz/api/preflight", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({
      agent: "haltr-demo-agent",
      client: "my-bot/1.0",
      intent: {
        dex: "Raydium", side: "buy", sizeSol: 0.004, slippageBps: 50,
        assetMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
        transaction: Buffer.from(tx.serialize()).toString("base64"),
      },
    }),
  });
  if (!res.ok) return false; // fail closed
  const verdict = await res.json();
  return verdict.ok === true;
}

Try it

This form calls the live API for Haltr's demo agent. Its spec v7 allows Raydium only, at most 0.005 SOL a trade. Change the DEX or the size to see the check stop it.

RequestPOST /api/preflight
A real request. It is logged below with your client label.
Request body
{
  "agent": "haltr-demo-agent",
  "client": "haltr-docs",
  "intent": {
    "dex": "Raydium",
    "side": "buy",
    "assetMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "sizeSol": 0.004,
    "slippageBps": 50
  }
}
Response

No request sent yet. Edit the intent and send it. The answer from the live API appears here.

Recent checks

The ten newest checks served, read from the pre-flight log.

Pre-flight log · newest first10 served
TimeAgentVerdictReasonsLatencyClient
2026-09-29 17:57:49 UTCHaltr Reference AgentClearNone1090mshaltr-reference-agent/1
2026-09-29 17:42:43 UTCHaltr Reference AgentClearNone1102mshaltr-reference-agent/1
2026-09-29 17:27:36 UTCHaltr Reference AgentClearNone1093mshaltr-reference-agent/1
2026-09-29 17:12:30 UTCHaltr Reference AgentClearNone1076mshaltr-reference-agent/1
2026-09-29 17:09:23 UTCHaltr Demo AgentClearNone1086mshaltr-docs
2026-09-29 16:57:24 UTCHaltr Reference AgentClearNone1090mshaltr-reference-agent/1
2026-09-29 16:42:20 UTCHaltr Reference AgentClearNone1104mshaltr-reference-agent/1
2026-09-29 03:02:27 UTCHaltr Demo AgentStopMAX_TRADE_SIZE, MAX_SLIPPAGE4183msskill-test
2026-09-29 03:02:14 UTCHaltr Demo AgentClearNone4195msskill-test
2026-09-28 15:40:24 UTCHaltr Demo AgentClearNone4911mshaltr-docs