Console
API reference/POST /v1/parallel/findall/runs

POST /v1/parallel/findall/runs

Parallel FindAll: a verified list of the companies or people that match your conditions, as a job, preview first; and Entity Search, a quick ranked list at $0.005.

/llms.txt

Parallel FindAll and Entity Search. Parallel's FindAll builds a verified list of entities (companies, people, products, anything you can name) that match conditions you write in plain language. For each candidate it finds, it checks every condition against the web and answers with the evidence: citations, reasoning and a confidence. A run takes from about 30 seconds to two hours, longer than any request can stay open, so a run is a job:

  1. 01
    POST /v1/parallel/findall/runs creates it and answers at once with a run object;
  2. 02
    GET /v1/parallel/findall/runs/{id} reads it until its status is completed (or failed, or cancelled), or GET .../{id}/events streams candidates as they are found and checked;
  3. 03
    GET /v1/parallel/findall/runs/{id}/result reads the candidates, at any time.

Entity Search (POST /v1/parallel/findall/entity-search) is the quick version: one request, a ranked list of up to 100 people or companies with a name, a URL and a short description, in a second or two, with no conditions checked.

The field names are Parallel's, so Parallel's FindAll docs apply to the body you send, within the limits below.

Note

What you send goes to Parallel, a third party, which may use it and the answer to improve its services and stores data in the US. Do not send what you would not share with Parallel. See Data.

Who can use it

An organization API key of a paid organization: a key you created in API keys for an organization that has added paid credit. Playground and evaluation keys, and organizations still on the free trial, get 403 forbidden: "Parallel FindAll needs an organization API key from a paid organization: create one in API keys and add paid credit in Billing". Nothing is reserved or sent. This applies to Entity Search too.

FindAll runs and Entity Searches are billed to your organization's credit. A key limited to your own provider keys or to a routing policy cannot spend it, so a create or an Entity Search with such a key is a 403 forbidden too: "This API key is limited to its own provider keys or a routing policy, and Parallel FindAll and Entity Search are billed to marketplace credit: use an organization API key without that limit. A routing policy set on the organization or workspace applies to every key, so an owner must change it in the console". Nothing is reserved or sent. Reading runs is unchanged.

Start with a preview

A preview run costs $0.10 and checks a handful of candidates, so you can see whether your conditions find what you mean before you pay for a full run:

bash
curl https://api.routerplus.com/v1/parallel/findall/runs \
  -H "Authorization: Bearer $TM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "objective": "Find companies that offer managed PostgreSQL hosting",
    "entity_type": "companies",
    "match_conditions": [
      {"name": "managed_postgres", "description": "The company offers a managed (hosted) PostgreSQL database service."}
    ],
    "generator": "preview",
    "match_limit": 5
  }'
json
{"id": "pfrun_6f0c1e2d3a4b5c6d7e8f901a2b3c4d5e", "object": "parallel.findall_run", "status": "queued",
 "generator": "preview", "match_limit": 5, "enrichments": [], "termination_reason": null,
 "metrics": {"generated_candidates_count": null, "matched_candidates_count": null},
 "max_cost": 0.1, "cost": null, "created_at": "2026-11-06T01:47:13.980Z", "finished_at": null, "error": null}

Read it until it ends (our previews took 30 to 90 seconds):

bash
curl https://api.routerplus.com/v1/parallel/findall/runs/pfrun_6f0c1e2d3a4b5c6d7e8f901a2b3c4d5e \
  -H "Authorization: Bearer $TM_API_KEY"

Then read the matches:

bash
curl "https://api.routerplus.com/v1/parallel/findall/runs/pfrun_6f0c1e2d3a4b5c6d7e8f901a2b3c4d5e/result?match_status=matched" \
  -H "Authorization: Bearer $TM_API_KEY"

If the matches are what you wanted, create the same run with "generator": "base" (or core, or pro) and a larger match_limit. A run cannot be extended: see Extend and enrich.

Prices

Parallel's list price, with no markup. A run costs a fixed fee for its generator plus a fee for each match it returns, plus, for each enrichment, the enrichment's processor price for each match it enriched:

GeneratorFixed feePer matchLargest match_limit
preview$0.1$010
base$0.25$0.03825
core$2$0.15153
pro$10$115
Enrichment processorPer enriched match
lite$0.005
base$0.01
core$0.025

A preview run's match_limit (5 to 10) counts the candidates it checks, not the matches, and its matches are free; only its fixed fee is charged (and its enrichments).

Two numbers on every run object, in USD:

  • max_cost, set at create: the most the run can cost, fixed + match_limit × (per match + each enrichment's price). The gateway holds this from your credit while the run is open, as it holds any request's maximum cost (see Pricing). Without that much credit the create is the usual 429 insufficient_quota, and nothing runs.
  • cost, set when the run ends: what you were charged, fixed + matches × per match + Σ (matches enriched × the enrichment's price), where matches is Parallel's matched_candidates_count, never more than match_limit. The rest of the hold is released. cost is null until the run ends; it is never more than max_cost.

For example, a base run with match_limit 20 and one lite enrichment has max_cost $0.25 + 20 × ($0.03 + $0.005) = $0.95; if it ends with 12 matches, all enriched, its cost is $0.25 + 12 × $0.03 + 12 × $0.005 = $0.67.

Every run that Parallel accepted is charged by this formula, however it ends: completed, cancelled (the work done before it stopped) and failed (the work done before it failed). If we can no longer read how a run ended (Parallel stops answering about it, or no longer has it), the formula uses the last counts we read. A run Parallel refuses at create is not charged.

The one exception: if Parallel never answered a single status read for the run after it accepted it, we cannot know what it did, and the run is charged its max_cost. If Parallel reports how the run ended within 24 hours after its time limit, the run takes that end, its cost the formula, and the difference is credited back to your balance, once. A run Parallel no longer has will never report its end, so it is not credited back.

The hold cap

A run may hold at most $25. A create whose max_cost would be more is a 400 invalid_request that says the largest match_limit that fits, for example "match_limit: this run's worst case is $30.00, over the $25.00 a run may hold; the largest match_limit that fits is 15". The largest match_limit per generator is in the price table above (without enrichments; enrichments lower it). For more results, run several searches with an exclude_list of what you already have.

Create a run

The body, at most 256 KB:

FieldRequiredWhat it takes
objectiveyesWhat you are looking for, in plain language: 1 to 5,000 characters
entity_typeyesWhat kind of thing, such as companies or people: 1 to 200 characters
match_conditionsyes1 to 10 conditions, each {"name", "description"}. A name is 1 to 64 letters, digits or underscores, unique in the run; a description is 1 to 2,000 characters and says what must be true
generatoryespreview, base, core or pro
match_limityesHow many matches to find at most: 5 to 1,000 (5 to 10 for preview), within the hold cap
exclude_listnoUp to 1,000 entities to leave out, each {"name", "url"}: a name up to 300 characters, a URL up to 2,000
enrichmentsnoUp to 2 enrichments, each {"processor": "lite" | "base" | "core", "output_schema": {"type": "json", "json_schema": {...}}}. Each matched candidate is researched once more for the fields in the schema (at most 16 KB). The schema's property names must differ from the condition names and from the other enrichment's; at most 1,000 fields in all the enrichments' schemas together

Refused with a 400 invalid_request that names the field, before anything is held or sent:

FieldWhy
webhookNot supported: read the run, or stream its /events
memory_scope_keyRouterPlus does not use Parallel memory
metadataRouterPlus sets the run's metadata itself
mcp_serversA run cannot call MCP servers through RouterPlus
any other fieldUnknown

So is an enrichment schema no answer can satisfy, such as an empty enum or a required field that properties does not define.

Read a run

GET /v1/parallel/findall/runs/{id} answers the run object:

FieldMeaning
idOur id, pfrun_ and 32 hex digits. Parallel's own run id is never shown
objectparallel.findall_run
statusqueued, running, completed, failed or cancelled
generator, match_limitAs sent
enrichments[{"processor"}], one per enrichment Parallel accepted. If Parallel refused an enrichment right after the create, it is missing here (for example []), is not charged, and the run goes on without it: check this field in the create's answer
termination_reasonWhy the run ended, Parallel's word: match_limit_met, low_match_rate, candidates_exhausted, error_occurred, timeout, user_cancelled or insufficient_funds; null while it runs. insufficient_funds is about our account at Parallel, not your balance: the run is charged for the work done; contact support if you see it
metrics{"generated_candidates_count", "matched_candidates_count"}: the candidates found so far and how many matched; null until we first read the run's status from Parallel
max_cost, costSee Prices
created_at, finished_atRFC 3339 times; finished_at is null until the run ends
errornull, or {"code", "message"} when the run did not end normally: run_failed; run_cancelled (Parallel stopped it for a reason of its own; your own cancel shows status cancelled with error null); action_required; run_timeout; or run_expired (Parallel no longer has the run: its results are gone, and it was charged for the matches we last saw, or its max_cost if we saw none)

The run's cost is always what you were charged; error.message never says.

Read the result

GET /v1/parallel/findall/runs/{id}/result works in any state: it is a snapshot of the candidates so far. It answers {"id", "status", "candidates": [...]}, each candidate:

FieldMeaning
candidate_id, name, url, descriptionThe entity
match_statusgenerated (found, not yet checked), matched, unmatched or discarded
outputPer condition and enrichment field: {"value", "type", "is_matched"} (type is match_condition or enrichment; is_matched only on conditions)
basisPer field: {"field", "citations": [{"url", "title", "excerpts"}], "reasoning", "confidence"}. Not on unmatched candidates

Add ?match_status=matched for the matches only. The snapshot holds at most 5,000 candidates; a result over 10 MB is a 502 result_too_large.

Save the matches soon after the run ends. RouterPlus keeps no results: each call reads them from Parallel again. Parallel does not publish how long it keeps a run's results (in our tests they were all still there after an hour; we have not checked longer). If Parallel has dropped a run, the run shows failed with run_expired, and a result read answers 502 upstream_error.

You see only the matches you are charged for: at most match_limit while the run is open, and once it has ended, the number of matches its cost counts. Parallel can go on finding matches after a run ends or is cancelled; those are not charged and not shown. Enrichment fields appear only on those matches, and once the run has ended, each enrichment only on as many matches as its cost counts. While a run is being cancelled you may see matches that are not charged in the end: read the result again after the run ends, and keep that copy.

Stream events

GET /v1/parallel/findall/runs/{id}/events is a server-sent event stream for up to 570 seconds; open it again to go on. Each event's data is JSON:

typedata
findall.status{"type", "event_id", "timestamp", "run"}: run is the run object above. Sent about every 10 seconds and when the status changes
findall.candidate.generated, .matched, .unmatched, .enriched{"type", "event_id", "timestamp", "candidate"}: the candidate as in the result, without basis
error{"type": "error", "message": "the event stream failed"}

To resume, pass the last event_id you saw as ?last_event_id=... (letters, digits, - and _, up to 64). Events over 64 KB are dropped. At most 5 streams per organization are open at once.

The stream follows the same rule as the result: matches past what you are charged for, and enrichments past what the cost counts, are not sent.

Cancel

POST /v1/parallel/findall/runs/{id}/cancel stops the run at Parallel and answers the run object, at that moment usually still running with cost null. Work already under way may still finish, so the run is settled about 30 seconds later: its status becomes cancelled and its cost is charged for the work done, the fixed fee plus the matches found before it stopped (a cancelled run is not free; one cancelled before it started is charged its fixed fee). A second cancel in those 30 seconds answers 200 again and changes nothing. Once the run has ended, a cancel answers 409 run_finished; read the result again then (see Read the result).

Extend and enrich

Parallel lets a run be extended or enriched after it starts; through RouterPlus both are refused, because they would raise the run's cost past the max_cost it was created with:

  • POST .../{id}/extend answers 409 not_supported: "extending a run is not supported: create a new run with a larger match_limit (each run's fixed fee is charged again)". Pass the first run's matches as its exclude_list to skip them.
  • POST .../{id}/enrich answers 409 not_supported: "adding an enrichment to a created run is not supported: create a new run with the enrichment in its enrichments field".
bash
curl https://api.routerplus.com/v1/parallel/findall/entity-search \
  -H "Authorization: Bearer $TM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"entity_type": "companies", "objective": "Companies that develop open-source relational databases", "match_limit": 10}'
json
{"object": "parallel.entity_search", "entities": [{"name": "...", "url": "https://...", "description": "..."}], "cost": 0.005}
FieldRequiredWhat it takes
entity_typeyespeople or companies
objectiveyes1 to 5,000 characters
match_limitno5 to 100; default 100. Parallel may return fewer (one of our 100-company searches returned 29)

Each search costs $0.005, charged when Parallel answers; a search that fails is not charged. Results are best-effort: nothing is verified, and there are no citations.

Professional context only. Parallel allows Entity Search for professional purposes only, and not for decisions about employment, credit or housing. By using it you accept the same limit.

Limits

LimitValueOver it
Creates per organization per minute2429 rate_limit: wait retry-after
Active runs (queued or running) per organization3429 rate_limit: "3 Parallel FindAll runs already active: wait for one to end, or cancel one". The three can hold up to 3 × $25 = $75 of your credit between them
Result reads and event streams opened per organization per minute60429 rate_limit: wait retry-after
Entity Searches per organization per minute30429 rate_limit: wait retry-after
Open event streams per organization5429 rate_limit
A run's hold (max_cost)$25400 invalid_request naming the largest match_limit that fits
Request body256 KB400 invalid_request
Result10 MB, 5,000 candidates502 result_too_large
Event stream570 secondsThe stream ends; open it again
A run's life2 hoursrun_timeout: the run is cancelled at Parallel and charged for the work done

Busy times can also bring a 429 rate_limit that says the service is running as many FindAll runs as it may, or a 503 provider_unavailable that says Parallel is limiting new runs: wait retry-after and try again. Neither is charged.

Errors

Statuserror_typeWhen
400invalid_requestA field refused or over its limit, or a max_cost over the hold cap (the message names the field)
400upstream_rejectedParallel refused the run or the search: "Parallel refused the run (HTTP 422)". Not charged
403forbiddenNot an organization key of a paid organization: create one in API keys and add paid credit. Or, on a create or an Entity Search, a key limited to its own provider keys or a routing policy: use one without that limit (a policy on the organization or workspace applies to every key: an owner changes it in the console)
404not_foundNo such run for your organization
409run_finished/cancel on a run that has already ended
409not_supported/extend or /enrich: create a new run instead
429rate_limitA per-minute or active-run limit, or 5 open streams: wait retry-after
429insufficient_quotaNot enough credit to hold the run's max_cost (or a search's $0.005)
502upstream_errorParallel did not accept the run, return the result, cancel, or answer the search. A failed create is not charged
502result_too_largeThe result is over 10 MB
503provider_unavailableParallel is limiting new runs, or the service is not configured (see below). Not charged
503gateway_errorOur ledger or run store is briefly unavailable: nothing was held or sent; retry after retry-after

Parallel's own error text is never passed on.

Troubleshooting

  • Every FindAll path answers 404 not_found, as an unknown route does. FindAll is not available on the gateway you are calling. Contact support to ask for it.
  • 503 provider_unavailable with "Parallel FindAll is turned on but not configured on this gateway yet". The routes exist but our Parallel key or its address is not in place yet. Ask support; retrying will not help until it is configured.
  • 403 forbidden. Use an organization API key from the console, and add paid credit to the organization.
  • 400 naming match_limit and the hold. Lower match_limit to the number the message gives, or drop an enrichment. If no match_limit fits, remove an enrichment, use a cheaper enrichment processor or a cheaper generator.
  • 429 insufficient_quota on a create. Your balance (or a monthly spend cap) cannot hold the run's max_cost: lower match_limit, or add credit.
  • A run's cost is more than its fixed fee though you cancelled it at once. Work under way when you cancelled still counts; see Cancel.

Data

  • What you send in a run (the objective, the entity type, the conditions, the exclude list and the enrichment schemas) and in an Entity Search goes to Parallel, a third party, with our Parallel key. Under Parallel's standard terms it may use inputs and outputs to improve its services; until our account terms with Parallel are settled, treat runs and searches as retained and possibly used for training by Parallel. Parallel stores data in the US. See Data policy.
  • RouterPlus keeps, per run, ids, the generator, the match limit, the enrichment processors, a one-way hash of each enrichment field name, the hold, the status, Parallel's termination reason and counts, the enriched counts charged, an error code, the cost and times: no objective, condition, candidate, output, event or Parallel text. The create body is logged only if your organization has request logging on, as any request is. Results, events and Entity Search answers are never logged or kept.
  • RouterPlus never sends webhook, memory_scope_key or mcp_servers.

Markdown source for agents: /docs/parallel-findall.md · index at /llms.txt