txshield Docs
Home/API Documentation

TxShield API

Stop wasting SOL on dead transactions. Drop an unsigned tx in, get back the fee bucket your bot needs to land, the slippage the route will actually take, the simulation outcome, and a per-vector risk breakdown — typically in under 80 ms.

API v1 · stable P50 ≤ 80 ms Solana mainnet MEV detection · production beta Last updated · 2026‑05‑27
Try it live — interactive playground → fill in your key · fire real requests · inspect responses inline

Overview

Every Solana transaction faces the same three execution risks before it lands: it gets dropped or stuck because the priority fee is in the wrong bucket, the route slips harder than the wallet UI estimated, or it reverts at execution for a reason the wallet never surfaced. TxShield runs all three checks pre-flight in a single /simulate call so wallets and bots can either bump the fee, switch the route, abort the tx, or proceed with confidence.

The same call also runs the safety checks — program blacklist, sandwich-attacker proximity, rug-pull / honeypot, durable-nonce, flash-loan / oracle. MEV / sandwich detection is currently production beta and treated as advisory; the execution-quality vectors (landing, slippage, simulation, fees) are GA.

Base URL: https://api.txshield.dev. All endpoints under /api/v1/. JSON in, JSON out. UTF-8. ISO 8601 timestamps in UTC.

i
You only need one endpoint to ship.

POST /api/v1/solana/tx/simulate drives every vector in this guide. Webhooks, batching and streaming are convenience layers over the same call.

01Quickstart

Five minutes from npm install to your first verdict.

1. Get an API key

Sign in to the dashboard and create a key under Settings → API keys. Each key is scoped to one project, lives in one of three modes (test, live, internal) and can be rotated or revoked at any time.

!
Never put a live key in client-side code.

Use scoped session tokens for browser/mobile origins. They expire after 15 minutes and are bound to a single user wallet.

2. Pick how you call us

The API is plain HTTP — every endpoint is a one-line curl. Official TypeScript and Python SDKs are shipping under Beta Milestone 1 of the Solana Foundation Developer Tooling grant; until they land on npm / PyPI, use curl or generate a client from the OpenAPI 3.1 spec with the generator of your choice.

setup
# nothing to install — just curl + your keyexport TXSHIELD_KEY="txshield_live_..."

3. First request

POST /api/v1/solana/tx/simulate
curl -X POST "https://api.txshield.dev/api/v1/solana/tx/simulate" \  -H "X-API-Key: $TXSHIELD_KEY" \  -H "Content-Type: application/json" \  -d '{"transaction": "<base64-versioned-tx>", "policy": "wallet-default"}'

4. Read the verdict

The response envelope is the same shape on every chain.

HTTP/2 200 · application/json simulated · 68 ms
{
  "success": true,
  "compute_units": 28104,
  "suggested_compute_limit": 31000,
  "fee_estimate_sol": 0.0000125,
  "priority_fees": {
    "low": 1000, "medium": 10000,
    "high": 100000, "very_high": 1000000,
    "samples": 312
  },
  "slippage": { "bps": 7, "route": "jupiter-v6" },
  "risk": {
    "mev_score": 0.04, "mev_level": "none", "mev_type": null,
    "has_blacklisted_program": false,
    "blacklisted_programs": [],
    "dex_programs": ["JUP6L…AG4"],
    "token_risk": null,
    "flash_loan_risk": { "detected": false, "oracle_manipulation": false },
    "durable_nonce": { "detected": false, "address": null },
    "risk_level": "low"
  },
  "landing_estimate": {
    "fee_percentile_bucket": "low",
    "submitted_fee_microlamports": 1000,
    "recommended_fee_for_high_landing": 12500
  },
  "recommendations": [],
  "program_breakdown": […],
  "call_tree": […]
}

02Authentication

Two layers, picked by call site:

Both authenticate the same endpoints. Where you use which is a security choice — never put an API key in client-side code.

Four sign-in methods (all issue a JWT bearer)

MethodFlowEndpoints
Solana wallet Sign-In-With-Solana: dashboard asks the wallet (Phantom, Backpack, Solflare, Glow) to sign a server-issued nonce. We verify the ed25519 signature, upsert by wallet pubkey, and issue a JWT. No password. POST /auth/wallet/challenge
POST /auth/wallet/login
Google OAuth Standard authorization-code flow. HttpOnly state cookie for CSRF. Upserts by Google subject ID, issues JWT via URL fragment redirect. GET /auth/oauth/google/start
GET /auth/oauth/google/callback
GitHub OAuth Same shape as Google. Useful when devs already have a GitHub SSO session. GET /auth/oauth/github/start
GET /auth/oauth/github/callback
Email + password Classic. Argon2id hashing. Refresh-token rotation. POST /auth/register
POST /auth/login

Wallet sign-in — the wire shape

Two calls. First fetch a nonce; second submit the signature.

Sign-In-With-Solana
# 1. Get a challenge for this pubkeycurl -X POST "https://api.txshield.dev/auth/wallet/challenge" \  -H "Content-Type: application/json" \  -d '{"pubkey": "<base58-wallet-address>"}'# → { "nonce": "...", "message": "txshield.dev wants you to sign in...\nNonce: ...\nIssued: ..." }# 2. Sign the `message` with the wallet, then submitcurl -X POST "https://api.txshield.dev/auth/wallet/login" \  -H "Content-Type: application/json" \  -d '{"pubkey": "...", "signature": "<base58-ed25519-sig>", "nonce": "..."}'# → { "token": "eyJ...", "refresh_token": "eyJ...", "user": { ... } }

Nonces expire after 5 minutes and are single-use. The signed message follows the SIWS draft so wallet UIs render it as a human-readable prompt, not opaque bytes.

Scoped session tokens (browser-safe)

For wallet/mobile origins that already have a JWT, mint a short-lived session token server-side and hand it to the client. Tokens expire after 15 minutes and are bound to a single user wallet so leakage has a tiny blast radius.

03Solana — single simulation

POST/api/v1/solana/tx/simulate

The core of the product. Submit one unsigned VersionedTransaction serialized as base64. We simulate it against mainnet state, run the 14 detection vectors in parallel, and return a single envelope.

Request body

FieldTypeRequiredDescription
transactionstring · base64requiredSerialized VersionedTransaction (or legacy Transaction) — the bincode produced by tx.serialize(), base64-encoded. Signature slots may be empty/zero; we don't verify them.
policystringoptionalNamed policy preset. Default: wallet-default. Other values: strict (lower abort thresholds, suitable for high-value), bot (latency-optimised, mev + simulation only).
vectors[]string[]optionalRestrict which detection vectors run. Default: all. Common subsets: ["mev","slippage","rug","program"].
timeout_msintoptionalServer-side timeout cap. Default 800. Anything below 80 will fall back to cached priority-fee data only.
abort_on_active_threatbooloptionalDefault true. When the verdict carries an active threat (drainer program, OFAC-listed account, confirmed-attacker proximity), return decision: "ABORT" instead of just risk-scoring it. Renamed from abort_on_critical_risk in May 2026.
abort_on_flash_loan_oraclebooloptionalDefault true. Aborts if the tx pattern matches flash-loan + oracle-read sequencing typical of price-manipulation attacks. Shipped May 2026 (beta).
abort_on_durable_noncebooloptionalDefault false. Aborts if the tx uses an AdvanceNonceAccount instruction (durable nonce). Most wallets do not use durable nonces; presence often signals a delayed-broadcast attack pattern. Shipped May 2026 (beta).

Response — top-level fields

FieldTypeRequiredDescription
successboolrequiredDid the inner Solana simulateTransaction succeed? false just means the tx would revert — the verdict envelope is still useful.
compute_unitsint?optionalCU consumed during the simulated execution. Null if the tx didn't reach execution.
suggested_compute_limitint?optionalCU limit we recommend you set on the real submit (typically compute_units × 1.1).
fee_estimate_solfloat?optionalEstimated fee in SOL at current cluster prices, including priority fees.
priority_feesobjectrequiredP25/P50/P75/P95 of getRecentPrioritizationFees for the programs touched. Use medium as a default tip; jump to high when latency matters.
slippageobject?optionalWorst-case slippage in basis points, plus the route used. Populated when a DEX program is detected.
riskobjectrequiredPer-vector breakdown — see Detection vectors. Includes flash_loan_risk and durable_nonce nested objects as of May 2026.
landing_estimateobject?optionalWhere your submitted priority fee sits in the current validator percentile distribution. Includes fee_percentile_bucket (one of low/medium/high/very_high/unknown), submitted_fee_microlamports, and recommended_fee_for_high_landing (a concrete uplift target if you are in the low bucket). Shipped May 2026.
recommendations[]arrayrequiredConcrete actions you can take (e.g. add a priority fee, increase slippage tolerance, switch route). Empty when nothing's wrong.
program_breakdownarrayoptionalPer-program CU + invocation count, useful for cost attribution and debugging.
call_treearrayoptionalCPI tree extracted from simulation logs. Helpful when a tx fails mid-flight.
failure_reasonstring?optionalHuman-readable explanation of why success is false (when applicable).

Solana — batch simulation

POST/api/v1/solana/tx/simulate-batch

Up to 50 transactions in one round-trip. Use it when your bot evaluates multiple candidate routes per block — saves the round-trip latency on N-1 of them.

i
Order is preserved.

Results return in the same order as the input array. No partial-failure quirks — if one tx errors, only that index's success is false; others continue.

Solana — streaming verdicts

WSwss://txshield.dev/api/v1/solana/tx/simulate-stream

WebSocket connection for sub-50 ms verdicts. Send a JSON envelope per line; receive verdicts as they finish. Authenticate with the ?api_key=… query param at connect time. Connection idle-timeout 60s — send a ping if you've gone quiet.

Simulation history

GET/api/v1/solana/simulations

Paginated list of past simulations on this account. Query params: limit (default 25, max 200), cursor (opaque string from previous page), since/until (ISO 8601), risk_level, has_blacklisted_program.

Retention: 90 days by default; up to 7 years for volume customers (negotiated per tenant).

Aggregate stats

GET/api/v1/solana/simulations/stats

Pre-computed aggregates for the dashboard widget: total sims, 24h count, success rate, P50/P95/P99 latency. Refreshed every 60s.

04Detection · MEV / sandwich

!
Production beta — treat verdicts as advisory.

The MEV vector is fully shipped to mainnet and processing live traffic, but per-DEX precision is still being calibrated against rolling ground truth. Use mev_score and mev_level for signal, not a hard block, until the methodology paper lands under Beta Milestone 2 of the Solana Foundation grant. The execution-quality vectors (priority-fee, slippage, simulation, landing estimate) are GA.

Detects front-run + back-run pairs against monitored Solana DEX programs (Jupiter, Raydium, Orca, Meteora, Lifinity). Returns:

Treat high/critical as a hard refusal in production. medium usually means you should re-route through a private mempool or wait for the next block.

Detection · Rug-pull / honeypot

Engaged when the tx touches an SPL-token program. Checks:

Detection · Slippage overflow

Pulls live route quotes from Jupiter Price API at submit-time priority fees — not the stale UI estimate. Returns slippage.bps as worst-case basis points and slippage.route as the chosen route. Use recommendations to surface alternative routes when bps > your threshold.

Detection · Program safety

Curated and customer-submitted blacklist of malicious programs anywhere in the CPI tree. Categories:

CategoryWhat it means
drainerKnown wallet drainers — auto-block on every account.
rug_deployerPrograms that have rugged at least once historically.
fake_tokenCounterfeit USDC/USDT/etc. minted to mimic legitimate tokens.
honeypotSell-disabled programs (catch buyers who can't exit).
phishingPrograms used by phishing kits (drain on sign).
compromisedOnce-legitimate programs whose authority has been compromised.

Per-tenant overrides for volume customers — extend the list with your own blocklist/allowlist.

Detection · Priority fee

Live getRecentPrioritizationFees sampling per program. Returned as p25/p50/p75/p95 inside priority_fees. Use the medium percentile as the default tip; jump to high when landing latency matters more than fee cost.

Detection · Pre-flight simulation

The basis for everything else. Solana simulateTransaction with full pre-execution against mainnet state. Returns balance changes, CPI call tree, per-program compute units, and revert reasons in compute_units, program_breakdown, call_tree, failure_reason.

05Webhooks

POST/api/v1/solana/simulations/webhooks

Register a URL to receive verdict events in real-time. We POST a JSON payload to your URL whenever an event of a type you subscribed to fires. Default delivery latency: < 200 ms after the originating event.

Subscribable event types

EventFires when
simulation.completedVerdict landed for a /simulate call. Filtered by risk_level ≥ your configured threshold.
simulation.high_riskConvenience alias — fires only when risk_level is high or critical.
tx.submittedA /submit call cleared the abort gates and was relayed to the configured submit path (direct, staked sender, or managed-tip Jito).
tx.finalityPost-submit finality monitor confirms a tx is finalized, dropped, or reverted. Useful for closing out bot trade lifecycles without polling the RPC. Shipped May 2026.
alert.threshold_breachA configured alert (rate-anomaly, MEV-spike, plan-quota) crossed its threshold.

Signature verification

Every webhook delivery carries an X-TxShield-Signature header — HMAC-SHA256 over the raw body, signed with your endpoint's secret. Verify in your handler before trusting the payload:

verify HMAC
import { createHmac, timingSafeEqual } from "node:crypto";function verify(rawBody: Buffer, signature: string, secret: string) {  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");  return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));}

Retry policy

If your endpoint returns a non-2xx status (or doesn't respond within 8s), we retry with exponential backoff: 30s, 2m, 10m, 1h, 6h. After the 5th attempt we mark the delivery as failed; you can manually replay it from the dashboard. Idempotency: each delivery carries a stable delivery_id in the body — use it to dedupe on your side.

06API keys

GET/api/v1/api-keys POST/api/v1/api-keys DEL/api/v1/api-keys/{id} POST/api/v1/api-keys/{id}/rotate

Manage keys programmatically or via the dashboard. The cleartext key is only returned once — at creation. After that you only see the prefix (e.g. txshield_live_) and metadata (requests_count, last_used_at, created_at).

Rotation is graceful: the new key activates immediately, the old one stays valid for 24h, then auto-revokes. No downtime.

07Billing

Pure pay-as-you-go. 1,000 simulations per day on the house, then €0.002 per simulation past that, billed at the end of the calendar month. No tiers, no monthly fee, no commitment, no feature gating — every account gets every detection vector, webhooks, batch and WebSocket from day one. A separate /submit relay tier charges €0.003 per billable submit-strategy call (staked sender, managed-tip Jito); direct and auto-direct submits are free. Jito tips pass through at exact cost.

Free quotaMetered (after card added)
Price€0€0.002 per simulation past the daily free tier
Daily allowance1,000 sims / day · resets 00:00 UTCSame 1,000 / day still free, then metered
Rate limit10 rps100 rps · burst 250
Behaviour past quota429 with Retry-AfterContinues serving · €0.002 per call
Detection vectorsAll 14All 14
FeaturesWebhooks · WebSocket · batchWebhooks · WebSocket · batch · custom rules · per-tenant blocklist
SLABest-effortP50 ≤ 80 ms · 99.9 % uptime
SupportCommunity DiscordEmail + Slack · 24h response

Above ~5M sims / month? Volume customers get a negotiated per-call rate, a dedicated regional cluster (99.99% SLA), SOC 2 / ISO 27001 evidence pack, and Slack-Connect with 1-hour pager response. Email hello@txshield.dev.

Refunds & disputes

Because this is pay-as-you-go, every line on your monthly invoice corresponds to a specific API call we logged. You can query the underlying records via GET /api/v1/solana/simulations (simulations) or GET /api/v1/solana/submissions (relay submits) to verify any charge against your own logs.

If a charge is wrong — double-billed, metering glitch, service degradation that materially affected your usage — email hello@txshield.dev within 14 days of the invoice date with the invoice number and a brief description. We refund or credit verified billing errors within 5 business days. Stripe disputes through your card issuer also work, but are slower and noisier; we would rather hear from you first.

Cancellation: cancel any time at /billing or via the Stripe Customer Portal. The current billing period is not prorated — you keep API access through end of month, then your account reverts to the 1,000-sim/day free tier (no data loss, no key rotation required).

EU consumer right of withdrawal (§ 312g BGB) applies only to B2C purchases. Business accounts (USt-IdNr provided at signup) are commercial contracts under § 14 BGB and not subject to the 14-day withdrawal window; the refund window above is a voluntary policy we offer regardless.

Endpoints:

GET/api/v1/billing/usage GET/api/v1/billing/subscription POST/api/v1/billing/checkout POST/api/v1/billing/portal

checkout creates a Stripe Checkout session for the metered subscription and returns a redirect URL. portal creates a Customer Portal session for managing payment methods, invoices, and cancellation. Adding a card just lifts the throttle — you're never charged for the first 1,000/day.

08Errors

HTTP status codes are load-bearing. Read them.

CodeMeaningWhat to do
200OKRead the verdict envelope.
400Bad requestValidation error in request shape — check error.message.
401UnauthenticatedMissing or invalid API key / JWT.
403ForbiddenPlan-gated feature (e.g. custom rules on Free tier).
404Not foundResource doesn't exist or isn't visible to your account.
409ConflictIdempotency conflict — same key, different body.
422UnprocessableRequest shape OK but content is invalid (e.g. tx fails to deserialize).
429Rate limitedBackoff — see Rate limits. Honour Retry-After header.
500Server errorOur problem — automatic alert fires. Retry with backoff.
503Service unavailableRegion failover in progress. Retry with backoff.

All error responses share a JSON shape:

HTTP/2 422 · application/json
{
  "error": {
    "code": "invalid_transaction",
    "message": "failed to deserialize VersionedTransaction: …",
    "request_id": "req_01HVZX9P3J4D2TJYP91D"
  }
}

09Rate limits

Per-API-key rate limits, enforced at the edge. Burst window: 1 second.

Steady-stateBurstBehaviour
Free quota10 rps25 rpsThrottle — 429 with Retry-After.
Metered (card on file)100 rps250 rpsThrottle past burst.
VolumeNegotiatedNegotiatedPer-tenant.

Headers on every response:

10SDKs

Until the official SDKs ship under Beta Milestone 1 of the Solana Foundation Developer Tooling grant, curl + a generated client from the OpenAPI spec is the supported path. Every endpoint is doc-equivalent to a one-line curl; see the request examples above.

Other languages: use the OpenAPI spec at /openapi.json with your generator of choice. We test against openapi-typescript, openapi-python-client, and oapi-codegen (Go); pull-requests welcome for additional generators once the grant SDKs land.

11Changelog

OpenAPI spec · /openapi.json Status · txshield.dev/status Contact · hello@txshield.dev