docs: document restoreFromStateId in kickoff API reference and migration guide operational notes

- Add restoreFromStateId (optional, uuid) to the POST /kickoff request schema
  with fork semantics, silent fresh-session fallback for unknown ids, and a
  pointer to the migration guide
- Add a flow_state_restore request example and a 422 example for non-UUID
  inputs.id alongside the existing missing_inputs case
- Add an Operational notes section to the inputs-id-deprecation guide covering
  how to chain turns today (client-generated UUID pinned via inputs.id), the
  silent fresh-session behavior for unknown restoreFromStateId, and the AMP
  UUID format requirement for inputs.id

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Joao Moura
2026-07-13 22:01:37 -07:00
parent 9d72e269e4
commit 1f025fcf86
3 changed files with 112 additions and 2 deletions

View File

@@ -137,6 +137,50 @@ Migrating to `restoreFromStateId` keeps every kickoff as its own execution — w
its own status, traces, and row in the list — while still hydrating state from a
previous run.
### Operational notes
A few current behaviors to be aware of when chaining runs over the AMP REST API:
- **The API does not return the new run's state id yet.** A `restoreFromStateId`
kickoff mints a fresh `state.id` for the new run, but neither the `/kickoff`
response (which returns `kickoff_id`) nor the `/status` payload currently
surfaces it, so there is no way to read back the id you would need for the next
turn. Until the API exposes the minted state id (this gap is being tracked), the
working approach for multi-turn chains is to generate a UUID client-side and pin
it as the new run's id via `inputs.id` alongside `restoreFromStateId`:
```bash
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_CREW_TOKEN" \
-d '{
"inputs": {"id": "NEW-CLIENT-GENERATED-UUID", "topic": "AI Agent Frameworks"},
"restoreFromStateId": "STATE-ID-FROM-PREVIOUS-TURN"
}' \
https://your-crew-url.crewai.com/kickoff
```
This deliberately leans on the deprecated `inputs.id` parameter — today it is the
only way to know the new run's state id ahead of time. Keep the pinned UUID on
your side for the next turn's `restoreFromStateId`, and plan to drop `inputs.id`
once the API returns the minted state id.
- **An unknown `restoreFromStateId` silently starts a fresh session.** If the
referenced state id does not exist (typo, deleted state, wrong deployment), the
kickoff does not fail — the run proceeds with a brand-new state, and nothing in
the kickoff response or status payload signals that hydration was skipped.
Validate state ids client-side before sending them.
- **`inputs.id` must be a valid UUID on AMP.** The local SDK accepts arbitrary
strings, but AMP rejects non-UUID values with a `422`:
```json
{
"error": "Validation Error",
"message": "'inputs.id' must be a valid UUID when provided; got 'test 1'."
}
```
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team if you're unsure which mode your flow needs or hit issues
during the migration.

View File

@@ -138,6 +138,18 @@ paths:
example:
requestId: "user-request-12345"
source: "mobile-app"
restoreFromStateId:
type: string
format: uuid
description: |
State id of a previous `@persist` flow execution to hydrate from.
The new run **forks** from the referenced snapshot: state is restored,
then the execution proceeds under a fresh state id (the source run's
history is preserved). If the referenced state id is unknown, the run
silently starts as a fresh session — no error is returned. See the
[inputs.id deprecation guide](/en/guides/flows/inputs-id-deprecation)
for migration details and operational notes.
example: "abcd1234-5678-90ef-ghij-klmnopqrstuv"
taskWebhookUrl:
type: string
format: uri
@@ -177,6 +189,12 @@ paths:
linkedin_url: "https://linkedin.com/in/johnsmith"
taskWebhookUrl: "https://api.example.com/webhooks/task"
crewWebhookUrl: "https://api.example.com/webhooks/crew"
flow_state_restore:
summary: Flow kickoff restored from a previous state
value:
inputs:
topic: "AI Agent Frameworks"
restoreFromStateId: "abcd1234-5678-90ef-ghij-klmnopqrstuv"
responses:
"200":
description: Crew execution started successfully
@@ -199,11 +217,26 @@ paths:
"401":
$ref: "#/components/responses/UnauthorizedError"
"422":
description: Validation error - ensure all required inputs are provided
description: |
Validation error. Returned when required inputs are missing, or when
`inputs.id` is provided but is not a valid UUID.
content:
application/json:
schema:
$ref: "#/components/schemas/ValidationError"
examples:
missing_inputs:
summary: Required inputs missing
value:
error: "Validation Error"
message: "Missing required inputs"
details:
missing_inputs: ["budget", "interests"]
invalid_inputs_id:
summary: inputs.id is not a valid UUID
value:
error: "Validation Error"
message: "'inputs.id' must be a valid UUID when provided; got 'test 1'."
"500":
$ref: "#/components/responses/ServerError"

View File

@@ -138,6 +138,18 @@ paths:
example:
requestId: "user-request-12345"
source: "mobile-app"
restoreFromStateId:
type: string
format: uuid
description: |
State id of a previous `@persist` flow execution to hydrate from.
The new run **forks** from the referenced snapshot: state is restored,
then the execution proceeds under a fresh state id (the source run's
history is preserved). If the referenced state id is unknown, the run
silently starts as a fresh session — no error is returned. See the
[inputs.id deprecation guide](/en/guides/flows/inputs-id-deprecation)
for migration details and operational notes.
example: "abcd1234-5678-90ef-ghij-klmnopqrstuv"
taskWebhookUrl:
type: string
format: uri
@@ -177,6 +189,12 @@ paths:
linkedin_url: "https://linkedin.com/in/johnsmith"
taskWebhookUrl: "https://api.example.com/webhooks/task"
crewWebhookUrl: "https://api.example.com/webhooks/crew"
flow_state_restore:
summary: Flow kickoff restored from a previous state
value:
inputs:
topic: "AI Agent Frameworks"
restoreFromStateId: "abcd1234-5678-90ef-ghij-klmnopqrstuv"
responses:
"200":
description: Crew execution started successfully
@@ -199,11 +217,26 @@ paths:
"401":
$ref: "#/components/responses/UnauthorizedError"
"422":
description: Validation error - ensure all required inputs are provided
description: |
Validation error. Returned when required inputs are missing, or when
`inputs.id` is provided but is not a valid UUID.
content:
application/json:
schema:
$ref: "#/components/schemas/ValidationError"
examples:
missing_inputs:
summary: Required inputs missing
value:
error: "Validation Error"
message: "Missing required inputs"
details:
missing_inputs: ["budget", "interests"]
invalid_inputs_id:
summary: inputs.id is not a valid UUID
value:
error: "Validation Error"
message: "'inputs.id' must be a valid UUID when provided; got 'test 1'."
"500":
$ref: "#/components/responses/ServerError"