blueprint (see
The population), so what it inferred is yours to inspect, not
a black box.
This endpoint is asynchronous. The POST returns 200 OK right away
with an id; you then GET the population repository route with that id until it
is ready. Generation grounds the request in real-world data and writes a persona for
each member, so it can run for minutes — see the
note on grounding below.
Authorization
Your bearer token:
Bearer <token>. See Authentication.Request body
The request is intentionally minimal. These three fields are the entire contract — there is nothing else to send.A non-empty natural-language description of who to generate. This is the only
signal the API needs; it infers the field structure from the prompt.
How many personas to generate. Must be at least
1. Large counts are capped; a
request over the limit returns VALIDATION_ERROR. The population size is this
number; there is no separate batch endpoint.How hard to ground the population in real-world data before generating. One of:
off— generate from the prompt alone, with no external lookups.web— enrich the inferred field model with a quick live lookup so distributions and details reflect current real-world data.research— run deeper research before generating, for the strongest real-world grounding and cited sources.
Request
Start a population
ThePOST returns 200 OK straight away. It does not wait for the personas; it
gives you an id used with the population repository route.
The population’s identifier. Use it to poll for the result.
Always
pending in this response — the population has been accepted and queued.200 OK
Grounding and timing
Generation grounds the request in real-world data and then writes a persona for
each member, so it does not return on the
POST. research grounding runs
deeper lookups and can take minutes, and time grows with count. That is
why this endpoint hands back an id to poll rather than holding the connection
open. Poll on an interval of a few seconds and do not block a user-facing
request on a research population.Poll for the result
GET with the returned id until status is succeeded or failed.
The population’s identifier, the same value you started.
Where the population is in its lifecycle. One of:
pending— accepted and queued; generation has not started yet.running— grounding and generation are under way;progressupdates.succeeded— finished;resultholds the population.failed— finished;errorcontains a stable failure category.
pending and running are not terminal — keep polling. succeeded and
failed are terminal — stop polling.How far generation has got, present while
running. produced is how many
personas are written so far and total is how many were requested.The generated population, present only when
status is succeeded. Its
shape is described under The population below.A stable failure category such as
provider_error. Present only when status
is failed.running and carries a
progress object so you can show how far along it is:
200 OK (running)
The population
Whenstatus is succeeded, the poll carries the population under result: the
rendered personas, the inferred blueprint the personas were sampled from, and
fidelity reports showing how closely the realized population matches that
blueprint. The fields below describe the shape of that result.
Each persona is dynamic. There is no fixed persona shape: the blueprint
declares the field set, and every persona carries exactly those fields as a flat
fields map of name to string value. For the League of Legends prompt the API
might infer region, rank, main_role, hours_per_week, name, and
backstory; a different prompt yields a different field set.
The generated personas. Each one carries the blueprint’s fields plus a
ready-to-use
system_prompt and a formatted markdown sheet — all three are
always present.The inferred field model the population was sampled from — the API’s reasoning
about what makes this population realistic, returned so you can inspect it and
read the field set the personas use.
How varied the population is. Present for multi-persona populations.
Per-field fidelity: for each root categorical field, how closely the realized
population matches the blueprint’s marginal distribution.
result
({ "id": ..., "status": "succeeded", "result": <the object below> }):
200 OK (succeeded)
personas and marginals are truncated above; a real population contains
count personas and one manifest per root categorical field.)
When generation fails
If generation fails after the population starts, the poll still returns200 OK
with status: "failed" and an error instead of a result:
200 OK (failed)
status and error, not on the HTTP status of the
poll — a failed population is reported with 200 OK. Start a new population to
retry; do not keep polling a failed one.
Errors
Errors arrive in two places: a bad request is rejected at thePOST, and a
failure during generation surfaces on the poll.
The POST returns one of these before any population is started:
| Status | Code | When |
|---|---|---|
400 | VALIDATION_ERROR | count is over the configured batch limit. |
401 | UNAUTHORIZED | The bearer token is missing, invalid, or expired. |
402 | PAYMENT_REQUIRED | Your credit balance can’t cover the request. See Credits and billing. |
422 | validation_failed | A required field is missing or has an invalid type/value. |
POST returns the standard error envelope. For example, an empty
prompt:
422 Unprocessable Entity
POST returns 200, a later failure appears on the poll as
status: "failed" with error: "provider_error" (a stable, opaque failure
category). Start a fresh population to retry. See
Errors for request errors.
Example
Start the population, then poll its repository route until it reaches a terminal status and read the personas fromresult.
fields map rather than hard-coding them — inspect blueprint.fields
to see which fields a given population carries. The diversity and marginals
reports are populated only for multi-persona populations (count > 1); a single
persona omits them.
Next
- Validate personas — score a population against the quality gates.
- Enhance a persona — deepen a single persona you already wrote.
- Errors — the full error model and how to recover.

