Developer Platform API
Docs for bots.
Base URL: https://api.icme.io/v1
Authentication: X-API-Key: YOUR_KEY
Most endpoints return application/json. Three endpoints stream text/event-stream (SSE) instead:
POST /v1/makeRules
SSE
POST /v1/checkIt
SSE
POST /v1/refinePolicy
SSE
All other endpoints return JSON. If you need JSON-only for checkIt
SSE event format
Every SSE line has the form data: {json}\n\n. There are three event types, distinguished by the step field:
Progress — intermediate status updates:
data: {"step":"1/3","msg":"Analyzing action..."}
data: {"step":"2/3","msg":"Extracting values from action..."}
data: {"step":"3/3","msg":"Verifying against policy..."}Done — final result. step is always "done". The rest of the payload is endpoint-specific (see each endpoint below):
data: {"step":"done","check_id":"...","result":"SAT","detail":"..."}Error — terminal failure. step is always "error":
data: {"step":"error","code":"INSUFFICIENT_CREDITS","error":"Out of credits."}The stream closes after a single done or error event. Keep-alive comments (: keep-alive) may appear between events — ignore lines that don't start with data: .
Parsing example (JavaScript)
Parsing example (Python)
Parsing example (curl)
Accounts
POST /v1/createUserX402
POST /v1/createUserX402Create an account via x402 USDC payment on Base. $5.00 one-time fee. No API key required.
The x402 middleware handles payment automatically. Send the request — if unpaid, you'll receive a 402 with payment requirements. Pay $5.00 USDC on Base, then retry with the Payment-Signature header. Returns API key and 325 starting credits.
Save your
api_keyimmediately. It is shown only once. Use it as theX-API-Keyheader for all authenticated endpoints.
POST /v1/createUserCard
POST /v1/createUserCardCreate an account via card payment. No crypto required. Returns a Stripe Checkout URL.
After paying, call GET /v1/session/{session_id} to retrieve your API key.
POST /v1/createUser
POST /v1/createUserCreate an account via USDC on Base (Stripe deposit flow). $5.00 one-time fee. Gives 325 credits.
Call without stripe_payment_intent_id to receive a deposit address. Send exactly $5.00 USDC to payTo on Base, then retry with stripe_payment_intent_id.
POST /v1/topUpX402
POST /v1/topUpX402Add 500 credits via x402 USDC payment on Base. $5.00. Requires X-API-Key header.
No request body needed. The x402 middleware handles payment — retry with Payment-Signature after paying.
POST /v1/topUpCard
POST /v1/topUpCardAdd credits via card payment. No crypto required. Returns a Stripe Checkout URL.
After paying, call GET /v1/session/{session_id} to confirm credits were added.
POST /v1/topUp
POST /v1/topUpAdd credits via USDC on Base (Stripe deposit flow). Call with empty body to see tiers and current balance.
$5
500
—
$10
1,050
+5%
$25
2,750
+10%
$50
5,750
+15%
$100
12,000
+20%
GET /v1/session/{session_id}
GET /v1/session/{session_id}Poll after a card payment to retrieve account info or confirm credits. No API key required.
Returns status: pending while payment is processing, status: complete once done. For signup, the response includes api_key — save it, it will not be shown again.
GET /v1/me
GET /v1/meReturn the authenticated user's account info and current credit balance. Requires X-API-Key header.
Use this to check your remaining credits before making calls. The balance is read from the database at request time, so it always reflects the latest value.
GET /v1/me/policies
GET /v1/me/policiesList all policies owned by the authenticated user, newest first. Requires X-API-Key header.
Returns a trimmed projection per policy — use GET /v1/policy/{id}/scenarios or GET /v1/policy/{id}/variables for full detail on a specific policy.
Policy
POST /v1/makeRules
POST /v1/makeRulesCompile a natural language policy to formal logic. 300 credits. Returns text/event-stream (SSE).
Write your guardrail policy in plain English. Preflight compiles it to SMT-LIB formal logic and returns a policy_id + scenarios for review.
scenarios are generated by ICME Preflight from your compiled rules, sorted to surface the most likely-to-be-wrong variable combinations first. Review them before using the policy in production. See Battle Testing Rules.
SSE progress steps: 1/6 → 2/6 → … → 6/6 (cloud mode) or 1/3 → 2/3 → 3/3 (local mode).
Done payload:
Credits and failure: If compilation fails (SSE error event), the 300 credits are refunded automatically. If the stream drops or your client fails to parse the policy_id from the done event, call GET /v1/me/policies to retrieve it — your policies are listed newest-first.
GET /v1/policy/{id}/scenarios
GET /v1/policy/{id}/scenariosRetrieve saved scenarios for a policy. Scenarios are refreshed after each refinePolicy call.
POST /v1/submitScenarioFeedback
POST /v1/submitScenarioFeedbackSubmit thumbs-up or thumbs-down feedback on a scenario. Returns immediately — no SSE.
approved: true— saves a test case with the expected result. No rebuild.approved: false— saves a test case and queues the annotation for the nextrefinePolicycall. Requiresannotationexplaining why the scenario is wrong. Be specific — name the variables, the values, and which rule is violated.
POST /v1/refinePolicy
POST /v1/refinePolicyApply all queued thumbs-down annotations in a single rebuild. Returns text/event-stream (SSE).
Batches all pending annotations, submits them to ICME Preflight, polls until the build completes, compiles new SMT, updates the guardrail in place, and writes the refined policy back to the database. Your policy_id does not change.
SSE progress steps: 1/5 → 2/5 → … → 5/5.
Done payload: same shape as makeRules — includes updated rule_count, scenarios, and next_steps.
POST /v1/runPolicyTests
POST /v1/runPolicyTestsRun all saved test cases against the compiled policy. test_case_ids is optional — if omitted, all saved test cases for the policy are run.
passed
Expected and actual results match
failed
Rule logic is wrong — submit thumbs-down and call refinePolicy
ambiguous
Preflight translator disagreed — improve variable descriptions and refine
Relevance Screening
POST /v1/checkRelevance
POST /v1/checkRelevanceFree relevance screen. Checks whether an action touches any of your policy variables before running a paid check. No credits charged. Requires X-API-Key header.
threshold is optional. Default 0.0, meaning any match triggers should_check: true. Raise it to skip actions that only touch a small fraction of your policy.
should_check: true— the action is relevant to your policy. RuncheckItbefore executing.should_check: false— zero variables matched. Proceed without a paid check.
Use before every checkIt call to avoid paying for irrelevant actions like reading files, formatting text, or summarizing content.
POST /v1/explain
POST /v1/explain Free translation + relevance screen. Takes any raw agent action (shell commands, tool calls, file operations, encoded instructions) and returns a plain English description of what it does, plus the same relevance data as checkRelevance. No credits charged. Requires X-API-Key header.
Designed for non-developers reviewing agent activity, Claude Code hook integrations, and audit dashboards where raw tool calls are unreadable.
The endpoint runs two steps internally: an LLM translates the raw input to plain English, then the same relevance logic as checkRelevance screens it against your policy variables.
Request:
policy_id
string (UUID)
Yes
UUID of the compiled policy (from makeRules)
input
string
Yes
The raw agent action to explain. Shell command, JSON tool call, encoded text, anything. Max 2000 chars.
threshold
number
No
Relevance threshold (0.0–1.0). Default 0.0. Actions at or above this trigger should_check: true.
Response:
plain_english
string
Human-readable description of what the action does
input
string
The original input that was explained
relevance
number
Fraction of policy input variables touched (0.0–1.0)
matched_variables
number
Count of policy variables the action touches
total_variables
number
Total input variables in the policy
matched
string[]
Names of the matched policy variables
should_check
boolean
Whether the action exceeds the threshold. If true, run checkIt before executing.
threshold
number
The threshold that was used
time_ms
number
Processing time in milliseconds
When to use explain vs checkRelevance:
Use explain when the input is opaque (shell commands, tool call JSON, encoded text) and you need a human-readable translation.
Use checkRelevance when you already have a plain English action string and just need the relevance screen.
Both are free. Both return should_check. The only difference is explain adds the translation step and returns plain_english.
Typical flow with Claude Code hooks:
Install the hook with one command:
bash
GET /v1/policy/{id}
GET /v1/policy/{id}Retrieve a policy's original text, compiled SMT-LIB, and parsed rules. No credits charged. Requires X-API-Key header.
policy_id
string (UUID)
The policy identifier
original_text
string
The plain English policy you submitted to makeRules
smt
string
The compiled SMT-LIB formal logic
rules_parsed
array
The individual rules extracted during compilation
rule_count
integer
Number of rules in the policy
created_at
string (ISO 8601)
When the policy was created
Use this to inspect what your policy compiled to, debug unexpected checkIt results, or export the SMT-LIB for external tooling.
Checking Actions
POST /v1/checkItPaid
POST /v1/checkItPaidCheck an agent action against a compiled policy via x402 payment. $0.10 per call. No API key required.
result is SAT (permitted) or UNSAT (blocked). Every decision returns a check_id which serves as a cryptographic audit receipt.
Writing action strings: End every action string with an explicit claim — "Therefore this transfer is permitted." State every policy variable explicitly in the action. Do not rely on the extractor to infer missing values.
POST /v1/checkIt
POST /v1/checkItCheck an agent action against a compiled policy. 1 credit. Requires X-API-Key header. Returns text/event-stream (SSE).
Same as checkItPaid but authenticated via API key and deducts 1 credit. This is the cheapest path if you already have credits from signup (325 free) or topUp.
SSE progress steps: 1/3 → 2/3 → 3/3.
Done payload:
If you need a plain JSON response instead of SSE, use POST /v1/checkItProd — same logic, single JSON response, no streaming.
POST /v1/checkItProd
POST /v1/checkItProdSame as checkIt but returns a single application/json response instead of SSE. 1 credit. Requires X-API-Key header. Uses the cloud reasoning engine for extraction and verification.
Best choice when you want a simple await res.json() workflow without SSE parsing.
POST /v1/verify
POST /v1/verifyCheck structured values directly against a policy. No LLM extraction. 1 credit. Requires X-API-Key header.
Returns a minimal ALLOWED or BLOCKED verdict.
POST /v1/verifyPaid
POST /v1/verifyPaidCheck any policy with no account. $0.10 per call via USDC on Base (Stripe deposit flow). No API key required.
Call without payment header to receive a deposit address. Send exactly $0.10 USDC to payTo on Base, then retry.
ZK Proofs
Every checkIt/checkItPaid call triggers zero-knowledge proof generation in the background. The proof_id and proof_url are returned immediately in the done event, but the proof itself takes 30–60 seconds to generate. GET /v1/proof/{id} returns 404 until generation completes.
Polling for proof readiness
Poll GET /v1/proof/{id} until it returns 200. Recommended interval: 5 seconds, timeout after 120 seconds.
404
Proof is still generating — keep polling
200
Proof is ready — response contains metadata
409
Proof was already consumed (single-use)
GET /v1/proof/{id}
GET /v1/proof/{id}Retrieve proof metadata including validity, trace length, and timing. Add ?include_bytes=true to include the raw proof hex.
GET /v1/proof/{id}/download
GET /v1/proof/{id}/downloadDownload raw ZK proof binary. Single-use — marks the proof as consumed.
POST /v1/verifyProof
POST /v1/verifyProofVerify a zero-knowledge proof. No additional cost — proof generation was paid for by the original check.
Single-use: each proof can only be verified once. Subsequent calls return 409.
Payment Flows
x402 (Recommended for Agents)
Fully autonomous — no accounts, no API keys for checkItPaid and createUserX402.
Call the endpoint → receive
402with payment requirements in the response bodySign and submit USDC payment on Base
Retry the request with
Payment-Signatureheader
x402 client libraries (@x402/fetch, x402-reqwest, agentcash) handle this automatically.
Card
Call
/v1/createUserCardor/v1/topUpCardOpen
checkout_url— pay with card, Apple Pay, etc.Poll
GET /v1/session/{session_id}to confirm and retrieve your API key or updated balance
USDC on Base (Stripe Deposit)
Call endpoint without
stripe_payment_intent_id→ receive402withpayToaddressSend exact USDC amount to
payToon Base (eip155:8453)Retry request with
stripe_payment_intent_idset
Amounts must be exact. Each PaymentIntent is single-use.
Credit Budget
Signup
$5.00 (gives 325 credits)
makeRules
300 credits
checkIt
1 credit
verify
1 credit
checkItPaid
$0.10 (no credits needed)
topUpX402
$5.00 (gives 500 credits)
After signup you have 325 credits — enough for 1 policy + 25 checks.
Live Demo Policy
Policy ID: f6e3cd15-9e28-45c4-9f4c-683edd63e468
Try checkItPaid against this policy for $0.10:
bash
Discovery
Your server exposes two discovery documents for x402scan and agent tooling:
GET /openapi.json— OpenAPI 3.1.0 spec withinfo.guidancefor agent onboardingGET /.well-known/x402— x402 v1 fallback listing payable resources
x402scan listing: x402scan.com/server/a90f142f-33fd-4a22-a57f-1772f85d72f5
Last updated

