> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runflow.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Context Management

> Manage execution information and user identification

The **Runflow Context** is a global singleton that manages execution information and user identification. It allows you to identify once and all agents/workflows automatically use this context.

## Why Identify Matters

When you call `identify()`, you're telling Runflow **who** is interacting with your agent. This single call connects three critical systems:

* **Memory** — conversation history is stored and retrieved by this identifier. Same identifier = same conversation history.
* **Traces** — all execution traces are linked to this user, so you can search and filter by user in the dashboard.
* **Metrics** — business events emitted with `track()` are associated with this user.

Without `identify()`, your agent still works, but memory won't persist correctly between sessions and your dashboard data won't be linked to specific users.

```typescript theme={null}
import { identify } from '@runflow-ai/sdk/observability';

// Always call identify BEFORE agent.process()
identify(userPhone);

const result = await agent.process({ message, sessionId });
```

## Basic Usage

```typescript theme={null}
import { Agent, openai } from '@runflow-ai/sdk';
import { identify } from '@runflow-ai/sdk/observability';

// Identify user by phone (WhatsApp)
identify('+5511999999999');

// Agent automatically uses the context
const agent = new Agent({
  name: 'WhatsApp Bot',
  instructions: 'You are a helpful assistant.',
  model: openai('gpt-4o'),
  memory: {
    maxTurns: 10,
  },
});

// Memory is automatically bound to the phone number
await agent.process({
  message: 'Hello!',
});
```

## Smart Identification (Auto-Detection)

**New in v2.1:** The `identify()` function now auto-detects entity type from value format:

```typescript theme={null}
import { identify } from '@runflow-ai/sdk/observability';

// Auto-detect email
identify('user@example.com');
// → type: 'email', value: 'user@example.com'

// Auto-detect phone (international)
identify('+5511999999999');
// → type: 'phone', value: '+5511999999999'

// Auto-detect phone (local with formatting)
identify('(11) 99999-9999');
// → type: 'phone', value: '(11) 99999-9999'

// Auto-detect UUID
identify('550e8400-e29b-41d4-a716-446655440000');
// → type: 'uuid'

// Auto-detect URL
identify('https://example.com');
// → type: 'url'
```

**Supported patterns:**

* **Email**: Standard RFC 5322 format
* **Phone**: E.164 format (with/without +, with/without formatting)
* **UUID**: Standard UUID v1-v5
* **URL**: With or without protocol
* **Fallback**: Generic `id` type for custom identifiers

## Explicit Identification

For custom entity types or when auto-detection is not desired:

```typescript theme={null}
import { identify } from '@runflow-ai/sdk/observability';

// HubSpot Contact
identify({
  type: 'hubspot_contact',
  value: 'contact_123',
  userId: 'user@example.com',
});

// Order/Ticket
identify({
  type: 'order',
  value: 'ORDER-456',
  userId: 'customer_789',
});

// Custom threadId override
identify({
  type: 'document',
  value: 'doc_456',
  threadId: 'custom_thread_123',
});
```

## Common Patterns

### WhatsApp / Phone Integration

The phone number is the natural identifier. Memory persists across all conversations with the same number:

```typescript theme={null}
identify('+5511999999999');
```

### Email-Based

For web apps or email integrations:

```typescript theme={null}
identify('user@example.com');
```

### Multi-Conversation

When the same user can have multiple independent conversations (e.g., different support tickets):

```typescript theme={null}
identify({
  type: 'session',
  value: `${userEmail}:${conversationId}`,
});
```

### Integration Webhooks

Parse the identifier from the webhook payload:

```typescript theme={null}
export async function main(input: any) {
  // Extract identifier from whatever your integration sends
  const userId = input.email || input.phone || input.userId;

  identify(userId);

  const result = await agent.process({ message: input.message, sessionId: input.sessionId });
  return { message: result.message };
}
```

## Backward Compatibility

The old `Runflow.identify()` API still works but is not recommended. Prefer the direct import:

<CodeGroup>
  ```typescript Recommended theme={null}
  import { identify } from '@runflow-ai/sdk/observability';

  identify('user@example.com');
  ```

  ```typescript Legacy (still works) theme={null}
  import { Runflow } from '@runflow-ai/sdk/core';

  Runflow.identify({
    type: 'email',
    value: 'user@example.com',
  });
  ```
</CodeGroup>

## State Management

```typescript theme={null}
import { Runflow } from '@runflow-ai/sdk/core';

// Get complete state
const state = Runflow.getState();

// Get specific value
const threadId = Runflow.get('threadId');
const entityType = Runflow.get('entityType');

// Set custom state (advanced)
Runflow.setState({
  entityType: 'custom',
  entityValue: 'xyz',
  threadId: 'my_custom_thread_123',
  userId: 'user_123',
  metadata: { custom: 'data' },
});

// Clear state (useful for testing)
Runflow.clearState();
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Best Practices" icon="lightbulb" href="/best-practices">
    Identify patterns and more tips
  </Card>

  <Card title="Memory" icon="brain" href="/core-concepts/memory">
    Learn about memory management
  </Card>

  <Card title="Observability" icon="chart-line" href="/core-concepts/observability">
    Track execution with observability
  </Card>

  <Card title="Quick Start" icon="rocket" href="/quickstart">
    See identify in action
  </Card>
</CardGroup>
