Skip to main content
client.prompts.render(slug, options?) resolves a prompt for the client’s projectId and env in a single request. Set format — on the client or per call — to get a result shaped for that provider; omit it to get the neutral result.
The options object is { format?, label?, subject?, variables?, fallback?, onUnknownRole? }: label picks the label to resolve for this call (defaulting to the client’s env — env is a label value), format overrides the client default, subject (a stable id) pins a weighted release to a variant, and fallback is served on a network error. The return shape is fixed by the call’s format, not by the network outcome. Authored developer blocks render as-is; the SDK maps them per provider (OpenAI keeps developer, Anthropic folds them into system). onUnknownRole ("drop" default, "warn", or "error") sets how a message with an unrecognized role is handled during provider conversion — see Unknown roles.

Shaped result

With a format, render returns a result you can spread straight into a provider request. format: "openai" returns { messages, config, metadata }; format: "anthropic" returns { system, messages, config, metadata } — the authored system and developer instructions are folded into a top-level system string, which Anthropic takes as a separate request field. When the prompt authors tools, the result also carries provider-shaped tools and tool_choice. Spread the result into the request, and pass the whole result to turn.headers(prompt) for the provenance headers:

Neutral result and converters

Omit format (on both the client and the call) to get the neutral RenderedPrompt: messages, tools, toolChoice, promptId, version, versionId, releaseId, variantName, contentHash, label, slug, blockRenderRecord, and modelConfig. This is the path for providers the shaper does not cover (Vercel AI, LangChain) or for driving one prompt through more than one provider. The @to11ai/sdk/gateway subpath converts a neutral result into a provider’s request shape: gatewayAuthHeaders and gatewayPromptHeaders are also re-exported from the main @to11ai/sdk entry. With a format, render applies the message conversion for you, so most apps never call the converters directly.

Unknown roles

The message converters recognize system, user, assistant, developer, and tool. A message whose role is anything else is handled by the onUnknownRole policy — set it per call, on createClient, or on the converter directly:
A prompt rendered by to11 only ever carries known roles, so on render() this matters mainly when you convert your own message arrays (assembled conversation history, messages from another source). onUnknownRole: "error" on render() is a way to assert that invariant explicitly.

Skills are not renderable through the SDK

A skill is the second kind of prompt: it is delivered to a developer’s machine as files and read there by a coding agent, rather than sent to a model as messages. There is nothing for render() to return. Two things keep that from surprising you:
  • You will not find one by accident. client.prompts.list() returns chat prompts only. Skills are excluded from listing unless a caller asks for them explicitly, so a consumer that never asked never learns a skill’s slug.
  • If you do render one deliberately, it throws. The SDK validates every render response against a closed schema, and a skill’s response does not match it — so the call raises a validation error rather than handing back something your code would misread. Behind that, a format guard throws too, naming the format and pointing at the to11 CLI.
Nothing is misread and nothing is silently coerced. To work with skills, use the to11 CLI, which is what delivers them.