LLM observability with Langfuse — query traces, generations, costs, metrics, and debug LLM pipelines via the REST API
79%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Fix and improve this skill with Tessl
tessl review fix ./langfuse-observability/SKILL.mdLangfuse is an open-source LLM observability platform. Use this skill to query traces, generations, costs, and metrics from a self-hosted or cloud Langfuse instance.
# Set your Langfuse credentials
export LANGFUSE_HOST="https://langfuse.example.com" # or https://cloud.langfuse.com
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."All API calls use basic auth with public key as username and secret key as password.
# Base pattern for all requests
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/<endpoint>"curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/health" | jq .curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/traces?limit=10&page=1" | \
jq '.data[] | {id, name, timestamp, userId, totalCost, latency, tags}'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/traces?limit=20&fromTimestamp=2026-02-01T00:00:00Z&toTimestamp=2026-02-28T23:59:59Z" | \
jq '.data[] | {id, name, timestamp, totalCost, latency}'# By user
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/traces?limit=10&userId=USER_ID" | \
jq '.data[] | {id, name, timestamp, totalCost}'
# By trace name
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/traces?limit=10&name=TRACE_NAME" | \
jq '.data[] | {id, name, timestamp, totalCost}'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/traces/TRACE_ID" | \
jq '{id, name, timestamp, userId, sessionId, totalCost, latency, tags, metadata,
observations: [.observations[] | {id, type, name, model, startTime, totalCost, usage}]}'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/traces/TRACE_ID" | jq '{input, output}'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/observations?type=GENERATION&limit=10&page=1" | \
jq '.data[] | {id, name, model, startTime, totalCost, inputUsage: .usage.input, outputUsage: .usage.output}'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/observations?type=GENERATION&limit=10" | \
jq '[.data[] | select(.model | test("gpt-4"))] | .[] | {id, model, totalCost}'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/observations?type=GENERATION&traceId=TRACE_ID" | \
jq '.data[] | {id, name, model, totalCost, usage, input, output}'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/observations/OBSERVATION_ID" | \
jq '{id, type, name, model, modelParameters, startTime, endTime, totalCost, usage, level, statusMessage}'# Find errors
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/observations?level=ERROR&limit=10" | \
jq '.data[] | {id, traceId, name, model, level, statusMessage, startTime}'
# Find warnings
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/observations?level=WARNING&limit=10" | \
jq '.data[] | {id, traceId, name, model, level, statusMessage, startTime}'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/metrics/daily?limit=7" | \
jq '.data[] | {date, traces: .countTraces, cost: .totalCost,
models: [.usage[] | {model, input: .inputUsage, output: .outputUsage, total: .totalUsage}]}'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/metrics/daily?limit=30" | \
jq '{totalCost: ([.data[].totalCost] | add), totalTraces: ([.data[].countTraces] | add),
days: (.data | length), breakdown: [.data[] | {date, cost: .totalCost, traces: .countTraces}]}'# List recent sessions
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/sessions?page=1&limit=10" | \
jq '.data[] | {id, createdAt, projectId}'
# Get session details
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/sessions/SESSION_ID" | jq .# List scores
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/scores?limit=10" | \
jq '.data[] | {id, name, value, dataType, traceId, comment}'
# Scores for a specific trace
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/scores?traceId=TRACE_ID" | \
jq '.data[] | {name, value, dataType, comment}'services:
langfuse-web:
image: langfuse/langfuse:3
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://user:pass@postgres:5432/langfuse
NEXTAUTH_SECRET: your-secret
SALT: your-salt
ENCRYPTION_KEY: your-encryption-key
NEXTAUTH_URL: https://langfuse.example.com
AUTH_DISABLE_SIGNUP: "true"
depends_on: [postgres]
langfuse-worker:
image: langfuse/langfuse-worker:3
environment:
DATABASE_URL: postgresql://user:pass@postgres:5432/langfuse
SALT: your-salt
ENCRYPTION_KEY: your-encryption-key
postgres:
image: postgres:17
volumes:
- langfuse_pg:/var/lib/postgresql/data
environment:
POSTGRES_DB: langfuse
POSTGRES_USER: user
POSTGRES_PASSWORD: passLangfuse v3 also supports ClickHouse for trace storage, Redis for queuing, and MinIO for object storage.
Send traces automatically from OpenRouter to Langfuse:
https://langfuse.example.comAll OpenRouter LLM calls will then appear as traces in Langfuse.
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/traces?limit=50&fromTimestamp=$(date -d '7 days ago' +%FT00:00:00Z)" | \
jq '[.data[] | {id, name, totalCost, timestamp}] | sort_by(-.totalCost) | .[:10]'curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/observations?type=GENERATION&limit=100" | \
jq '[.data[] | .model] | group_by(.) | map({model: .[0], count: length}) | sort_by(-.count)'ERRORS=$(curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/observations?level=ERROR&limit=1" | jq '.meta.totalItems')
TOTAL=$(curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_HOST/api/public/observations?limit=1" | jq '.meta.totalItems')
echo "Error rate: $ERRORS / $TOTAL"fromTimestamp/toTimestamp) on large queries to avoid timeoutsmeta.page, meta.limit, meta.totalItems, meta.totalPages2026-02-10T00:00:00Zusage.input, usage.output, usage.totalddnetters/homelab-agent-skills
808c382
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.