curl --request PUT \
--url https://api.helicone.ai/v1/request/{requestId}/property \
--header 'Content-Type: application/json' \
--data '
{
"key": "<string>",
"value": "<string>"
}
'{
"data": null,
"error": {}
}Add or update custom properties on a request after it has been created
curl --request PUT \
--url https://api.helicone.ai/v1/request/{requestId}/property \
--header 'Content-Type: application/json' \
--data '
{
"key": "<string>",
"value": "<string>"
}
'{
"data": null,
"error": {}
}Add custom properties to a request after it has been logged. This is useful when you need to enrich request metadata based on business logic, user actions, or post-processing results that aren’t available at the time of the original request.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.
Helicone-Property-* headers. See Custom Properties for more details.Helicone-Id response header when making requests through Helicone.Example: req_abc123def456"ConversationOutcome", "UserSatisfaction", "ProcessingStatus""resolved", "high", "completed"curl --request PUT \
--url https://api.helicone.ai/v1/request/req_abc123def456/property \
--header 'Authorization: Bearer <HELICONE_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"key": "ConversationOutcome",
"value": "resolved"
}'
const requestId = 'req_abc123def456';
const response = await fetch(
`https://api.helicone.ai/v1/request/${requestId}/property`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
key: 'ConversationOutcome',
value: 'resolved'
})
}
);
const result = await response.json();
console.log('Property added successfully');
import os
import requests
request_id = "req_abc123def456"
response = requests.put(
f"https://api.helicone.ai/v1/request/{request_id}/property",
headers={
"Authorization": f"Bearer {os.environ['HELICONE_API_KEY']}",
"Content-Type": "application/json"
},
json={
"key": "ConversationOutcome",
"value": "resolved"
}
)
result = response.json()
print("Property added successfully")
const addMultipleProperties = async (
requestId: string,
properties: Record<string, string>
) => {
const promises = Object.entries(properties).map(([key, value]) =>
fetch(
`https://api.helicone.ai/v1/request/${requestId}/property`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key, value })
}
)
);
await Promise.all(promises);
console.log('All properties added successfully');
};
// Usage
await addMultipleProperties('req_abc123def456', {
'ConversationOutcome': 'resolved',
'ResolutionTime': '5m',
'CustomerSatisfaction': 'high',
'AgentId': 'agent_789'
});
import os
import requests
from concurrent.futures import ThreadPoolExecutor
def add_property(request_id: str, key: str, value: str):
response = requests.put(
f"https://api.helicone.ai/v1/request/{request_id}/property",
headers={
"Authorization": f"Bearer {os.environ['HELICONE_API_KEY']}",
"Content-Type": "application/json"
},
json={"key": key, "value": value}
)
return response.json()
def add_multiple_properties(request_id: str, properties: dict):
with ThreadPoolExecutor(max_workers=5) as executor:
futures = [
executor.submit(add_property, request_id, key, value)
for key, value in properties.items()
]
results = [future.result() for future in futures]
print("All properties added successfully")
return results
# Usage
add_multiple_properties("req_abc123def456", {
"ConversationOutcome": "resolved",
"ResolutionTime": "5m",
"CustomerSatisfaction": "high",
"AgentId": "agent_789"
})
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://gateway.helicone.ai/v1',
defaultHeaders: {
'Helicone-Auth': `Bearer ${process.env.HELICONE_API_KEY}`
}
});
// Make the request
const { data, response } = await client.chat.completions
.create({
model: 'gpt-4',
messages: [{ role: 'user', content: 'Explain quantum computing' }]
})
.withResponse();
const requestId = response.headers.get('helicone-id');
const responseText = data.choices[0].message.content;
// Analyze the response and add properties
const wordCount = responseText.split(' ').length;
const hasCodeExample = responseText.includes('```');
const sentiment = analyzesentiment(responseText); // Your sentiment analysis
// Add enrichment properties
await Promise.all([
fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'WordCount', value: wordCount.toString() })
}),
fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'HasCodeExample', value: hasCodeExample.toString() })
}),
fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'Sentiment', value: sentiment })
})
]);
const processWorkflow = async (userQuery: string) => {
// Step 1: Initial LLM call
const { data: step1Data, response: step1Response } = await client.chat.completions
.create({
model: 'gpt-4',
messages: [{ role: 'user', content: userQuery }]
})
.withResponse();
const requestId = step1Response.headers.get('helicone-id');
// Mark as processing
await fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'WorkflowStatus', value: 'processing' })
});
// Step 2: Additional processing
const processingResult = await processData(step1Data);
// Update status
await fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'WorkflowStatus', value: 'completed' })
});
// Add final outcome
await fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'FinalOutcome', value: processingResult.status })
});
};
const handleSupportConversation = async (ticketId: string, userMessage: string) => {
// Make request with initial properties
const { data, response } = await client.chat.completions
.create(
{
model: 'gpt-4',
messages: [
{ role: 'system', content: 'You are a helpful support agent.' },
{ role: 'user', content: userMessage }
]
},
{
headers: {
'Helicone-Property-TicketId': ticketId,
'Helicone-Property-Channel': 'chat'
}
}
)
.withResponse();
const requestId = response.headers.get('helicone-id');
// User interaction happens...
// Later, after ticket is resolved:
await Promise.all([
fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'TicketStatus', value: 'resolved' })
}),
fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'ResolutionTime', value: '15m' })
}),
fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'RequiredEscalation', value: 'false' })
})
]);
};
const runExperiment = async (variant: 'A' | 'B') => {
const { data, response } = await client.chat.completions
.create(
{
model: 'gpt-4',
messages: [{ role: 'user', content: 'Explain climate change' }]
},
{
headers: {
'Helicone-Property-Variant': variant,
'Helicone-Property-Experiment': 'prompt-test-1'
}
}
)
.withResponse();
const requestId = response.headers.get('helicone-id');
const responseText = data.choices[0].message.content;
// Evaluate response quality
const qualityScore = await evaluateQuality(responseText);
const userEngagement = await trackUserEngagement(responseText);
// Add evaluation results as properties
await Promise.all([
fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'QualityScore', value: qualityScore.toString() })
}),
fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'UserEngagement', value: userEngagement })
}),
fetch(`https://api.helicone.ai/v1/request/${requestId}/property`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'EvaluationComplete', value: 'true' })
})
]);
};
// Query all resolved support tickets
const response = await fetch(
'https://api.helicone.ai/v1/request/query',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.HELICONE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
filter: {
request_response_rmt: {
properties: {
'TicketStatus': {
equals: 'resolved'
}
}
}
},
limit: 100
})
}
);
Helicone-Property-* headers for properties known at request time, and this API for post-request enrichmentPromise.all() to make parallel requests for better performance