---
title: "Generate Protocol Endpoint"
method: POST
path: "/protocols/generate"
tags: ["protocols"]
---

# Generate Protocol Endpoint

`POST /protocols/generate`

Generate a UCP protocol from a natural-language description.

When the description leaves a value undecided that would change what runs
on the channel, the response carries ``questions`` and no protocol. Answer
them and call again with the full ``clarifications`` history.

Any protocol that *is* returned has already passed the same validation as
``POST /protocols/validate`` and contains no unresolved ``input["..."]``
references, so it can be saved as an experiment template directly.

Parameters
----------
body : GenerateProtocolRequest
    The natural-language prompt, any answers already given, and an
    optional existing protocol to edit rather than replace.

Returns
-------
GenerateProtocolResponse
    Either the generated YAML with a suggested name, an explanation, and
    the assumptions made — or the questions needed to write it.

Raises
------
ExternalServiceError
    If the model could not produce a valid protocol.

## Request body

- GenerateProtocolRequest — Request body for generating a protocol from natural language.
  - `prompt` string, required — Plain-English description of the test to run, e.g. '1C/1C cycling for 200 cycles between 4.2 V and 2.5 V with 10-minute rests'.
  - `current_protocol` string, nullable — Optional existing protocol as UCP YAML. When supplied the prompt is treated as an edit to it rather than a fresh protocol.
  - `clarifications` ClarificationAnswer[] — Answers to questions a previous call returned, oldest first. Send the full history each time — the exchange is stateless.
    - `question` string, required
    - `answer` string, required
  - `cell_specification_id` string, nullable — Cell the test will run on. Its voltage limits, capacity and rate limits are given to the generator as facts, so it stops guessing (or asking) about them.
  - `skip_existing` boolean — Skip the saved-protocol search and write a new protocol. Set when the user rejects the suggested matches.

## Response `200`

Successful Response

- GenerateProtocolResponse — A protocol, the questions needed to write one, or an existing match. Exactly one branch is populated. Callers should check ``questions`` and ``matches`` before reading ``protocol_yaml`` — both leave it empty.
  - `protocol_yaml` string
  - `name` string
  - `explanation` string
  - `assumptions` string[]
  - `questions` ClarifyingQuestionResponse[]
    - `question` string, required
    - `why` string
    - `options` string[]
  - `matches` ExistingProtocolMatchResponse — A saved protocol that already does what was asked for.
    - `template_ids` string[], required
    - `note` string

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/ionworks/apis/fastapi.md) · [All operations](https://skmtc.dev/ionworks/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/ionworks/fastapi/revisions/7337a3cbdaf2/schema)
