Managing Requests & Sessions
Choose request metadata, inspect stored requests, filter by time or request id, and clean up request/session data.
Requests and sessions are how Emend keeps your agent traffic organized. Use this guide when you need to choose request metadata, inspect what was stored, or delete one request versus a whole session.
For method-level details, see the Requests API Reference and Publishing Interactions API Reference.
Setup
from emend import EmendClient client = EmendClient() # uses EMEND_API_KEY env var# Self-hosted: client = EmendClient(url_endpoint="http://localhost:8081")Mental Model
- Interaction: one message, tool result, image, or other item in the turn you publish.
- Request: one
publish_interactioncall. Emend creates arequest_idand stores the interactions,user_id,source,agent_version, andsession_idtogether. - Session: the conversation, task, experiment run, or support ticket that multiple requests belong to. Reuse the same
session_idfor all turns that should be understood together.
The most common production pattern is: publish each agent turn as one request, reuse the same session_id for the whole conversation, and keep source and agent_version stable enough to debug where behavior came from.
source is a non-sensitive producer/workflow machine label. Empty means the source is absent where the API permits it. Every non-empty value must match ^[a-z0-9][a-z0-9._:-]{0,127}$ and is limited to 128 ASCII characters. Do not include user identifiers, email addresses, or other PII. For example, support-agent:v2 is valid.
Which Workflow Should I Follow?
| Stage | Task | API | Description | Note |
|---|---|---|---|---|
| Before publishing | Choose request metadata | session_id / source / agent_version | Decide how traffic should be grouped and attributed before sending interactions from your app. | Prevents messy data later |
| Payload examples | Publish interactions | client.publish_interaction | Use the publishing page when you need examples for text turns, images, screenshots, expert content, or user action tracking. | Owns payload shape |
| Debugging and audit | Inspect stored requests | client.get_requests | Use this to review what was published, filter by user or time window, or find the request id you need for a targeted cleanup. | Returns sessions with requests |
| Cleanup | Delete request data | delete_request / delete_session | Delete one request when a single turn is wrong. Delete a whole session for temporary tests, experiments, or user-requested cleanup. | Use carefully |
Parameter Guide
| Parameter | Use it when | Why it matters |
|---|---|---|
| user_id | Publishing or retrieving data for a specific end user. | Profiles and user playbooks are scoped to this user. Use your stable application user id. |
| interactions | Sending the actual content for one request. | The payload examples live in Publishing Interactions; this page explains the request container around them. |
| session_id | Grouping related requests into one conversation, ticket, task, or experiment. | Required for publishing. It gives extraction and evaluation the surrounding context and lets you delete the group later. |
| source | Distinguishing which producer or workflow emitted traffic, such as support-agent:v2, web-app, staging-eval, or shadow-test. | Useful for audits, evaluation filters, and understanding which integration produced a request. |
| agent_version | Tracking the agent build, prompt version, or model configuration that produced the response. | Helps compare behavior across deployments and debug regressions. |
| wait_for_response | You need confirmed extraction counts or deletion confirmation before continuing. | False is faster for normal publish and cleanup paths. True waits for server-side processing and returns richer confirmation. |
| skip_aggregation | You want profiles/user playbooks extracted but do not want this publish to update agent playbook aggregation. | Useful for controlled tests or specialized ingestion jobs. Leave it off for normal product traffic. |
| force_extraction | You are running a deliberate test and need extraction to run even if gates would normally skip it. | Bypasses extraction gates. Use sparingly because it can increase LLM work. |
| evaluation_only | The request should be stored for session-level evaluation but should not teach profiles or playbooks. | Useful for evaluation datasets and shadow runs that should not affect production learning. |
Choose Request Metadata Before Publishing
Before you publish interaction content, decide how you want the request to be grouped and attributed. These choices make later inspection, evaluation, and cleanup much easier.
| Decision | Recommended choice | Avoid |
|---|---|---|
| session_id | Use the host conversation id, support ticket id, call id, task id, or experiment run id. Reuse it for every request in the same conversation. | Generating a new id for every turn in one conversation. |
| source | Use a small stable set such as support-agent:v2, web-app, offline-eval, or shadow-test. | Encoding high-cardinality details like timestamps or request ids, or any user identifiers, email addresses, or other PII. |
| agent_version | Use the deployed agent version, prompt version, model bundle, or candidate name. | Leaving production traffic indistinguishable across agent releases. |
| wait_for_response | Keep False for high-volume production traffic. Use True in tests, demos, notebooks, or backfills that need immediate counts. | Waiting synchronously on every production turn unless your app truly needs it. |
For full publishing examples, including text turns, images, screenshots, expert content, and user actions, use Publishing Interactions.
Inspect Requests for a User
Use get_requests when you need to see what was stored. The response is grouped by session, and each session contains one or more request objects with their interactions.
Use the broad user query for support review or audit screens. Add a time range for incident debugging or batch jobs. Use request_id when you already know the specific request you need to inspect.
response = client.get_requests( user_id="customer_123", top_k=50,) for session in response.sessions: print(f"Session: {session.session_id}") for request_data in session.requests: request = request_data.request print(f" Request: {request.request_id}") print(f" Source: {request.source}") print(f" Agent version: {request.agent_version}") print(f" Interactions: {len(request_data.interactions)}")Filter by Time or Request ID
Time filters are useful for "what happened during this deploy window?" or "what did this user do in the last week?" request_id is the narrowest lookup and is the safest way to inspect before deleting one request.
from datetime import datetime, timedelta, timezone recent_requests = client.get_requests( user_id="customer_123", start_time=datetime.now(timezone.utc) - timedelta(days=7), end_time=datetime.now(timezone.utc),) single_request = client.get_requests(request_id="req_12345")Clean Up Request Data
Delete data at the smallest scope that matches your intent:
- Use
delete_requestwhen one turn was malformed, duplicated, or published to the wrong user. - Use
delete_sessionwhen the whole conversation, test run, or experiment should be removed. delete_sessionpreserves an external session outcome. Use governance erasure when subject-owned outcome data must also be removed.- Use
wait_for_response=Truewhen your script must confirm deletion before it proceeds. Without it, the Python client returns immediately after scheduling the delete request.
Delete One Request
response = client.delete_request( request_id="req_12345", wait_for_response=True,) if response and response.success: print(response.message)Delete a Whole Session
response = client.delete_session( session_id="support_ticket_789", wait_for_response=True,) if response and response.success: print(f"Deleted {response.deleted_requests_count} requests")Fire-and-Forget Cleanup
Use this for low-risk cleanup jobs where the caller does not need confirmation. If you need the deleted count, use wait_for_response=True instead.
client.delete_session( session_id="old_test_run_001", wait_for_response=False,)Request-Level Processing Flags
These publish_interaction flags change how the request is processed after it is stored. They are useful, but they should not be the default for normal production traffic. For full payload examples, use Publishing Interactions.
| Flag | Use it when | Effect |
|---|---|---|
| wait_for_response | A test, demo, notebook, or backfill needs immediate request ids, diagnostics, or extraction counts. | False returns after the server queues processing. True waits for server-side processing and returns richer confirmation. |
| evaluation_only | A session should be evaluated but should not teach user profiles or playbooks. | Stores the request for session-level evaluation while excluding it from learning pipelines. |
| force_extraction | You are intentionally testing extraction and need to bypass normal skip gates. | Runs extraction even when stride, pre-filter, or should-run gates would normally skip it. |
| skip_aggregation | You want to inspect extracted profile or user-playbook signals without updating agent playbook aggregation. | Allows extraction while avoiding an agent-playbook aggregation update for that publish. |
Common Choices
| Scenario | Follow this example | Why |
|---|---|---|
| Choosing ids and metadata before sending traffic | Choose request metadata before publishing | Keeps later review, evaluation, and cleanup predictable. |
| Publishing text, images, screenshots, expert content, or user actions | Publishing Interactions | That page owns payload shape and content examples. |
| Debugging a user report | Inspect requests for a user | Shows what was actually stored, grouped by session. |
| Investigating a deploy window | Filter by time or request ID | Narrows review to the relevant time range or exact request. |
| Removing one bad publish | Delete one request | Limits cleanup to the malformed or duplicated request. |
| Removing a temporary test run | Delete a whole session | Removes every request from that test/session at once. |
| Running evaluation data that must not teach memory | Request-level processing flags | Stores evidence for evaluation without affecting learned context. |
| Testing extractor behavior | Request-level processing flags | Forces extraction and can avoid aggregation side effects. |