APIFlow-Bench: The Enterprise Survival Test for AI Agents

APIFlow-Bench: The Enterprise Survival Test for AI Agents

Zelin Wan

As enterprises adopt AI agents, the real worry is not one wrong answer in isolation; it is whether an agent can stay reliable across the whole workflow. Enterprise adoption is being slowed by governance, security, integration, and compliance concerns, which is why leaders treat long-chain failure as a business risk rather than a simple model glitch. That is where “almost works” quietly turns into real cost: one bad assumption early in a workflow can cascade into rework, compliance risk, support escalations, data leakage, or broken automation across multiple systems.

In modern enterprise systems, almost everything that matters is an API call wrapped in business logic. A useful agent is not the one that sounds fluent; it is the one that can authenticate, inspect state, recover from errors, retry safely, and return a result the system can trust. That is why API readiness is such a strong proxy for agent readiness. This is not a theoretical distinction. Real API agents fail in ways that are operationally specific: a token expires mid-session, a payload is malformed in one field, a retry is issued too aggressively, a write succeeds but is not confirmed, or the agent assumes an action landed when it did not. A benchmark that ignores those distinctions will systematically overestimate reliability.

A model that can survive long API chains is not merely better at tool use. It is better at preserving context, respecting constraints, managing state, and completing work across dependent steps.

In a world where agents are wired directly into APIs, queues, and orchestration layers, the blast radius of a small error is no longer small. That is why sandboxed execution covering both Task Goal Completion (TGC) and Scenario Goal Completion (SGC) and realistic evaluation are starting to look less like best practices and more like table stakes.

Most public AI benchmarks still miss this reality. They focus on narrow tasks, static prompts, or clean data, and they often underweight the exact things that decide whether an agent survives production: multi-turn dependency, workflow fidelity, state carryover, recovery from failure, and behavior under enterprise constraints. In other words, they measure whether a model can answer, but not whether it can execute.

The core issue is compounding error. On short tasks, a model can get lucky or recover quickly. On long-horizon workflows, every step depends on the previous one, so a small mistake can remain invisible until the end, when it becomes an incorrect report, a failed reconciliation, or a broken automation. What looks like a minor hallucination at step three becomes a production incident at step twenty-seven.

That gap is the reason APIFlow-Bench exists, and it is designed to measure exactly that failure mode.

APIFlow-Bench asks a harder and more practical question: can an AI agent finish a real enterprise-style API workflow, end to end, without losing the thread? If the answer is yes, that tells us something meaningful about API readiness, workflow reliability, and the shape of agentic autonomy. If the answer is no, it tells us where the operational risk lives.

We are releasing it today with a public leaderboard and full transcripts: seven capability axes, exercised across 467 generated tasks: 226 dependent chains plus 241 standalone subtasks, over REST APIs in this first cut, each scored by a deterministic validator. The rest of this blog discusses how we built it and what mechanisms we used to verify the results.

What most current benchmarks measure

Agents are no longer just issuing tool calls; they are executing real workflows against real state, so the benchmark objective should be end-state correctness covering both TGC and SGC. A number of benchmarks have moved the field forward by evaluating agents in realistic environments. Some grade against final state, some simulate app behavior, and some focus on function calling or tool invocation. But most still cover only part of the problem.

State-based evaluation is the right default here: AppWorld for example scores task and scenario completion against simulated app state and explicitly tracks collateral damage, while τ-bench compares the final database state to the annotated goal state.

But end-state scoring is not enough for engineering analysis. A single pass/fail label collapses distinct failure modes into one bit: auth refresh, schema repair, retry discipline, state verification, and policy handling all look the same if the workflow either eventually succeeds or does not.

That is the core gap in most current benchmarks. For example, BFCL is useful for measuring function-calling correctness, but it is still a tool-use benchmark, not a recovery-and-repair benchmark; it tells you whether the model can emit the right call, not whether it can survive a 401, fix a rejected payload, retry safely, and confirm that the side effect actually landed.

Each prior benchmark covers a benchmark-specific slice, missing the whole API-engineering taxonomy as separate axes
covered across prior work our focus: under-targeted elsewhere
Benchmark stateful chain end-state / side-effect auth refresh pagination to end schema repair
AppWorld
τ-bench
Agent-Diff
BFCL v3
superglue API-Bench v2
APIFlow-Bench
scored as a first-class axis · exercised incidentally · not covered. Every prior benchmark covers part of the picture (AppWorld even targets pagination, and several grade end-state and statefulness well), but none we surveyed decomposes the API-engineering taxonomy into separately-scored axes, and two of the hardest modes (auth refresh, schema repair) look under-targeted across the benchmarks we checked. The five are the widely-cited result-graded and tool-calling benchmarks; marks fact-checked against each paper/docs: AppWorld arXiv:2407.18901 · τ-bench 2406.12045 · Agent-Diff 2602.11224 · BFCL v3 (Berkeley Function-Calling Leaderboard) · superglue API-Bench v2 (superglue.ai, vendor tool, not peer-reviewed). ✓/◐/✗ are our reading of each benchmark’s published task taxonomy; “incidental” = present but not separately graded.

What a better benchmark needs

Single score benchmark design should evolve into benchmark design that combines correct final state with diagnostic coverage of failure modes, so we can measure not just whether an agent completed the task, but whether it can survive the kinds of failures that break real workflows.

The benchmark standard for API agents should therefore be two-layered. First, preserve end-state fidelity: the agent has to leave the system in the correct state, with the correct side effects, and without collateral damage. Second, separately score the major engineering failure modes that determine whether the agent is robust in production.

That decomposition is what current evaluations usually lack. If you do not split out auth recovery, schema repair, retry behavior, state verification, and similar axes, you can rank agents by whether they “finish,” but you cannot tell which ones are resilient, which ones are brittle, and which ones only work on the happy path.

APIFlow-Bench is built around the idea that enterprise API work is not one skill. It is a collection of distinct competencies: authentication refresh, endpoint discovery, schema repair, error recovery, pagination, multistep execution, and state verification. A model that can call tools is not necessarily a model that can finish a workflow. A model that can finish a workflow once is not necessarily a model that can do it reliably across long chains.

That distinction matters. A benchmark should not just ask whether an agent got the final answer right. It should ask whether the agent navigated the workflow correctly, preserved state, and earned the result through the right sequence of actions.

APIFlow-Bench is designed around the gap between workflow completion and workflow robustness. It measures whether an agent can carry a long-horizon API workflow to completion, but it also makes the failure surface explicit: authentication, discovery, schema repair, multistep reasoning, error recovery, pagination, and statefulness are scored separately rather than folded into a single success bit.

What APIFlow-Bench measures

APIFlow-Bench evaluates seven capability axes:

Axis what it tests easy medium hard
authentication refresh / scope a token mid-session
discovery pick the right endpoint among look-alikes
schema repair a body the API rejects
multistep carry state across a chain of calls
error_recovery back off and retry correctly
pagination walk to the last page
statefulness confirm a side-effect actually landed
Seven capability axes: each one appears across the generated tasks at every creation-time difficulty (easy / medium / hard), composed forward into chains up to 20 dependent subtasks long.

These axes are not treated as incidental: they are scored directly, because enterprise failures are rarely generic, and the difference between a good agent and a broken one is often a single missed edge case.

That is why the benchmark uses realistic, failure-first tasks. A task begins the way a real developer ticket begins: with a broken call, an error hint, and a request to complete the workflow correctly. The agent is not given a toy prompt. It is dropped into a workflow that looks like the work teams actually hand to software today.

Every task is a similar request a developer would hand an agent

Tasks are initialized in a failure-first state, with the offending call embedded inline, similar to an API client binding the selected request payload. The same structural pattern is repeated across all seven axes:

Every task reads like a real ticket: failure-first, with the broken request pasted in

My nightly pull keeps 401ing against the readings API after the deploy. This call is the one that’s broken:

<request>
GET /v3/stations/stn-12/readings
headers: Authorization: Bearer tk_live_OLD_session
</request>
Error: {“error”:”token_expired”,”hint”:”refresh via POST /v3/oauth/token then retry”}

Refresh auth and get me the live reading for stn-12. I need the value and the reading ref.

Axis: authentication

We generate every task on purpose: for privacy, cost, and reproducibility

Every task is a synthetic workflow modeled on common enterprise API patterns; no user traffic is mined or replayed, and we deliberately generate every task end to end. That choice gives us three advantages. First, it protects privacy: no user traffic needs to be replayed. Second, it gives us scale: we can produce a large, graded, difficulty-controlled set far more efficiently than hand-authoring every workflow. Third, it makes the benchmark reproducible: the pipeline can be rerun to regenerate tasks, expand coverage, or create a fresh private set.

Generation also creates a harder requirement: we have to prove the tasks are valid, solvable, and not easy to game. So the benchmark is built around two questions:

  1. Is the task fair and actually solvable?
  2. If a model passes, did it really do the work?

APIFlow-Bench addresses both.

How the benchmark is built

At the simplest level, APIFlow-Bench is a contract between the benchmark and any backend that implements it.

The action space is deliberately compact:

  • 7 tools
  • 5 entity kinds
The whole action space: 7 tools × 5 entity kinds

7 tools

readwriteeditsearchexecuteclarifyreport_blocked

5 entity kinds

requestresponsevariablespechandle
The tools are polymorphic on entity kind (read a response and read a spec are the same tool), so the action space stays at seven no matter how many entity types a backend registers. A canary UUID sits in every task header, and a private task layer is held out against contamination.

The tools are polymorphic across entity kinds, which keeps the interface stable even as the backend grows. That means the benchmark can be implemented across different systems without changing the underlying evaluation logic.

Each task is generated inside a sandboxed mock environment, with a canary UUID embedded in the task header and a private task layer held out to reduce contamination. The sandbox is not just a safety layer; it is also part of the measurement strategy. It gives us full control over difficulty, state, and failure conditions, so errors surface in evaluation rather than production.

The pipeline enforces validity as a first-order constraint; the grader audit then verifies that a nominal pass corresponds to completed work, not just a satisfied check.

How grading works

The most important design principle in the benchmark is simple: grade the result, not the answer string.

The obvious grader is a substring check: does the agent’s final answer contain the expected value? It is tempting: you control what that value is. But it breaks in two opposite ways at once:

One substring check, two ways to be wrong

Two ways a substring check fails: it rejects a correct answer formatted differently, and it passes a lucky coincidence.

The fix is not a better regex: it is to stop grading text.

A substring check is not enough. The right value for the wrong reason is not a pass, and a correct value phrased differently should not fail. So APIFlow-Bench avoids text-only grading and instead evaluates two independent surfaces.

  • State: the first surface checks whether the work actually happened. The benchmark looks for an earned canary value in the agent’s final workspace state and traces that value back to the response it had to come from. This data-flow check is what makes the pass meaningful.
  • Answer: the second surface checks whether the user received the requested result. The agent must declare its final answer in a structured answer card, which is compared field by field using typed comparison rather than string matching.

A run passes only when both surfaces succeed. State proves the labor. The answer card proves the user got the result they asked for.

Why this is stronger than a leaderboard score

A leaderboard can tell you which model scored higher. It cannot always tell you why.

That is why APIFlow-Bench separates deterministic validation from deeper provenance checks. The deterministic grader confirms the earned value is present and typed correctly. A parallel verifier can inspect whether the result looks legitimately earned rather than narratively reconstructed. In other words, the benchmark is designed not just to reward the right output, but to discourage the wrong kind of right output.

That matters because enterprise evaluation should be closer to an audit than a trivia game. In production, a model does not get credit for sounding plausible. It gets credit for doing the work.

So we follow the rule: grade the result the user wanted, never the route taken, and prove it with a value the agent could only have earned. That value is a canary: distinctive, hard-coded in the mock backend, reachable only on the correct path, and different on every decoy (the deprecated /v1 route returns other numbers; the summary endpoint a rounded one). The value is normalized for format (48210 == 48,210 == $48,210), so punctuation never sinks a correct answer, and it is distinctive enough that coincidence can’t supply it. A pass then requires two independent surfaces:

A pass requires both the state and the answer to check out
G1 (Grader 1) · stateG2 (Grader 2) · answerPASS
Surface What it proves How it’s checked
G1: state the work happened the earned canary value turns up in the agent’s final workspace state (something it fetched, stored, or wrote), and a data-flow check ties that value to the API response it had to come from. The canary is mock-minted and unique to the correct path, so finding it is proof the agent made the real call, not luck, and not a guess
G2: answer the user got the answer a typed answer-card: the agent declares its final answer as JSON, compared field-by-field with a typed comparator (numeric / currency / string / set), not a substring scan
Pass = the state check AND the answer check. State (and the data-flow tracing its values back to the real call) proves the labor; the answer-card proves the user was actually served. Checkpoints (e.g. “did it back off after the 429?”) are recorded for diagnostics but never decide pass/fail: only the result does. No eighth tool: the answer-card is parsed from the final message.

The deterministic grader checks the value; the LLM verifier looks for suspicious provenance

The deterministic validator already enforces that the required value is present, well-typed, and, via data-flow tracing, actually derived from the originating response. What it cannot fully resolve are the higher-order correctness checks: unit consistency, decimal placement, and whether the agent genuinely earned the number rather than producing a superficially plausible one. A parallel LLM verifier therefore re-evaluates the same target values for unit correctness, decimal placement, and provenance, and its design functions as a one-way valve.

By design a one-way valve: it could only ever close a pass, never open one (advisory in this run, so it changed nothing)

The advisory LLM verifier is a one-way valve: it can only turn a deterministic pass into a fail, never the reverse.

The diagram is the design: what the flag would do if it were enforced. A flag means the LLM verifier judges a deterministic pass as one that should have failed. In this run the flag was not enforced: the LLM verifier is advisory only and does not change leaderboard scores, so the published board is the deterministic grader’s alone and every flag is left for a human to review (the results section reports what it caught).

From a single task to a dependency chain of subtasks, interpret the structure as three nested hierarchy levels

The generator instantiates a synthetic world, then forward-propagates a dependency chain of subtasks across that same world state; only a subtask that the real harness can actually solve is permitted to seed the next step. Read the pipeline as three nested layers.

Three levels, zooming in: the chain → one subtask → the pieces a subtask leans on

Three nested levels of the generation pipeline: the chain, one subtask, and the shared components.

The structure at each level is recursive: a chain comprises a sequence of subtasks, each subtask comprises a sequence of steps, and the steps rely on a small shared set of components.

The chain: N subtasks, each seeded from the last one’s real, solved end-state

A single shared world S₀ is initialized once and propagated through the entire chain. The generator then instantiates subtasks sequentially, with each subtask seeded from the verified end state of the previous one, Sᵢ, defined as the agent’s workspace plus the mock’s accumulated side effects from a run that actually passed. A coupling ledger tracks cross-subtask dependencies: an early “plant trap” subtask mints a server-generated identifier, and a later “trigger trap” subtask must consume that exact identifier.

Level 1 · the forward chain: subtasks grown left→right, each seeded from the previous verified end-state Sᵢ

Level 1: the forward chain, where each subtask is grown from the previous subtask's verified end state.

Unrolled view (top→down). Read each column top→down: top = input (world S₀ + subtask plan) → middle = the “cell” that builds one subtask; its carried state is the end-state Sᵢ → bottom = output (one solo task). The hidden state Sᵢ flows left→right from cell to cell; the long arc over the top is a coupling that spans subtasks: subtask 1 creates an id that subtask 3 later reuses. Once every subtask is accepted you have the full chain, which is then turned into the chain tasks.

One subtask consists of a gated step loop that must complete successfully before the next subtask is instantiated

Zoom into one cell of the chain: two gates must be cleared before any model is scored. A deterministic self-test that validates the grader, and a real-harness solve that confirms the subtask is solvable with pass@10 at least 3. A subtask then begins from the previous subtask’s workspace state, is proposed with explicit connection constraints, and is graded, audited, self-tested, written out, and solved N times before acceptance. If it clears the threshold, its resulting end state Sᵢ is saved, and any deferred dependency needed by a later subtask is opened or resolved.

Level 2 · inside one subtask: the gated step flow (Step 0–8)

Level 2: the gated step flow inside one subtask, from plan resolution through replay checks.

Level 2 · one subtask’s internal component flow (top→down). The orange back-edges are two kinds of feedback. Step 3/4 → Step 2 (short edge): if the audit or self-test fails, redesign the validator once, then re-run. Step 7 → Step 1 (long edge): if the solvability gate fails, repair in place (≤ 3 rounds), then tear down and re-propose the subtask (≤ 1), and if it still won’t pass, truncate the chain and ship at the last solid subtask. These are the feedback edges this otherwise top-down flow needs.

The shared components each step relies on are built once, threaded through the workflow, and verified at the end

The two loops rely on a small shared set of components: two inputs that start the chain at Step 0, two state carriers that pass state from Step 8 back to Step 0, and two final-stage components that run only after the full chain is built.

Step 0 (input) · plan resolution: per-subtask axis / difficulty / coupling

Plan resolution: the axis, difficulty, and coupling sequences all derive from one random seed for reproducibility.

All three sequences come from one random seed (for reproducibility). One guard applies only to the axis line: it inspects the plan to find which subtasks are seeded to create resources, and forces those onto a resource-creating axis; the difficulty sequence and the coupling plan feed straight into the per-subtask plan, bypassing that guard, so the three lines map exactly to the axis, difficulty, and coupling rows in the box on the right.

Step 0 (input) · build the initial mock-API environment (state S₀) + 5 deterministic checks

Building the mock-API world: five steps with one frontier-LLM call, then five deterministic checks.

Left: building the world (5 steps, one Frontier-LLM call). Right: 5 deterministic checks adjust the mock API’s routes for each task category (authentication, schema, and so on). S₀ is an in-memory object; the YAML task files are generated later, in a separate build step.

Step 8 · the coupling ledger: one subtask creates a resource (plant), a later subtask consumes it (trigger)

The coupling ledger: one subtask plants a resource and a later subtask must consume exactly that resource.

One subtask creates a resource and records it as a pending dependency; a later subtask takes that resource, consumes it, and satisfies the dependency, forming the plant→trigger arc shown in the diagram.

Step 8 → Step 0 · save the resulting state (Sᵢ) and use it as the starting point for the next subtask

Each subtask passes its variables and verified end state forward to the next subtask in the chain.

Each subtask passes two things forward to the next subtask: the variables it produced, and the changes it made to the mock server’s state. The random seed is deliberately left unchanged, and the reference solution also saves the correct final state that answers are checked against.

After the chain · turn it into finished tasks: both single-subtask (solo) and full-chain tasks

Turning the chain into finished tasks: each cut point becomes one chain task plus standalone subtasks.

Build the tasks by taking, for each cut point k, the first k subtasks and packaging them into a single chain task. The instruction is compressed into one goal that does not leak the solution; the success check is assembled selectively from the final subtask’s answer check, the final subtask’s state check plus any earlier dependency-critical state checks, and all subtasks’ diagnostics; the mock server combines the setups from subtasks 1 through k; and chain annotation uses one Frontier-LLM call to label the chain’s overall capability and difficulty.

After the chain · write out the chain file and run the final replay check that decides whether it ships

Golden replay: the full-chain replay must pass and the sabotaged replay must fail before a chain ships.

Golden replay requires two checks: the forward full-chain replay must pass, and the negative replay, with only the terminal subtask and earlier evidence removed, must fail. The negative check is applied only when a later subtask genuinely depends on an earlier subtask’s result; chains without that dependency run the forward check only. Static checks also run on the task definition: a leaked random seed blocks publishing, and a missing pass/fail condition blocks publishing only when the answer could be guessed trivially, otherwise it is just a warning.

We hand the grader a blank exam, an answer key, and a sabotaged exam, then watch how it reacts

A grader can be present-but-meaningless: a check that fires no matter what it’s handed reports a pass that means nothing. A zero-LLM self-test triad (Step 4 of the subtask loop above) rejects that mechanically, before the task ever reaches the solvability gate:

A check that still passes when its own evidence is destroyed is the one that voids a benchmark, so we destroy it on purpose
1

Blank exam

agent did nothing

must FAIL

Catches a check that passes on an empty workspace.

2

Answer key

the reference solution

must PASS

Catches a check that rejects the truth.

3

Sabotaged exam

each check’s own evidence, corrupted

must FAIL

Catches a check that asserts nothing.

Blank-fails and key-passes are table stakes; many broken graders pass both while still being toothless. Corrupting each check’s specific evidence and demanding that check break is what proves every assertion is load-bearing.

An oracle must solve every task before any model is scored

Each subtask goes through a solvability gate in the exact same harness used for leaderboard scoring: a strong oracle solves it ten times in parallel, and the subtask is accepted only if it reaches pass@10 ≥ 3. If a subtask falls short, it is repaired up to 3 times; if that still fails, it is discarded and replaced with a fresh subtask rather than an easier one, and if it still cannot pass, the chain is truncated at the last solid subtask instead of being padded with a broken one. The assembled chain is then validated by the golden-replay check, and every shipped chain passed this process.

The per-subtask solvability gate: ten attempts, then repair, then teardown, never an easier task

The per-subtask solvability gate: ten oracle attempts, then repair, then teardown if it still fails.

The oracle must solve each subtask in the exact harness that later scores it: zero drift. A subtask under pass@10 ≥ 3 is repaired in place (≤ 3 rounds), then torn down and re-proposed (≤ 1); if it still won’t clear, the chain is truncated and shipped at the last solid subtask rather than padded with a broken subtask; difficulty is never lowered. The assembled chain is then proven end-to-end by golden-replay before it ships.

Three checks are easy to conflate: (1) during generation each subtask is oracle-solved (pass@10 ≥ 3); (2) the assembled chain is proven by deterministic golden-replay of its reference solution, not by an end-to-end model solve; (3) the leaderboard in the results section is the separate model evaluation. Only (3) measures the models; (1) and (2) only decide whether a task is fit to ship.

Every gate must be discoverable, or it penalizes calibrated abstention

A tempting way to make a generated task seem hard is to hide an undocumented requirement, such as a mandatory header that is never revealed by any error message. We forbid that.

An undiscoverable trap penalizes the well-calibrated model the hardest

Discoverable gate ✓

The requirement is learnable: from the served spec, or a specific, truthful error hint. A capable model infers the path and proceeds. Harder = more inference.

Hidden trap ✗

No path is visible. A reckless model guesses and might get lucky; a calibrated model correctly stops and reports itself blocked, and is marked wrong. Harder = more guesswork.

The trap inverts the incentive: it rewards reckless guessing and punishes calibrated abstention. So the rule is absolute: every gate on the success path must be learnable from the served spec or a truthful error hint. This is also why we track abstention as a first-class signal, not just a wrong answer.

The proof: we attacked our own grader

The gates still need an adversarial audit, so we tried to cheat our own grader

The gates above define how a task should be valid; whether they actually held is an empirical question that we answer only by attacking the finished grader. The grader was given to an independent reviewer whose sole job was to break it, separate from the person who built it.

One attack constructed a correct solution that the grader would wrongly reject (a false negative), and another a wrong answer that the grader would wrongly accept (a false positive). Each claimed hole was then manually confirmed against the live mock. Six attacks succeeded, all instances of the same failure mode: the grader was scoring something other than the work the model actually earned.

Those attacks drove fixes that hardened the grader used for the 1.0 run, and from there every generated chain ships only after it passes the golden-replay check described above.

What an adversarial audit of our own grader turns up, and the fix for each
Axis Class The exploit The fix
schema false neg A creation POST returns 201, but the check pinned 200, so the minimal correct solve fails accept the real success code ([200,201])
schema false pos The graded value was echoable: present in a payload the agent could copy without fetching it remove the echo; pin a distinct canary the mock only serves on the real path
statefulness false neg A currency comparator demanded “USD” the agent had no source for: correct numbers rejected for a missing unit grade numerically; stop forcing a hallucinated unit
pagination false pos The total was served on a summary endpoint: passable without paging at all remove the leak; a terminal-page marker forces the full walk
multi-step false pos The final canary was reachable by guessing one URL, skipping the chain gate the value behind stateful mock logic + a non-guessable id
multi-step false pos A value was readable before the publish step that was supposed to produce it gate the read on the publish; add chain-level checks to the state check
Every fix was re-verified by booting the real mock server and running both the exploit and the honest solve: the exploit must now fail, the honest solve must still pass. Every number in this note is from after this pass.

Every hole we found was a gap in how the doctrine was applied, not in the doctrine itself, which is the realistic way any grader fails. A self-test triad and a solvability gate can tell you the design is sound, but only an adversarial read of the finished grader can tell you whether it was actually applied correctly in practice. That audit surfaced issues the automated gates missed.

The same task, a pass and a fail, and why the fail fails

A near-miss that did the work but fumbled the hand-off is graded a fail, correctly

Both runs walk the identical path (dimmed): they part only at the final hand-off (highlighted).

PASS
refresh token → POST /v3/oauth/token
GET /v3/stations/stn-12/readings
  → 200 {value: 63.5,
         reading_ref:"telem-9f3a-2201"}
answer-card:
  {"reading": 63.5,
   "ref": "telem-9f3a-2201"}
G1 canary in state · G2 answer-card matches
FAIL
refresh token → POST /v3/oauth/token
GET /v3/stations/stn-12/readings
  → 200 {value: 63.5,
         reading_ref:"telem-9f3a-2201"}
final message (prose, no card):
  "The live reading is about 63.5."
G1 canary in state · G2 no ref, no typed card
Both runs fetched the correct value from the API, so the state check passes for both. The right column never declared the structured answer the user asked for (it dropped the reference id and buried the number in prose), so the answer check fails and the run fails. The answer-card is a thin, declared contract, not an arbitrary schema: the user asked for the value and the ref, so returning them as named fields is part of finishing the job. Doing the work and delivering it are different skills, and a workflow benchmark scores both. An illustrative example, not a verbatim transcript; the structure mirrors real ones.

What we found, and what the numbers say

You cannot fairly force a frontier model to fail, so instead we measure how much the models spread apart on the same tasks

We wanted “hard” tasks, and the obvious move was to stack more obstacles: extra auth walls, tighter rate limits, more decoy routes. But every candidate task has to clear the solvability gate above (a frontier-strength oracle solving it ten times), and under that gate this strategy always collapsed into one of two cases. If an obstacle was discoverable, the oracle inferred the path and kept solving the task round after round, so nothing got harder in practice. If an obstacle was undiscoverable, there was no path at all: the oracle hit a dead end, correctly reported that it was blocked, and the pass rate dropped to zero.

Neither of those outcomes is genuine difficulty. The first changes nothing; the second is just a broken task. The uncomfortable result is that a low pass rate, by itself, cannot distinguish “legitimately hard” from “broken.” A fair, discoverable task is one a capable model usually solves; pushing it below that bar means either hiding information (unfair) or breaking the task (worthless).

What is missing from those two outcomes is any stable middle. For a frontier model, “discoverable yet still hard” almost never exists: if the path can be inferred, it infers it. That middle does exist for weaker models, and that asymmetry is what difficulty is actually for. The job of a hard task is not to make the best model fail; it is to separate models. A task the best model passes nine times out of ten while a weaker one passes once is a far better measurement instrument than a task nobody can solve.

We call that separation spread, and when we measured it, it did not come from stacked obstacles at all; it came from chain length. Put nineteen models (frontier and open-weight) on the same workflows: on short chains they cluster near the top, but stretch the chain to twenty dependent subtasks and their scores fan out from 44% to 73%. That fan-out is where the measurement really lives.

Each dot is one model’s pass rate on one task set (ties stack vertically): gray dots are closed frontier models, green are open-weight. Hover a dot to trace one model across all five sets; click to pin a trace and compare up to two models. Solo subtasks barely separate the panel: eighteen of the nineteen models land between 88% and 97% (gpt-5.4-mini sits at 77%). Each added chain length slides the whole panel down, and by twenty subtasks it has fanned out from 44% to 73%. The gray and green dots stay interleaved at every length: the top is not a frontier-only club. source: this run; per-model pass rates on the solo set and the 5/10/15/20-subtask chain sets

Refusals aside, almost no failure was a give-up: the agents did the work and missed the final answer

Almost no failure was a give-up: 402 of 409 failures were wrong final answers, and a typical run took 13 tool calls

Of 409 failures, 402 were wrong final answers and 7 were abstentions; a typical run took 13 tool calls.

Because every gate is discoverable, a model that stops and says “I’m blocked” is making a defensible call, but on these 20-subtask chains almost none did: 7 of 409 failures (1.7%) were abstentions. The remaining failures are overwhelmingly wrong final answers, and 169 of them are runs where the agent drove the workspace to the right state yet reported the wrong final answer. The long-horizon tax is losing the thread at the final subtask, not giving up. The tool-call distribution (median 13, max 168) confirms genuine multi-step work. source: the 20-subtask-chain slice, 19 ranked models; abstention = agent reported itself blocked

A cheap open-weight model keeps pace with the frontier

Point estimate (dot) and 90% confidence interval (CI, the whisker) per model, on the eleven 20-subtask chains. The interval is a cluster bootstrap that resamples the 11 worlds (one per chain), keeping each world’s five epochs together, because epochs of one chain are not independent draws; treating all 55 runs as independent would understate the interval by roughly half. At a true n of 11 worlds the intervals are wide and all nineteen overlap from top to bottom: the only defensible statement is the ordering of point estimates, not that any one model beats another. The useful signal is the pattern: the frontier gpt-5.5 leads at 72.7%, but a cheap open-weight model (deepseek-v4-flash) ties for second at 69.1%, and two more open-weight models, glm-5p2 and qwen3p7-plus, share fourth at 65.5%, so the top is not a frontier-only club. claude-fable-5 is not ranked here: a safety-filter artifact declined 87.8% of its runs at the API layer before any work began (on the runs it did engage, it passed 90.9%). source: 1,045 ranked runs (19 models × 11 chains × 5 epochs) on the 20-subtask chains; 2000-sample world-level cluster bootstrap

Each cell is one 20-subtask chain (one world) × one model, five epochs (n=5). Rows are sorted hardest-first, and the split is by axis, not model: the authentication chains are red across the whole panel (each requires re-authenticating against a credential store, repeatedly, across twenty subtasks, a 6% pass rate overall), while the statefulness chain is green for all nineteen models, and pagination for all but two small models. So at twenty subtasks the discriminator is which capability the chain stresses, far more than which model runs it, but this is a small, uneven per-axis sample (authentication = 3 of the 11 worlds, statefulness and pagination = 1 each), so read it as this 20-subtask slice, not a verdict on the whole capability. claude-fable-5 is excluded here, as in the leaderboard above. source: the 1,045 ranked runs on the 20-subtask chains; rows = world·dominant-axis

The two graders agree on 733 of 935 runs of the original panel, and where they split, the deterministic grader is the stricter judge

The two graders agree on 733 of 935 runs; most disagreements are deterministic fails the LLM judged defensible.

The two graders agree on 733 of 935 20-subtask-chain runs (78.4%), measured on an earlier cut of the panel; the comparison was not rerun for the models added later. The split is one-sided and tells you which grader is conservative: 198 of the 202 disagreements are runs the deterministic grader failed but the LLM judged defensible: it refuses a right-looking answer without proof of the work (the correct final state plus a valid data-flow through the subtasks), and the advisory LLM cannot rescue them. Only 4 went the other way (a deterministic pass the LLM flagged as suspect-provenance, left for human review). A verifier that agreed 100% would be decorative. Read this as an advisory disagreement analysis, not validity evidence: the LLM decided no score, and the 4 suspect passes are flagged for human review, not adjudicated here.

What a high score here doesn’t buy, and where the bench goes next

This APIFlow-Bench run still sits inside four clear limitations. The table below breaks down those constraints and shows where the bench goes next.

Four limitations bound this run

small n

The headline is 11 twenty-subtask chains, five epochs each across the nineteen ranked models (1,045 runs), the 11 of 13 chains that reached a full 20 subtasks (two of the others were cut short and shipped anyway: one at 5 subtasks, one at 14). With per-chain CIs this wide the top overlaps: read it as a tie, not a standing. The full bank is 467 tasks.

REST only

This release covers REST APIs. GraphQL and MCP (Model Context Protocol) are on the roadmap but are not measured here: no multi-protocol claim.

19-model panel

Nineteen models (frontier and open-weight) chosen to span the field, not a census; six were added later on the identical harness and bank. Absolute rankings would shift with a different slate; what is robust is that spread comes from chain length, not model size.

not a product score

A vendor-neutral score on a generic agent contract, not a measure of any product. It cannot see code quality, latency, cost, or whether the agent would be safe to run unattended.

Three directions come next, each aimed at a limitation above:

Where APIFlow-Bench goes next: deeper, wider, bigger

① Deeper than 20

Every task comes from a forward-built chain of up to 20 dependent subtasks, and the 20-subtask slice already spreads the models apart (pass rates ranging 44–73%). Next: past 20 subtasks and mixed chain shapes (branches, retries) where frontier models may separate more clearly.

② More protocols

REST in this cut. The action space (7 tools over 5 entity kinds) is protocol-agnostic, and the generator already supports GraphQL and MCP environments, so the same result-based grading can extend to the two other protocol surfaces agents work against.

③ More tasks

467 tasks across 13 worlds is still a pilot, and the headline 20-subtask slice is only 11 chains. Tasks are generated, not authored, so adding more worlds mostly means running the generator and validation pipeline, not hand-authoring tasks: finer difficulty resolution and world-level CIs tight enough to rank.

Why this matters beyond APIFlow-Bench

The most revealing part of the benchmark is chain length. As workflows get longer, the gap between models widens. Short chains tend to compress performance. Longer chains expose whether an agent can preserve context, maintain consistency, and recover from intermediate failures without losing the final objective. That is where the benchmark starts measuring something closer to real autonomy.

This is also where APIFlow-Bench becomes more than a benchmark. It becomes a stress test for the transition from conversational assistance to operational execution. If a model can stay reliable across many dependent API steps, that is a strong signal that it can participate in enterprise workflows in a way that matters.

We do not think of APIFlow-Bench as a final answer. We think of it as a sharper signal.

A strong result on one benchmark does not magically transfer to every domain, every tool stack, or every regulatory environment. But if models improve on realistic API workflows, that is a meaningful sign that their agentic reliability is improving in ways enterprises can care about. It tells us something about how much state they can carry, how well they can recover, how reliably they can execute under constraints, and how far they can go before human intervention becomes necessary.

That is the bar we should be raising across the field. Benchmarks should not simply measure whether an agent can produce a plausible completion. They should measure whether it can complete a workflow that resembles production work, under realistic constraints, with a result that can be trusted. That is the standard APIFlow-Bench is trying to set.

What comes next

APIFlow-Bench is deliberately open and extensible. The current release focuses on REST workflows, but the same evaluation pattern can extend to GraphQL, MCP, and other protocol surfaces. The bigger goal is not to crown one benchmark as definitive. The goal is to build a clearer language for measuring agent readiness across many realistic workflows.

That is the standard APIFlow-Bench is trying to raise. The benchmark is not only about ranking models. It is about defining a more serious evaluation target for agentic systems: API readiness as a measurable property of workflow reliability.

If agents are going to participate in enterprise systems, we need benchmarks that can tell us whether they are actually ready for the APIs that run those systems. APIFlow-Bench is our contribution to that standard.


APIFlow-Bench · a vendor-neutral agentic-API benchmark over REST · Postman Research.
Three runs on the identical harness and bank, merged: the 13-model run (2026-06-29) plus extensions on 2026-07-02 and 2026-07-18. 44,362 trials across the ranked models, a near-complete but not perfect 19 × 467 × 5 grid (44,365 cells expected), temperature 1.0. The Frontier LLM used throughout (to generate the tasks and as the solvability oracle) is Opus 4.8. The headline leaderboard is the 11 full twenty-subtask chains (19 × 11 × 5 = 1,045 ranked runs). Confidence intervals are a 90% cluster bootstrap over the 11 worlds, 2,000 resamples. All figures are from this run unless marked illustrative.

What do you think about this topic? Tell us in a comment below.

Comment

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.