Menu
Client Methods

Playbook Management

Methods for reviewing, searching, retrieving, adding, and deleting user playbooks and agent playbooks.

Durable aggregation operations

Use submit_playbook_aggregation with request_id and agent_version for a full aggregation that may outlive the HTTP request. Admission returns a persisted receipt; it does not wait for generation. SQLite with its vector extension, managed Supabase, and native PostgreSQL support this API. Storage adapters without durable-operation support return HTTP 503 rather than accepting work they cannot execute.

Python
operation = client.submit_playbook_aggregation(
    request_id="aggregate-v2-release-1", agent_version="v2"
)
operation = client.get_playbook_aggregation_operation(operation.operation_id)
print(operation.status, operation.result)

Use get_playbook_aggregation_operation with the returned operation ID to poll.

If submission times out, repeat it with the same request ID and agent version. It returns the same operation, including after completion. Reusing that ID with different parameters returns HTTP 409. A different request ID also returns 409 while an operation for that agent version is unfinished. Managed requests are scoped by the authenticated organization and project; another project's receipt cannot be read with its operation ID.

The corresponding HTTP routes are POST /api/playbook_aggregation_operations (HTTP 202, JSON request_id and agent_version) and GET /api/playbook_aggregation_operations/{operation_id} (HTTP 200, or 404 for an unknown receipt). Receipt timestamps are Unix seconds. Status is queued, running, retrying, succeeded, or failed.

succeeded means the aggregation output and completion receipt committed together, including valid zero-output results. Generated agent playbooks still require their normal review and approval; optional tagging and optimization may continue afterward. Workers recover unfinished operations after lease expiry, with bounded retries for execution failures. Deleting or erasing current source content cancels unfinished operations. Retiring captured inputs prevents the old worker from saving its result; a retry uses the remaining current inputs. Historical tombstone cleanup does not cancel work. Failed receipts expose a safe error code, not provider messages or source content.

The existing synchronous aggregation API remains available. See receipt schemas.

search_user_playbooks

Search for user playbooks using semantic/text search and advanced filtering. On authenticated requests, served results are synchronously recorded as evidence before a successful response returns. If recording fails, the search fails; empty results create no evidence batch.

Python
response = client.search_user_playbooks(
    query="user satisfaction",
    user_id="user_123",
    request_id="request_123",
    session_id="session_123",
    agent_version="v2.1.0",
    source="api",
    tags=["support"],
    top_k=10
)
Terminal
curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/search_user_playbooks" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "query": "user satisfaction",
  "user_id": "user_123",
  "request_id": "request_123",
  "session_id": "session_123",
  "agent_version": "v2.1.0",
  "source": "api",
  "tags": ["support"],
  "top_k": 10
}
JSON
PropTypeDefaultDescription
query?str—Query for semantic/text search
user_id?str—Filter by user and identify the user for retrieval-experiment assignment. Required for agent traffic while an experiment is active.
request_id?str—Optional caller correlation ID for the search turn, at most 255 characters.
session_id?str—Optional caller session ID for the search turn, at most 255 characters.
agent_version?str—Filter by agent version
playbook_name?str—Filter by playbook name
source?str—Filter by exact interaction source. Omit or pass an empty string to disable source filtering.
start_time?datetime—Filter by start time
end_time?datetime—Filter by end time
status_filter?list[Status]—Filter by status (None for CURRENT, PENDING, ARCHIVED)
tags?string[]—Optional tag filter. Matches user playbooks that have any requested tag.
top_k?int10Maximum number of results to return, from 1 through 100.
threshold?floatmodel-specificSimilarity threshold for vector search. Omit it to use the embedding model's default.
enable_reformulation?boolfalseEnable query reformulation for improved search results
search_mode?SearchMode—Search mode: "vector", "fts", or "hybrid". When unset, the server uses its configured default ("hybrid").


review_user_playbooks

Re-run the evidence-grounded reviewer over the newest current user playbooks created in an inclusive time window. top_k is applied in newest-first order. For each selected playbook, the server loads the full interaction window recorded by its finalized playbook-extraction run, adds any extra cited interactions retained through consolidation, and restores request grouping. Historical review is therefore not limited by the playbook's smaller cited-evidence subset, the current extraction window size, or the current source filter. Only cited IDs are presented as candidate evidence; the remaining generation-window interactions provide chronology without becoming additional evidence.

The default report mode runs inline and returns decisions without changing storage, while simulating the same newest-first context transitions as apply mode. Because each selected playbook receives a fresh model review, the server automatically gives this endpoint its extended synchronous timeout. A playbook is reported as skip when its finalized generation-window provenance, validated evidence metadata, or a required interaction/request is unavailable, or when its ownership provenance does not match the requesting user; the run then continues. The automatic reviewer that runs immediately after generation separately uses that generation's configured extraction window.

Set report_only=False to apply the decisions. Apply mode is accepted and run in the background — the response returns immediately with a run_id and an empty results list, because a run makes one model call and one write per selected playbook. The run reviews newest-first and commits each completed decision before reviewing the next playbook: accepted rows stay current, rejected rows are archived, and an edit inserts the replacement as current while superseding its incumbent. A later failure stops the run but leaves earlier decisions committed. Applied edits are recorded on the replacement's lineage under the returned run_id.

Python
from datetime import UTC, datetime

response = client.review_user_playbooks(
    start_time=datetime(2026, 7, 1, tzinfo=UTC),
    end_time=datetime(2026, 7, 28, tzinfo=UTC),
    top_k=50,
    report_only=True,
)

for result in response.results:
    print(result.user_playbook_id, result.decision, result.reason)
Terminal
curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/review_user_playbooks" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "start_time": "2026-07-01T00:00:00Z",
  "end_time": "2026-07-28T23:59:59Z",
  "top_k": 50,
  "report_only": true
}
JSON
PropTypeDefaultDescription
start_timedatetime—Inclusive lower bound for user playbook creation time
end_timedatetime—Inclusive upper bound for user playbook creation time; must be after start_time
top_k?int10Maximum number of newest matching current playbooks to review (1-100)
report_only?booltrueReturn decisions inline without writes when true; accept the run and apply it in the background when false

See ReviewUserPlaybooksResponse for result fields and decision details.


search_agent_playbooks

Search for agent playbooks using semantic/text search and advanced filtering. The optional source filter matches provenance: an agent playbook is included when at least one linked source user playbook has that exact source.

Python
response = client.search_agent_playbooks(
    query="concise responses",
    user_id="user_123",
    agent_version="v2.1.0",
    source="api",
    tags=["tone"],
    playbook_status_filter="approved"
)
Terminal
curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/search_agent_playbooks" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "query": "concise responses",
  "user_id": "user_123",
  "agent_version": "v2.1.0",
  "source": "api",
  "tags": ["tone"],
  "playbook_status_filter": "approved"
}
JSON
PropTypeDefaultDescription
query?str—Query for semantic/text search
user_id?str—User receiving the playbooks. Used only for retrieval-experiment assignment, not as an agent-playbook filter. Required for agent traffic while an experiment is active.
agent_version?str—Filter by agent version
playbook_name?str—Filter by playbook name
source?str—Match agent playbooks linked to at least one user playbook with this exact interaction source. Omit or pass an empty string to disable source filtering.
start_time?datetime—Filter by start time
end_time?datetime—Filter by end time
status_filter?list[Status]—Filter by lifecycle status. Defaults to CURRENT and PENDING when omitted.
tags?string[]—Optional tag filter. Matches agent playbooks that have any requested tag.
playbook_status_filter?PlaybookStatus—Filter by playbook approval status (PENDING, APPROVED, REJECTED)
top_k?int10Maximum number of results to return
threshold?floatmodel-specificSimilarity threshold for vector search. Omit it to use the embedding model's default.
enable_reformulation?boolfalseEnable query reformulation for improved search results
search_mode?SearchMode—Search mode: "vector", "fts", or "hybrid". When unset, the server uses its configured default ("hybrid").


get_user_playbooks

Retrieve user playbook rows containing agent guidance, including entries extracted from interactions and rows created by supported manual or playbook-optimizer workflows.

Python
response = client.get_user_playbooks(
    limit=100,
    tags=["support"]
)
Terminal
curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/get_user_playbooks" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "limit": 100,
  "tags": ["support"]
}
JSON
PropTypeDefaultDescription
limit?int100Maximum number of results to return
user_playbook_id?int—Exact user playbook ID filter
user_id?str—Filter by user ID
request_id?str—Filter by generating request ID
query?str—Case-insensitive text filter across visible user playbook fields
playbook_name?str—Filter by playbook name
agent_version?str—Filter by agent version
start_time?datetime—Filter by created-at start time
end_time?datetime—Filter by created-at end time
status_filter?list[Status]—Filter by status
tags?string[]—Optional tag filter. Matches user playbooks that have any requested tag.


add_user_playbook

Add user playbook entries directly to storage.

Python
response = client.add_user_playbook(
    user_playbooks=[
        {
            "agent_version": "v2.1.0",
            "request_id": "req_123",
            "content": "User expressed satisfaction with response"
        }
    ]
)
Terminal
curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/add_user_playbook" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "user_playbooks": [
    {
      "agent_version": "v2.1.0",
      "request_id": "req_123",
      "content": "User expressed satisfaction with response"
    }
  ]
}
JSON
PropTypeDefaultDescription
user_playbookslist[UserPlaybook | dict]—List of user playbook entries. Each item is a `UserPlaybook` model or a plain dict with the same fields — click through to see the schema.

At least one of content or trigger must be provided.


add_agent_playbooks

Add agent playbook entries directly to storage.

Python
response = client.add_agent_playbooks(
    agent_playbooks=[
        {
            "agent_version": "v2.1.0",
            "content": "Agent should provide more concise responses",
            "playbook_status": "approved",
            "playbook_metadata": "{}"
        }
    ]
)
Terminal
curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/add_agent_playbook" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "agent_playbooks": [
    {
      "agent_version": "v2.1.0",
      "content": "Agent should provide more concise responses",
      "playbook_status": "approved",
      "playbook_metadata": "{}"
    }
  ]
}
JSON
PropTypeDefaultDescription
agent_playbookslist[AgentPlaybook | dict]—List of agent playbook entries. Each item is an `AgentPlaybook` model or a plain dict with the same fields — click through to see the schema.


get_agent_playbooks

Retrieve agent playbook entries.

Python
response = client.get_agent_playbooks(
    limit=10,
    tags=["tone"]
)
Terminal
curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/get_agent_playbooks" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "limit": 10,
  "tags": ["tone"]
}
JSON
PropTypeDefaultDescription
limit?int100Maximum number of results
agent_playbook_id?int—Exact agent playbook ID filter
query?str—Case-insensitive text filter across visible agent playbook fields
playbook_name?str—Filter by playbook name
agent_version?str—Filter by agent version
start_time?datetime—Filter by created-at start time
end_time?datetime—Filter by created-at end time
status_filter?list[Status]—Filter by status
tags?string[]—Optional tag filter. Matches agent playbooks that have any requested tag.
playbook_status_filter?PlaybookStatus—Filter by playbook status. When unset, the server defaults to returning APPROVED playbooks.
force_refresh?boolfalseBypass cache


Update Methods

update_user_playbook

Update editable fields of a user playbook in place. Pass only the fields you want to change.

Python
response = client.update_user_playbook(
    user_playbook_id=42,
    content="Refined playbook content",
)
Terminal
curl -X PUT "${REFLEXIO_URL:-https://www.reflexio.ai}/api/update_user_playbook" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "user_playbook_id": 42,
  "content": "Refined playbook content"
}
JSON
PropTypeDefaultDescription
user_playbook_idint—The ID of the user playbook to update.
playbook_name?str—New playbook category name.
content?str—New content text.
trigger?str—New trigger text.
rationale?str—New rationale text.

Returns: UpdateUserPlaybookResponse with success and message.


update_agent_playbook

Update editable fields of an agent playbook in place. Pass only the fields you want to change.

Python
response = client.update_agent_playbook(
    agent_playbook_id=17,
    content="Updated guidance"
)
Terminal
curl -X PUT "${REFLEXIO_URL:-https://www.reflexio.ai}/api/update_agent_playbook" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "agent_playbook_id": 17,
  "content": "Updated guidance"
}
JSON
PropTypeDefaultDescription
agent_playbook_idint—The ID of the agent playbook to update.
playbook_name?str—New playbook category name.
content?str—New content text.
trigger?str—New trigger text.
rationale?str—New rationale text.
playbook_status?PlaybookStatus—New approval status. To change ONLY the status, prefer update_agent_playbook_status — it has tighter semantics and a single-purpose endpoint.

Returns: UpdateAgentPlaybookResponse with success and message.


update_agent_playbook_status

Dedicated endpoint for the approval workflow (approve / pending / reject). Use this instead of update_agent_playbook when the only change is the playbook_status — the server enforces tighter validation and writes a smaller change log.

Python
from reflexio import PlaybookStatus

response = client.update_agent_playbook_status(
    agent_playbook_id=17,
    playbook_status=PlaybookStatus.APPROVED,
)
Terminal
curl -X PUT "${REFLEXIO_URL:-https://www.reflexio.ai}/api/update_agent_playbook_status" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "agent_playbook_id": 17,
  "playbook_status": "approved"
}
JSON
PropTypeDefaultDescription
agent_playbook_idint—The ID of the agent playbook.
playbook_statusPlaybookStatus—New approval status: PENDING, APPROVED, or REJECTED.

Returns: UpdatePlaybookStatusResponse with success and message.


delete_agent_playbook

Delete an agent playbook by ID.

Python
response = client.delete_agent_playbook(
    agent_playbook_id=123,
    wait_for_response=True
)
Terminal
curl -X DELETE "${REFLEXIO_URL:-https://www.reflexio.ai}/api/delete_agent_playbook" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "agent_playbook_id": 123
}
JSON

delete_user_playbook

Delete a user playbook by ID.

Python
response = client.delete_user_playbook(
    user_playbook_id=456,
    wait_for_response=True
)
Terminal
curl -X DELETE "${REFLEXIO_URL:-https://www.reflexio.ai}/api/delete_user_playbook" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "user_playbook_id": 456
}
JSON

Bulk Delete Operations

delete_agent_playbooks_by_ids

Delete multiple agent playbooks by their IDs.

Python
response = client.delete_agent_playbooks_by_ids(agent_playbook_ids=[1, 2, 3])
Terminal
curl -X DELETE "${REFLEXIO_URL:-https://www.reflexio.ai}/api/delete_agent_playbooks_by_ids" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "agent_playbook_ids": [
    1,
    2,
    3
  ]
}
JSON

Returns: BulkDeleteResponse with success, deleted_count, and message


delete_user_playbooks_by_ids

Delete multiple user playbooks by their IDs.

Python
response = client.delete_user_playbooks_by_ids(user_playbook_ids=[1, 2, 3])
Terminal
curl -X DELETE "${REFLEXIO_URL:-https://www.reflexio.ai}/api/delete_user_playbooks_by_ids" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "user_playbook_ids": [
    1,
    2,
    3
  ]
}
JSON

Returns: BulkDeleteResponse with success, deleted_count, and message


delete_all_playbooks

Delete all playbooks (both user and agent). Cascading variant — wipes both stores.

Python
response = client.delete_all_playbooks()
Terminal
curl -X DELETE "${REFLEXIO_URL:-https://www.reflexio.ai}/api/delete_all_playbooks" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY"

Returns: BulkDeleteResponse with success, deleted_count, and message


delete_all_user_playbooks

Delete all user playbooks (user only, not agent).

Python
response = client.delete_all_user_playbooks()
Terminal
curl -X DELETE "${REFLEXIO_URL:-https://www.reflexio.ai}/api/delete_all_user_playbooks" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY"

Returns: BulkDeleteResponse with success, deleted_count, and message


delete_all_agent_playbooks

Delete all agent playbooks (agent only, not user).

Python
response = client.delete_all_agent_playbooks()
Terminal
curl -X DELETE "${REFLEXIO_URL:-https://www.reflexio.ai}/api/delete_all_agent_playbooks" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY"

Returns: BulkDeleteResponse with success, deleted_count, and message