Headers allow you to pass request-specific values (like user IDs, authentication tokens, or organization metadata) to your Agent at runtime via HTTP headers. These values are validated, cached per conversation, and made available throughout your Agent system for:
Context Fetchers : Dynamic data retrieval based on request values
External Tools : Authentication and personalization for API calls
Agent Prompts : Personalized responses using context variables
Include context values as HTTP headers when calling your agent API. These headers are validated against your configured schema and cached for the conversation.
curl -N \
-X POST "http://localhost:3003/api/chat" \
-H "Authorization: Bearer $INKEEP_API_KEY " \
-H "user_id: u_123" \
-H "auth_token: t_abc" \
-H "org_name: Acme Corp" \
-H "Content-Type: application/json" \
-d '{
"messages": [ { "role": "user", "content": "What can you help me with?" } ],
"conversationId": "conv-123"
}'
Header keys are normalized to lowercase. Define them as lowercase in your schema and reference them as lowercase in templates.
Define a schema for your headers and configure how it's used in your agent.
You must include the headers schema in your context config.
import { z } from "zod" ;
import { agent , subAgent } from "@inkeep/agents-sdk" ;
import { contextConfig , fetchDefinition , headers } from '@inkeep/agents-core' ;
// Define schema for expected headers (use lowercase keys)
const personalAgentHeaders = headers ({
schema : z . object ({
user_id : z . string (),
auth_token : z . string (),
org_name : z . string (). optional ()
});
});
// Create a context fetcher that uses header values with type-safe templating
const userFetcher = fetchDefinition ({
id : "user-info" ,
name : "User Information" ,
trigger : "initialization" ,
fetchConfig : {
url : `https://api.example.com/users/ ${ personalAgentHeaders . toTemplate ( 'user_id' ) } ` ,
method : "GET" ,
headers : {
Authorization : `Bearer ${ personalAgentHeaders . toTemplate ( 'auth_token' ) } ` ,
},
transform : "user" , // Extract user from response, for example if the response is { "user": { "name": "John Doe", "email": "john.doe@example.com" } }, the transform will return the user object
},
responseSchema : z . object ({
user : z . object ({
name : z . string (),
email : z . string (),
}),
}),
defaultValue : "Guest User"
});
// Configure context for your agent
const personalAgentContext = contextConfig ({
headers : personalAgentHeaders ,
contextVariables : {
user : userFetcher ,
},
});
// Create a Sub Agent that uses context variables
const personalAssistant = subAgent ({
id : "personal-assistant" ,
name : "Personal Assistant" ,
description : "Personalized AI assistant" ,
prompt : `You are a helpful assistant for ${ personalAgentContext . toTemplate ( 'user.name' ) } from ${ personalAgentHeaders . toTemplate ( 'org_name' ) } .
User ID: ${ personalAgentHeaders . toTemplate ( 'user_id' ) }
Provide personalized assistance based on their context.` ,
});
// Attach context to your Agent
const myAgent = agent ({
id : "personal-agent" ,
name : "Personal Assistant Agent" ,
defaultSubAgent : personalAssistant ,
subAgents : () => [ personalAssistant ],
contextConfig : personalAgentContext ,
});
Validation : Headers are validated against your configured schema when a request arrives
Caching : Validated context is cached per conversation for reuse across multiple interactions
Reuse : Subsequent requests with the same conversationId
automatically use cached context values
Updates : Provide new header values to update the context for an ongoing conversation
Context values persist across conversation turns. To update them, send new header values with the same conversation ID.
Header values can be used in your agent prompts and fetch definitions using JSONPath template syntax {{headers.field_name}}
.
You can use the headers schema's toTemplate()
method for type-safe templating with autocomplete and validation.
Use header values to fetch dynamic data from external APIs:
// Define schema for expected headers (use lowercase keys)
const personalAgentHeaders = headers ({
schema : z . object ({
user_id : z . string (),
auth_token : z . string (),
org_name : z . string (). optional ()
});
});
const userDataFetcher = fetchDefinition ({
id : "user-data" ,
name : "User Data" ,
fetchConfig : {
url : `https://api.example.com/users/ ${ personalAgentHeaders . toTemplate ( 'user_id' ) } /profile` ,
headers : {
Authorization : `Bearer ${ personalAgentHeaders . toTemplate ( 'auth_token' ) } ` ,
"X-Organization" : personalAgentHeaders . toTemplate ( 'org_name' )
},
body : {
includePreferences : true ,
userId : personalAgentHeaders . toTemplate ( 'user_id' )
}
},
responseSchema : z . object ({
name : z . string (),
preferences : z . record ( z . unknown ())
})
});
// Configure context for your Agent
// You must include the headers schema and fetchers in your context config.
const personalAgentContext = contextConfig ({
headers : personalAgentHeaders ,
contextVariables : {
user : userFetcher ,
},
});
Reference context directly in agent prompts for personalization using the context config's template method:
// Create context config with both headers and fetchers
const userContext = contextConfig ({
headers : requestHeaders ,
contextVariables : {
userName : userDataFetcher ,
},
});
const assistantAgent = subAgent ({
prompt : `You are an assistant for ${ userContext . toTemplate ( 'userName' ) } from ${ requestHeaders . toTemplate ( 'org_name' ) } .
User context:
- ID: ${ requestHeaders . toTemplate ( 'user_id' ) }
- Organization: ${ requestHeaders . toTemplate ( 'org_name' ) }
Provide help tailored to their organization's needs.`
});
Configure external agents or MCP servers with dynamic headers using the headers schema:
// Define schema for expected headers (use lowercase keys)
const personalAgentHeaders = headers ({
schema : z . object ({
user_id : z . string (),
auth_token : z . string (),
org_name : z . string (). optional ()
});
});
// Configure external agent
const externalAgent = externalAgent ({
id : "external-service" ,
baseUrl : "https://external.api.com" ,
headers : {
Authorization : `Bearer ${ personalAgentHeaders . toTemplate ( 'auth_token' ) } ` ,
"X-User-Context" : personalAgentHeaders . toTemplate ( 'user_id' ),
"X-Org" : personalAgentHeaders . toTemplate ( 'org_name' )
}
});
// Configure context for your Agent with your headers schema.
const personalAgentContext = contextConfig ({
headers : personalAgentHeaders ,
});
Use lowercase keys : Always define schema properties in lowercase and reference them as lowercase in templates
Validate early : Test your schema configuration with sample headers before deploying
Cache wisely : Remember that context persists per conversation - design accordingly
Secure sensitive data : For long-lived secrets, use the system instead of headers
Keep it minimal : Only include context values that are actually needed by your agents
Pass tenant-specific configuration to customize agent behavior per customer:
// Headers
"tenant_id: acme-corp"
"tenant_plan: enterprise"
"tenant_features: advanced-analytics,custom-branding"
Provide user identity and session information for personalized interactions:
// Headers
"user_id: user_123"
"user_role: admin"
"session_token: sk_live_..."
Forward headers from your API gateway for consistent authentication:
// Headers
"x-api-key: your-api-key"
"x-request-id: req_abc123"
"x-client-version: 2.0.0"
If you receive a 400 error about invalid headers:
Verify your schema matches the headers you're sending
Ensure all header keys are lowercase
Check that required fields are present
Validate the data types match your schema
If context values aren't available in subsequent requests:
Ensure you're using the same conversationId
across requests
Verify headers are being sent correctly
Check that your context config is properly attached to the Agent
- Learn about fetching and caching external data
- Configure external agent integrations
- Manage secure credentials for your Agents