Loop gate
POST /api/loop-gateShould the loop run another iteration? Send POST /api/loop-gate with the required fields goal, lastOutput and iteration and pay $0.001 per call over x402 or MPP (there is no free tier). It returns the result.
Send the goal, the iteration that just finished (lastOutput, iteration), and optionally maxIterations, a budget { spentUsd, maxUsd }, the history of earlier iterations (up to 20 of { iteration, summary }, oldest first) and constraints; get back decision (continue, stop or escalate), reason, confidence (0 to 1), the checks that produced it (goalMet, budgetExceeded, iterationsExhausted, repeating, stuck, constraintBreached) and nextStep (iterate, change_approach, narrow_scope, verify_result, hand_off). The budget and iteration checks run in code before anything else: when either trips the answer is stop, no model is consulted, goalMet is null and model is null, at the same price. An output that repeats an earlier summary (repeating) and three near-identical outputs in a row (stuck) are found lexically first. Otherwise a typed judgment model (the /v1/judge backends) answers whether the goal is met, whether the loop is stuck, whether a constraint is breached and what to do next; model names which served. Model-backed, not deterministic, except the budget and iteration checks, which are computed in code before any model call.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
goal | string | yes | What the loop is trying to accomplish. Up to 600 characters. |
lastOutput | string | object | yes | What the iteration that just finished produced, or a digest of it. Up to 3000 characters. |
iteration | integer (1-) | yes | The number of iterations completed so far (the one that produced lastOutput). |
maxIterations | integer (1-) | no | Optional. At iteration >= maxIterations the answer is stop, decided in code. |
budget | object | no | Optional { spentUsd, maxUsd }. At spentUsd >= maxUsd the answer is stop, decided in code. |
history | array of object | no | Optional, up to 20 earlier iterations as { iteration, summary }, oldest first; each summary up to 400 characters. Pass the same kind of text you pass as lastOutput so repeats compare like with like. The model reads the newest 5; all are compared lexically. |
constraints | array of string | no | Optional, up to 8 rules the output must respect, each up to 160 characters. With constraints the model also answers constraintBreached; a breach escalates. |
Example request
curl -i -X POST https://agent402.tools/api/loop-gate \
-H "Content-Type: application/json" \
-d '{"goal":"Find three peer-reviewed studies on sleep and memory consolidation published since 2020, with DOIs.","lastOutput":"Found two studies with DOIs (Nature Neuroscience 2021, Sleep 2023). A third search of PubMed returned review articles only.","iteration":4,"maxIterations":6,"budget":{"spentUsd":0.52,"maxUsd":0.5},"history":[{"iteration":2,"summary":"One study found (Nature Neuroscience 2021)."},{"iteration":3,"summary":"Second study found (Sleep 2023); PubMed search for a third in progress."}]}'
Without payment this returns HTTP 402 Payment Required with the exact price for loop-gate; any x402 v2 or MPP client pays it and retries.
Example response
{}
From an MCP client
catalog.call {
"slug": "loop-gate",
"params": {
"goal": "Find three peer-reviewed studies on sleep and memory consolidation published since 2020, with DOIs.",
"lastOutput": "Found two studies with DOIs (Nature Neuroscience 2021, Sleep 2023). A third search of PubMed returned review articles only.",
"iteration": 4,
"maxIterations": 6,
"budget": {
"spentUsd": 0.52,
"maxUsd": 0.5
},
"history": [
{
"iteration": 2,
"summary": "One study found (Nature Neuroscience 2021)."
},
{
"iteration": 3,
"summary": "Second study found (Sleep 2023); PubMed search for a third in progress."
}
]
}
}
The hosted connector at https://agent402.tools/mcp needs a payment for loop-gate; the stdio package pays it from a wallet or from an AGENT402_CREDITS_KEY issued earlier. Local install: npx -y agent402-mcp.
Errors and behavior
goal,lastOutputanditerationare required. An input the tool rejects returns an HTTP 4xx whose body carrieserror,tool,expected,requiredandexample, so the caller can correct it.- A paid call that ends in any status of 400 or above is not charged over x402, MPP or a prepaid credits key: settlement is canceled when the tool fails. The exception is a Tempo push credential, a transfer the buyer sent before the call: it settles before the tool runs, so if the tool then fails the payment is recorded as a refund owed to the paying wallet.
- Wallet-only: this tool runs a model, so it has no proof-of-work tier. A prepaid card-credits key issued earlier (
Authorization: Bearer a402_...) also pays it. - Model-backed: the answer is generated by a model, so the same input can produce a different result.
- A
GETorHEADto /api/loop-gate returns the same 402 quote, so the price can be read without a body. - An
Idempotency-Keyheader makes a retried paid call replay the first 200 instead of charging again (an answer larger than 1 MB is not replayed).
Paid call (JavaScript agent)
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const client = new x402Client();
client.setSpendControls?.({ maxAmountPerPayment: "$0.001" }); // refuse any quote above this tool's price
registerExactEvmScheme(client, { signer: privateKeyToAccount(KEY) });
const payFetch = wrapFetchWithPayment(fetch, client);
const res = await payFetch("https://agent402.tools/api/loop-gate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"goal": "Find three peer-reviewed studies on sleep and memory consolidation published since 2020, with DOIs.",
"lastOutput": "Found two studies with DOIs (Nature Neuroscience 2021, Sleep 2023). A third search of PubMed returned review articles only.",
"iteration": 4,
"maxIterations": 6,
"budget": {
"spentUsd": 0.52,
"maxUsd": 0.5
},
"history": [
{
"iteration": 2,
"summary": "One study found (Nature Neuroscience 2021)."
},
{
"iteration": 3,
"summary": "Second study found (Sleep 2023); PubMed search for a third in progress."
}
]
}),
});
Related tools
Decisions (OpenAI wire)
POST /v1/decisionsOpenAI's Decisions API on its own wire: point an OpenAI SDK's base URL here and client.decisions.create works unchanged.
Typed judgment
POST /v1/judgeAsk a typed question about any content and get an answer your code can branch on, not prose to parse.
Judge long documents (preview)
POST /v1/judge/longThe typed questions of /v1/judge over a document of up to 900 KB (about 262k tokens), in one call.
Judge images (preview)
POST /v1/judge/visionAsk typed questions about up to 4 images (PNG or JPEG) and get answers your code can branch on: noul (yes/no.
Image generation
POST /api/image-genGenerate an image from a text prompt using GPT Image 2 (low quality, 1024x1024).
Image generation (HD)
POST /api/image-gen-hdGenerate a higher-quality image from a text prompt using GPT Image 2 (medium quality, 1024x1024).