# Session Management

Sessions are the way PizzaStack tracks all objects (tomatoes, sliced ingredients, sauces, bases, pizzas) across API calls. Every request includes an `X-Session-ID` header that links it to a session.

## How Sessions Work

A session is created automatically the first time you make a request with a given `X-Session-ID` value. All objects created during that session are tracked and can reference each other by ID.

```python
import requests
import uuid

API_BASE = "https://api.tomatopy.pizza/v1"
HEADERS = {
    "Content-Type": "application/json",
    "X-API-Key": "your-api-key",
    "X-Session-ID": str(uuid.uuid4())  # New session
}

# This request creates the session and a tomato within it
response = requests.post(f"{API_BASE}/tomato/acquire", headers=HEADERS, json={
    "variety": "San Marzano",
    "ripeness": 0.8,
    "weight": 150
})
tomato = response.json()
```

## The X-Session-ID Header

The `X-Session-ID` header is required on every request. It can be any unique string, but UUIDs are recommended.

```python
import uuid

# Generate a session ID
session_id = str(uuid.uuid4())  # e.g., "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
```

All requests in the same workflow should use the same session ID. Objects from one session cannot be referenced in another session.

```python
# These two requests share a session -- the sliced tomato can reference the acquired tomato
session_id = str(uuid.uuid4())
headers = {
    "Content-Type": "application/json",
    "X-API-Key": "your-api-key",
    "X-Session-ID": session_id
}

tomato = requests.post(f"{API_BASE}/tomato/acquire", headers=headers, json={
    "variety": "Roma", "ripeness": 0.85, "weight": 120
}).json()

sliced = requests.post(f"{API_BASE}/tomato/slice", headers=headers, json={
    "tomato_ids": [tomato["id"]],
    "method": "dice",
    "size": "medium",
    "consistency": "uniform"
}).json()
```

## Object Tracking Within a Session

Every object you create gets a unique ID prefixed by its type:

| Prefix | Type               | Created By        |
| ------ | ------------------ | ----------------- |
| `tom_` | Raw tomato         | `/tomato/acquire` |
| `slc_` | Sliced tomato      | `/tomato/slice`   |
| `jce_` | Tomato juice       | `/tomato/squeeze` |
| `sce_` | Sauce              | `/cook/simmer`    |
| `rst_` | Roasted ingredient | `/cook/roast`     |
| `bas_` | Pizza base         | `/pizza/base`     |
| `pza_` | Assembled pizza    | `/pizza/assemble` |
| `bkd_` | Baked pizza        | `/pizza/bake`     |

These IDs are only valid within their session. Passing an ID from one session into a request with a different `X-Session-ID` will return a 400 error.

## Debug Endpoint

### GET /v1/session/{session\_id}/log

Retrieve a log of all objects and operations in a session. This is useful for debugging pipeline issues.

```python
# Check session state
session_id = HEADERS["X-Session-ID"]
response = requests.get(
    f"{API_BASE}/session/{session_id}/log",
    headers={"X-API-Key": "your-api-key"}
)
log = response.json()

# Print all objects in the session
for entry in log["objects"]:
    print(f"{entry['id']} ({entry['type']}): sauce_quality={entry.get('sauce_quality', 'N/A')}")

# Print operation history
for op in log["operations"]:
    print(f"{op['timestamp']}: {op['endpoint']} -> {op['result_id']}")
```

Using `curl`:

```bash
curl -H "X-API-Key: your-api-key" \
  https://api.tomatopy.pizza/v1/session/your-session-id/log
```

## Session Lifecycle

Sessions have a limited lifetime. After a period of inactivity, sessions expire and their objects are no longer accessible.

```python
# Check if a session is still active by requesting its log
response = requests.get(
    f"{API_BASE}/session/{session_id}/log",
    headers={"X-API-Key": "your-api-key"}
)

if response.status_code == 200:
    print("Session is active")
elif response.status_code == 404:
    print("Session has expired or does not exist")
```

## Error Handling

```python
# Missing session ID
headers_no_session = {
    "Content-Type": "application/json",
    "X-API-Key": "your-api-key"
    # No X-Session-ID!
}

response = requests.post(f"{API_BASE}/tomato/acquire", headers=headers_no_session, json={
    "variety": "Roma", "ripeness": 0.8, "weight": 100
})
print(response.status_code)  # 400
print(response.json())       # {"error": "X-Session-ID header is required"}

# Cross-session reference
response = requests.post(f"{API_BASE}/tomato/slice", headers=HEADERS, json={
    "tomato_ids": ["tom_from_another_session"],
    "method": "dice",
    "size": "medium",
    "consistency": "uniform"
})
print(response.status_code)  # 400
print(response.json())       # {"error": "Object not found in session"}
```

## Best Practices

1. **One Session Per Workflow**

   Use a fresh session ID for each independent pizza-making workflow. Do not reuse session IDs across unrelated workflows.
2. **Use UUIDs for Session IDs**

   ```python
   import uuid
   session_id = str(uuid.uuid4())
   ```
3. **Check Session State When Debugging**

   If something is not working as expected, use the debug endpoint to inspect what objects exist and their quality values.
4. **Do Not Share Sessions Across Concurrent Workflows**

   Each concurrent workflow should have its own session ID to avoid conflicts.

## Endpoint Reference

| Endpoint                       | Method | Description                           |
| ------------------------------ | ------ | ------------------------------------- |
| `/v1/session/{session_id}/log` | GET    | Retrieve session log and object state |

## Next Steps

* [Tomato Endpoints](/docs/core-modules/ingredient-manipulation.md) - Start acquiring ingredients
* [Best Practices](/docs/best-practices/virtual-kitchen-management.md) - Session management best practices
* [Tutorials](/docs/tutorials/perfect-pizza-production.md) - End-to-end tutorial


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tomatopy.pizza/docs/core-modules/kitchen-hardware-interface.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
