You can give Claude access to your organization's customer data — CRM records, email history, Slack conversations, and more — by querying the Nex API before each Claude API call. Nex returns structured, permissioned context that you include in Claude's system prompt or user message, grounding responses in real organizational data rather than general knowledge.
Prerequisites
Before starting, you'll need:
A Nex account at app.nex.ai with at least one data source connected (CRM, email, or Slack)
A Nex API key — find yours at app.nex.ai → Settings → API Keys
An Anthropic API key from console.anthropic.com
Python 3.8+ or Node.js 18+
Install dependencies:
How It Works
The pattern is straightforward:
User or agent needs information about a customer
Query Nex /v1/context/ask with a natural language question
Nex returns structured context from your connected data sources
Include that context in Claude's system prompt
Claude responds with accurate, grounded information
Step 1: Connect Your Data Sources
Log in to app.nex.ai and connect your data sources:
Go to Settings → Integrations
Connect your CRM (HubSpot, Salesforce, Pipedrive)
Connect your email (Google Workspace or Microsoft 365)
Connect Slack if relevant to your use case
Nex will begin syncing your data. Initial sync typically completes within minutes for most CRM sizes.
Step 2: Get Your API Key
Navigate to Settings → API Keys in the Nex app and create a new key. Keep this secure — it provides access to your organizational data.
Step 3: Query Context and Call Claude
Python
import os
import requests
import anthropic
NEX_API_KEY = os.environ["NEX_API_KEY"]
TypeScript
import Anthropic from "@anthropic-ai/sdk";
const NEX_API_KEY = process.env.NEX_API_KEY!;
const NEX_BASE_URL = "https://app.nex.ai/api/developers";
const anthropicClient = new Anthropic();
interface NexContextResponse {
answer: string;
sources: Array<{ name: string; type: string }>;
}
async function getCustomerContext(
query: string,
customerName?: string
): Promise<NexContextResponse> {
const contextQuery = customerName ? `About ${customerName}: ${query}` : query;
const response = await fetch(`${NEX_BASE_URL}/v1/context/ask`, {
method: "POST",
headers: {
Authorization: `Bearer ${NEX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ query: contextQuery }),
});
if (!response.ok) {
throw new Error(`Nex API error: ${response.status}`);
}
return response.json();
}
async function askClaudeWithContext(
userMessage: string,
customerName?: string
): Promise<string> {
const contextData = await getCustomerContext(userMessage, customerName);
const sourceNames = contextData.sources.map((s) => s.name).join(", ");
const systemPrompt = `You are a helpful assistant with access to current organizational data.
When answering questions about customers, deals, or business relationships, use the provided
organizational context below. If the context does not contain relevant information, say so clearly.
Organizational Context:
---
${contextData.answer}
---
Data sources consulted: ${sourceNames}`;
const message = await anthropicClient.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
system: systemPrompt,
messages: [{ role: "user", content: userMessage }],
});
return (message.content[0]
Step 4: Advanced Patterns
Using the Timeline API for Relationship History
For customer-facing agents that need to understand the full history of interactions:
def get_customer_timeline(record_id: str) -> list:
"""Get the activity timeline for a specific record."""
headers = {"Authorization": f"Bearer {NEX_API_KEY}"}
response = requests.get(
f"{NEX_BASE_URL}/v1/records/{record_id}/timeline",
headers=headers
)
response.raise_for_status()
return response.json().get("events", [])
def build_context_for_call_prep(customer_name: str) -> str:
"""Build comprehensive call prep context for Claude."""
context = get_customer_context(
"What is the current deal stage, key contacts, recent emails, and any open issues?",
customer_name
)
search_response = requests.post(
f"{NEX_BASE_URL}/v1/search",
headers={"Authorization": f"Bearer {NEX_API_KEY}", "Content-Type": "application/json"},
json={"query": customer_name, "limit": 10}
)
search_results = search_response.json().get("results", [])
context_parts = [
f"## Current Account State
{context.get('answer', '')}",
f"
## Recent Activity
" + "
".join(
f"- {r.get('title', '')}: {r.get('summary', '')}"
for r in search_results[:5]
Streaming Responses with Real-Time Context
Common Use Cases
1. Sales Call Preparation
Give your sales team an AI assistant that knows everything about the account before a call — deal stage, key contacts, recent emails, competitor mentions, and open issues — all from your actual CRM and email data.
def prep_call(account_name: str) -> str:
context_query = f"""For account '{account_name}', provide:
1. Current deal stage and deal value
2. Key stakeholders and their roles
3. Last 3 email interactions and their topics
4. Any open issues or concerns mentioned
5. Competitor mentions if any"""
context = get_customer_context(context_query, account_name)
response = anthropic_client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1500,
system="You are a sales intelligence assistant. Prepare a concise call preparation brief using the provided context.",
messages=[{
"role": "user",
"content": f"Context:
{context['answer']}
Create a structured call prep brief."
}]
)
return response.content[0]
2. Customer Support Context Enrichment
When a support ticket comes in, automatically enrich Claude with the customer's full history before generating a response.
def handle_support_ticket(ticket_text: str, customer_email: str) -> str:
context = get_customer_context(
f"What is the history with customer {customer_email}? Previous tickets, product usage, and account health?",
customer_email
)
response = anthropic_client.messages.create(
model="claude-sonnet-4-6",
max_tokens=800,
system=f"You are a support agent. Use the customer context below to give an informed response.
Context:
{context['answer']}",
messages=[{"role": "user", "content": f"New support ticket:
{ticket_text}"}]
)
return response.content[0]
3. Weekly Account Summary
Automate account health summaries sent to account managers:
4. Multi-Turn Conversation with Persistent Context
class CustomerContextAgent:
def __init__(self, customer_name: str):
self.customer_name = customer_name
self.conversation_history = []
self.context = get_customer_context(
"Provide a comprehensive overview of this customer.",
customer_name
)
def chat(self, user_message: str) -> str:
self.conversation_history.append({"role": "user", "content": user_message})
response = anthropic_client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=f"You are an account intelligence assistant for {self.customer_name}.
Account context:
{self.context['answer']
FAQ
How does Nex handle data that changes between requests?
Nex maintains a real-time context graph that reflects changes in your connected data sources. When you query /v1/context/ask, you receive the current state of the data — including CRM updates, new emails, and recent Slack messages that may have arrived since your last request. There's no manual re-index cycle to trigger.
How should I handle cases where Nex returns no context?
Nex may return minimal context if a customer has little data in your connected sources or if the query doesn't match any records. In your Claude system prompt, instruct the model to acknowledge when context is limited rather than hallucinating. The code examples above include this pattern.
Is my customer data sent to Anthropic when I use this pattern?
When you include Nex context in a Claude API call, that context text is processed by Anthropic's API under your usage agreement. Review Anthropic's data handling policies for your compliance requirements. Nex itself stores and processes your data under its own SOC2 Type 1-compliant policies (verify at trust.nex.ai).
How do I filter context to only relevant data for a specific agent or role?
Nex's RBAC system ensures each API key can only access data within its permitted scope. Create separate API keys for different agent roles (sales agent key, support agent key) with appropriate data permissions configured in the Nex dashboard. Each key will only return data within its scope.
What model should I use for context-enriched prompts?
For complex organizational context queries, Claude Sonnet 4.6 (claude-sonnet-4-6) provides a strong balance of reasoning ability and context window capacity. If your context is extensive (full email threads, multiple account records), ensure you stay within the model's context window — use the Nex API's summarization features or limit the number of records retrieved per query.