Documentation Index Fetch the complete documentation index at: https://mintlify.com/helicone/helicone/llms.txt
Use this file to discover all available pages before exploring further.
Custom Properties let you attach metadata to every LLM request using simple HTTP headers. This metadata becomes queryable in the dashboard and API, enabling you to filter, segment, and analyze your data by any dimension that matters to your business.
Why Use Custom Properties
Without custom properties:
❌ Can’t segment costs by feature, environment, or user type
❌ Hard to trace which requests belong to specific workflows
❌ No way to filter requests by your business dimensions
❌ Limited debugging context for production issues
With custom properties:
✅ Filter requests by environment, feature, version, or any custom dimension
✅ Calculate cost per user, feature, or workflow
✅ Debug issues by filtering on relevant metadata
✅ Analyze performance across different segments
✅ Track business metrics alongside technical metrics
Quick Start
Add custom properties using HTTP headers with the format Helicone-Property-[Name]:
import { OpenAI } from "openai" ;
const client = new OpenAI ({
baseURL: "https://ai-gateway.helicone.ai" ,
apiKey: process . env . HELICONE_API_KEY ,
});
const response = await client . chat . completions . create (
{
model: "gpt-4o-mini" ,
messages: [{ role: "user" , content: "Hello!" }]
},
{
headers: {
"Helicone-Property-Environment" : "production" ,
"Helicone-Property-Feature" : "chat" ,
"Helicone-Property-Version" : "v2.1.0" ,
"Helicone-User-Id" : "user-123"
}
}
);
Common Property Patterns
Environment & Deployment
Track which environment requests come from:
const headers = {
"Helicone-Property-Environment" : process . env . NODE_ENV , // "production", "staging", "development"
"Helicone-Property-Version" : packageJson . version , // "v2.1.0"
"Helicone-Property-Region" : process . env . AWS_REGION , // "us-east-1"
"Helicone-Property-DeploymentId" : process . env . DEPLOY_ID // "deploy-abc123"
};
Use cases:
Compare costs across environments
Debug production-specific issues
Track performance by region
Analyze usage by deployment version
Feature & Workflow
Identify which feature or workflow made the request:
const headers = {
"Helicone-Property-Feature" : "chat" , // "chat", "summarize", "translate"
"Helicone-Property-Workflow" : "customer-support" , // "customer-support", "content-gen"
"Helicone-Property-Component" : "message-handler" , // "message-handler", "analyzer"
"Helicone-Property-RequestType" : "user-query" // "user-query", "system-task"
};
Use cases:
Calculate cost per feature
Optimize expensive workflows
Track feature adoption
Debug specific workflow failures
User Segmentation
Segment by user characteristics:
const headers = {
"Helicone-User-Id" : userId , // "user-123"
"Helicone-Property-UserTier" : userTier , // "free", "pro", "enterprise"
"Helicone-Property-UserType" : userType , // "individual", "business"
"Helicone-Property-Organization" : orgId , // "org-456"
"Helicone-Property-SignupDate" : user . signupDate // "2024-01-15"
};
Use cases:
Calculate cost per user tier
Analyze usage by organization
Track power users
Measure cohort retention
Business Context
Add business-specific metadata:
const headers = {
"Helicone-Property-Industry" : "healthcare" , // "healthcare", "finance", "retail"
"Helicone-Property-UseCase" : "medical-coding" , // Your specific use case
"Helicone-Property-Priority" : "high" , // "low", "medium", "high"
"Helicone-Property-SLA" : "tier1" , // SLA tier for the request
"Helicone-Property-Campaign" : "spring-promo" // Marketing campaign
};
Use cases:
Calculate ROI by use case
Prioritize high-value requests
Track campaign effectiveness
Ensure SLA compliance
Filtering by Properties
Dashboard Filters
In the Helicone dashboard:
Go to the Requests page
Click Add Filter
Select Custom Property
Choose your property name and value
Click Apply
You can combine multiple property filters to narrow down results.
API Filtering
Critical: When filtering by custom properties via API, you MUST wrap the properties filter inside a request_response_rmt object. Omitting this wrapper returns empty results.
Single property filter:
curl --request POST \
--url https://api.helicone.ai/v1/request/query-clickhouse \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $HELICONE_API_KEY " \
--data '{
"filter": {
"request_response_rmt": {
"properties": {
"Environment": {
"equals": "production"
}
}
}
},
"limit": 100
}'
Multiple property filters:
curl --request POST \
--url https://api.helicone.ai/v1/request/query-clickhouse \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $HELICONE_API_KEY " \
--data '{
"filter": {
"left": {
"request_response_rmt": {
"properties": {
"Environment": {
"equals": "production"
}
}
}
},
"operator": "and",
"right": {
"request_response_rmt": {
"properties": {
"Feature": {
"equals": "chat"
}
}
}
}
},
"limit": 100
}'
Combining properties with other filters:
curl --request POST \
--url https://api.helicone.ai/v1/request/query-clickhouse \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $HELICONE_API_KEY " \
--data '{
"filter": {
"left": {
"request_response_rmt": {
"model": {
"equals": "gpt-4o-mini"
}
}
},
"operator": "and",
"right": {
"request_response_rmt": {
"properties": {
"Environment": {
"equals": "production"
}
}
}
}
},
"limit": 100
}'
Cost Analysis by Property
Calculate costs segmented by any custom property:
Cost per Feature
// Tag all requests by feature
const headers = {
"Helicone-Property-Feature" : featureName
};
// Query via API and sum costs
const features = [ "chat" , "summarize" , "translate" , "analyze" ];
for ( const feature of features ) {
const response = await fetch ( 'https://api.helicone.ai/v1/request/query-clickhouse' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ HELICONE_API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
filter: {
request_response_rmt: {
properties: {
Feature: { equals: feature }
}
}
}
})
});
const { data } = await response . json ();
const totalCost = data . reduce (( sum , req ) => sum + req . cost , 0 );
console . log ( ` ${ feature } : $ ${ totalCost . toFixed ( 2 ) } ` );
}
Cost per User Tier
// Tag requests by user tier
const headers = {
"Helicone-Property-UserTier" : userTier // "free", "pro", "enterprise"
};
// Calculate average cost per tier
const tiers = [ "free" , "pro" , "enterprise" ];
for ( const tier of tiers ) {
// Query requests for this tier
// Calculate: total cost / unique users
}
Cost per Environment
// Compare production vs staging costs
const environments = [ "production" , "staging" , "development" ];
for ( const env of environments ) {
// Query and sum costs by environment
}
Updating Properties After Request
You can add or update properties after a request is made:
// Make the request
const { data , response } = await client . chat . completions
. create ({ /* request */ })
. withResponse ();
// Get the request ID from response headers
const requestId = response . headers . get ( "helicone-id" );
// Update properties via API
await fetch ( `https://api.helicone.ai/v1/request/ ${ requestId } /property` , {
method: "PUT" ,
headers: {
"Authorization" : `Bearer ${ HELICONE_API_KEY } ` ,
"Content-Type" : "application/json"
},
body: JSON . stringify ({
"ResultCategory" : "success" ,
"ProcessingTime" : "1234" ,
"QualityScore" : "8.5"
})
});
Use cases:
Add properties based on response content
Update properties after post-processing
Tag requests with business outcome
Add quality scores or ratings
Property Naming Conventions
Best Practices
✅ Do:
Use PascalCase for property names: UserTier, FeatureName
Keep names concise but descriptive
Use consistent naming across your app
Document your property schema
❌ Don’t:
Use spaces or special characters
Include PII (personally identifiable information)
Use overly generic names like Type or Status
Change property names frequently
Example Schema
Document your properties for team consistency:
// properties-schema.ts
export const PropertySchema = {
// Environment
Environment: [ "production" , "staging" , "development" ],
Version: "semver string (e.g., v2.1.0)" ,
Region: [ "us-east-1" , "eu-west-1" , "ap-southeast-1" ],
// Feature
Feature: [ "chat" , "summarize" , "translate" , "analyze" ],
Workflow: [ "customer-support" , "content-generation" , "research" ],
Component: "string (e.g., message-handler)" ,
// User
UserTier: [ "free" , "pro" , "enterprise" ],
UserType: [ "individual" , "business" ],
Organization: "org-{id}" ,
// Business
Priority: [ "low" , "medium" , "high" ],
Industry: [ "healthcare" , "finance" , "retail" ],
Campaign: "string (e.g., spring-promo)"
};
Property Limits
No hard limit on number of properties per request
Keep property values under 1000 characters
Avoid overly complex or deeply nested values
Properties are indexed for fast querying:
Filtering by properties is performant
Use specific property values over wildcards
Combine filters efficiently (AND/OR logic)
Combining with Other Features
Properties + Sessions
Add properties to session requests:
const sessionId = randomUUID ();
await client . chat . completions . create (
{ /* request */ },
{
headers: {
// Session headers
"Helicone-Session-Id" : sessionId ,
"Helicone-Session-Path" : "/workflow/step" ,
"Helicone-Session-Name" : "Research Agent" ,
// Custom properties
"Helicone-Property-Environment" : "production" ,
"Helicone-Property-Topic" : "quantum-computing" ,
"Helicone-Property-Priority" : "high"
}
}
);
Now you can:
Filter sessions by properties
Analyze session costs by property
Debug sessions matching specific criteria
Properties + Traces
Add properties to custom traces:
import { HeliconeManualLogger } from "@helicone/helpers" ;
const logger = new HeliconeManualLogger ({
apiKey: process . env . HELICONE_API_KEY
});
await logger . logRequest (
{ /* trace data */ },
async ( resultRecorder ) => {
// Perform operation
const result = await performOperation ();
resultRecorder . appendResults ( result );
return result ;
},
{
"Helicone-Property-Operation" : "database_query" ,
"Helicone-Property-Table" : "users" ,
"Helicone-Property-Environment" : "production"
}
);
Use Case Examples
Multi-tenant SaaS
// Track costs per organization
const headers = {
"Helicone-Property-Organization" : orgId ,
"Helicone-Property-Workspace" : workspaceId ,
"Helicone-User-Id" : userId ,
"Helicone-Property-PlanType" : "enterprise"
};
// Calculate:
// - Cost per organization
// - Usage by workspace
// - Per-user costs within org
A/B Testing
// Track experiment variants
const variant = getUserExperiment ( userId , "new-prompt" );
const headers = {
"Helicone-Property-Experiment" : "new-prompt" ,
"Helicone-Property-Variant" : variant , // "control" or "treatment"
"Helicone-User-Id" : userId
};
// Analyze:
// - Cost difference between variants
// - Performance metrics by variant
// - User satisfaction by variant
Content Moderation
// Track moderation requests
const headers = {
"Helicone-Property-ContentType" : "user-message" ,
"Helicone-Property-ModerationLevel" : "strict" ,
"Helicone-Property-Category" : contentCategory ,
"Helicone-User-Id" : userId
};
// Later, add result
await updateRequestProperty ( requestId , {
"ModerationResult" : "flagged" ,
"FlagReason" : "inappropriate-content"
});
Troubleshooting
Properties Not Appearing
Problem : Properties aren’t showing up in the dashboard.
Solutions :
Verify header format: Helicone-Property-[Name]
Check that property name doesn’t contain spaces
Ensure value is a string (not an object or array)
Wait a few seconds for data to propagate
Can’t Filter by Property
Problem : Filtering by property returns no results.
Solutions :
In API, wrap properties in request_response_rmt object
Check property name matches exactly (case-sensitive)
Verify the property exists on your requests
Use equals operator for exact matches
Query Returns Empty Results
Problem : API query returns {"data":[], "error":null}.
Solutions :
Ensure request_response_rmt wrapper is present
Check that property value matches exactly
Verify date range includes requests with this property
Try querying without property filter first to verify data exists
Requests View and filter requests by custom properties
Sessions Combine properties with session tracking
User Metrics Analyze per-user metrics with Helicone-User-Id
Query API Query requests by properties programmatically
Questions?
Need help or have questions? We’re here to help: