---
title: "Edit a generated simulation suite"
method: PATCH
path: "/eval/simulation/onboarding/suite/{suiteId}"
tags: ["Simulation Suites"]
---

# Edit a generated simulation suite

`PATCH /eval/simulation/onboarding/suite/{suiteId}`

## Request

- Base URL: `https://api.vapi.ai`
- URL: `https://api.vapi.ai/eval/simulation/onboarding/suite/{suiteId}`
- Auth: HTTP bearer

Revise a suite created by `POST /eval/simulation/onboarding/suite`. Remove simulations, rewrite scenarios using natural-language instructions, or set `retryFailed` to regenerate scenarios that failed or exceeded generation limits. The response includes the updated suite and requirement coverage.

Requests can take up to 2 minutes.

Send a new `patchKey` for each edit. Replaying an applied key changes nothing and returns the current suite, with `failedEditSimulationIds` listing the simulations that edit could not rewrite, so retry a timeout or a 5xx with the same key. A suite remembers its last 50 keys, so never reuse one.

Each organization can make 60 edits per UTC day, shared with the dashboard. Requests that only remove simulations and replays of applied edits do not count toward this limit. On a 429 `SIMULATION_ONBOARDING_QUOTA_EXCEEDED`, wait until the daily limit resets at 00:00 UTC before retrying.

## Path parameters

- `suiteId` string, required

## Request body

- SimulationOnboardingSuiteUpdateDTO
  - `patchKey` string, required: A new key for each edit. Replaying an applied key changes nothing and returns the current suite. A suite remembers its last 50 keys, so never reuse one.
  - `removeSimulationIds` string[]: Simulations to take out of the suite. They are unlinked, not deleted.
  - `edits` SimulationOnboardingSuiteEditDTO[]: Simulations to rewrite in place, at most one edit per simulation: put every change for a simulation in one instruction.
    - `simulationId` string, uuid, required: Simulation in the suite whose scenario is rewritten.
    - `instruction` string, required: Natural-language instructions for revising this simulation's scenario, such as "Have the caller ask for a refund after 30 days."
  - `retryFailed` boolean: Regenerate the scenarios that failed or did not fit when the suite was generated.

## Response `200`

- SimulationOnboardingSuiteViewDTO
  - `suite` SimulationOnboardingSuiteRefDTO, required
    - `id` string, required: Suite id; pass it to edit or run the suite.
    - `name` string, required: Suite name.
  - `assistantId` string, required: Assistant the suite is assigned to.
  - `simulations` SimulationOnboardingSuiteSimulationDTO[], required: The suite's simulations, in order.
    - `id` string, required: Simulation id; pass it back to edit or remove the simulation.
    - `scenarioId` string, required: Scenario the simulation runs.
    - `name` string, required: Scenario name.
    - `personalityName` string: Name of the simulated caller's personality.
    - `successCriteria` string[], required: Each success criterion, as the yes/no question it is judged by.
    - `requirementIds` string[], required: Requirement ids this simulation covers, e.g. `R3`.
    - `mockedTools` string[], required: Tools the scenario mocks.
  - `coverage` SimulationOnboardingSuiteCoverageDTO, required
    - `covered` number, required: Requirements at least one simulation covers.
    - `total` number, required: Requirements in the agreed draft.
    - `gaps` SimulationOnboardingCoverageGapDTO[], required: Requirements no simulation covers, and why.
      - `requirementId` string, required: Requirement the gap is for, e.g. `R4`.
      - `reason` 'not-testable' | 'unmapped' | 'failed' | 'budget', required: Why no simulation covers it. `failed` and `budget` gaps are regenerated by an edit with `retryFailed`.
      - `detail` string: A short explanation for the user.
    - `retryable` number, required: Planned scenarios an edit with `retryFailed` would regenerate.
  - `requirements` SimulationOnboardingRequirementDTO[], required: The test requirements used to generate the suite. Match their ids to `coverage.gaps` to identify uncovered requirements.
    - `id` string, required: Stable requirement id, e.g. `R3`.
    - `text` string, required: One observable behaviour the assistant must get right.
    - `tag` 'assumption' | 'not-testable' | 'voice-only': Indicates an assumption, a requirement that needs a voice simulation, or a requirement that cannot be tested.
    - `note` string: What was assumed, why only a voice run can check it, or why it cannot be tested.
  - `docs` SimulationOnboardingSuiteDocsDTO, required
    - `bestPractices` string, required: Link to testing best practices.
    - `toolMocks` string, required: Link explaining why tools are mocked by default.
  - `reused` boolean, required: True when the request matched one already applied (same `idempotencyKey` or `patchKey`) and nothing changed.
  - `failedEditSimulationIds` string[]: Simulations an edit asked to rewrite that were not rewritten, for example because the rewrite did not generate in time. Retry them with a new `patchKey`.
  - `toolGaps` SimulationOnboardingToolGapDTO[]: Tool paths the suite's simulations do not exercise as configured, such as a tool mocked although it runs natively. Omitted when there are none.
    - `toolName` string, required: Function name of the tool, e.g. `handoff_to_group_1` or `transferCall`.
    - `assistantName` string: Assistant the tool belongs to, when it is a handoff destination's tool. Unset for the assistant's own tools.
    - `reason` 'dynamic-handoff' | 'destination-not-plain' | 'destination-unresolved' | 'destination-truncated' | 'transfer-external' | 'destination-name-unscoped' | 'native-tool-shadowed', required: Why the path is not exercised: a reason the simulations mock the tool, or why a native path is never reached. New reasons may be added.
    - `destinationNames` string[]: Static destinations the simulations do not reach through this tool.

## Other responses

- `400`: The body is invalid, or the edited suite uses something the org's data-region policy doesn't allow, so it isn't saved.
- `403`: The key can't edit simulation suites.
- `404`: The suite wasn't generated by `POST /eval/simulation/onboarding/suite` in this org, or the org doesn't have API access to these endpoints yet.
- `422`: An MCP server's tools could not be listed, so simulations would call them for real instead of a mock. Check the server is reachable and retry.
- `429`: `SIMULATION_ONBOARDING_QUOTA_EXCEEDED`: the org made 60 edits today. Don't retry; the limit resets at 00:00 UTC.
- `502`: The model failed to generate a usable result. Retry.
- `503`: Simulation generation is paused, no caller personalities are configured, or the quota store is unavailable for a private-key request. Quota outages return SIMULATION_ONBOARDING_QUOTA_UNAVAILABLE with Retry-After; retry with the same key.
- `504`: The edit took too long. Retry with the same `patchKey`.

## Changes

> 164 revisions in range; 15 not diffed, 8 could not be searched.

- **2026-10-29** `d4ae2ac5e134`: 2 info
  - api tag `Simulation Suites` added
  - api tag `Simulations` removed

[Operation history](https://skmtc.dev/vapiai/apis/vapi-api/changes/eval/simulation/onboarding/suite/:suiteId/patch.md)

---

[API](https://skmtc.dev/vapiai/apis/vapi-api.md) - [All operations](https://skmtc.dev/vapiai/apis/vapi-api/llms.txt) - [OpenAPI document](https://skmtc.dev/vapiai/apis/vapi-api/revisions/d73a715574fb?raw)
