clay-observability
Configures monitoring and alerts for Clay data enrichment pipelines to track costs and success rates.
Install
mkdir -p .claude/skills/clay-observability && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/5410" && unzip -o skill.zip -d .claude/skills/clay-observability && rm skill.zipInstalls to .claude/skills/clay-observability
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Monitor Clay enrichment pipeline health, credit consumption, and dataKey capabilities
- →Monitor Clay enrichment credit consumption
- →Track enrichment success rates
- →Configure alerts for pipeline failures
- →Visualize pipeline performance via dashboards
- →Calculate cost per enriched lead
How it works
It instruments webhook handlers to collect metrics on credit usage and hit rates, which are then exported to monitoring systems for visualization and alerting.
Inputs & outputs
When to use clay-observability
- →Monitor Clay enrichment credit consumption
- →Configure alerts for enrichment pipeline failures
- →Track data quality scores from Clay
- →Set up dashboards for integration health
About this skill
Clay Observability
Overview
Monitor Clay data enrichment pipeline health across four dimensions: credit consumption velocity, enrichment success rates (hit rates), data quality scores, and CRM sync reliability. Clay's credit-based pricing model makes observability essential for cost control.
Prerequisites
- Clay account with table access
- Metrics infrastructure (Prometheus/Grafana, Datadog, or custom)
- Webhook receiver that logs enrichment results
- Understanding of your enrichment column configuration
Instructions
Step 1: Instrument Your Clay Webhook Handler
// src/clay/metrics.ts — collect metrics from enriched data flowing back from Clay
interface ClayMetrics {
enrichmentsReceived: number;
enrichmentsWithEmail: number;
enrichmentsWithCompany: number;
enrichmentsWithPhone: number;
estimatedCreditsUsed: number;
averageICPScore: number;
leadsTier: { A: number; B: number; C: number; D: number };
}
class ClayMetricsCollector {
private metrics: ClayMetrics = {
enrichmentsReceived: 0,
enrichmentsWithEmail: 0,
enrichmentsWithCompany: 0,
enrichmentsWithPhone: 0,
estimatedCreditsUsed: 0,
averageICPScore: 0,
leadsTier: { A: 0, B: 0, C: 0, D: 0 },
};
private scoreSum = 0;
record(lead: Record<string, any>, creditsPerRow: number = 6) {
this.metrics.enrichmentsReceived++;
if (lead.work_email) this.metrics.enrichmentsWithEmail++;
if (lead.company_name) this.metrics.enrichmentsWithCompany++;
if (lead.phone_number) this.metrics.enrichmentsWithPhone++;
this.metrics.estimatedCreditsUsed += creditsPerRow;
const score = lead.icp_score || 0;
this.scoreSum += score;
this.metrics.averageICPScore = this.scoreSum / this.metrics.enrichmentsReceived;
if (score >= 80) this.metrics.leadsTier.A++;
else if (score >= 60) this.metrics.leadsTier.B++;
else if (score >= 40) this.metrics.leadsTier.C++;
else this.metrics.leadsTier.D++;
}
getReport(): string {
const m = this.metrics;
const emailRate = m.enrichmentsReceived > 0
? ((m.enrichmentsWithEmail / m.enrichmentsReceived) * 100).toFixed(1)
: '0';
const companyRate = m.enrichmentsReceived > 0
? ((m.enrichmentsWithCompany / m.enrichmentsReceived) * 100).toFixed(1)
: '0';
return [
`=== Clay Enrichment Report ===`,
`Total processed: ${m.enrichmentsReceived}`,
`Email find rate: ${emailRate}%`,
`Company match rate: ${companyRate}%`,
`Avg ICP score: ${m.averageICPScore.toFixed(1)}`,
`Lead distribution: A=${m.leadsTier.A} B=${m.leadsTier.B} C=${m.leadsTier.C} D=${m.leadsTier.D}`,
`Estimated credits used: ${m.estimatedCreditsUsed}`,
`Cost per email found: ${(m.estimatedCreditsUsed / Math.max(m.enrichmentsWithEmail, 1)).toFixed(1)} credits`,
].join('\n');
}
}
Step 2: Set Up Prometheus Metrics (Optional)
// src/clay/prometheus-metrics.ts
import { Counter, Gauge, Histogram } from 'prom-client';
// Counters
const clayEnrichmentsTotal = new Counter({
name: 'clay_enrichments_total',
help: 'Total enrichments received from Clay',
labelNames: ['table', 'status'],
});
const clayCreditsUsed = new Counter({
name: 'clay_credits_used_total',
help: 'Estimated Clay credits consumed',
labelNames: ['table', 'enrichment_type'],
});
// Gauges
const clayHitRate = new Gauge({
name: 'clay_enrichment_hit_rate',
help: 'Enrichment hit rate percentage',
labelNames: ['table', 'field'],
});
const clayCreditBalance = new Gauge({
name: 'clay_credit_balance',
help: 'Remaining Clay credits',
});
const clayICPScore = new Histogram({
name: 'clay_icp_score',
help: 'Distribution of ICP scores',
buckets: [20, 40, 60, 80, 100],
labelNames: ['table'],
});
// Record enrichment
function recordEnrichment(table: string, lead: Record<string, any>) {
clayEnrichmentsTotal.inc({ table, status: lead.work_email ? 'enriched' : 'empty' });
clayCreditsUsed.inc({ table, enrichment_type: 'waterfall' }, 6);
clayICPScore.observe({ table }, lead.icp_score || 0);
}
Step 3: Configure Alerting Rules
# prometheus/clay-alerts.yml
groups:
- name: clay-enrichment
rules:
- alert: ClayCreditBurnHigh
expr: rate(clay_credits_used_total[1h]) > 200
for: 15m
labels:
severity: warning
annotations:
summary: "Clay credit burn rate > 200/hour. Monthly projection: {{ $value | humanize }} credits"
- alert: ClayLowEmailHitRate
expr: clay_enrichment_hit_rate{field="email"} < 40
for: 30m
labels:
severity: warning
annotations:
summary: "Email find rate below 40% on table {{ $labels.table }}. Check input data quality."
- alert: ClayCreditBalanceLow
expr: clay_credit_balance < 500
labels:
severity: critical
annotations:
summary: "Clay credit balance below 500. Enrichments will stop when credits run out."
- alert: ClayWebhookFailureRate
expr: rate(clay_enrichments_total{status="error"}[15m]) > 0.1
labels:
severity: warning
annotations:
summary: "Clay webhook callback failure rate > 10%"
Step 4: Build a Dashboard
Key panels for a Clay observability dashboard:
dashboard_panels:
row_1:
- name: "Credit Balance"
type: gauge
metric: clay_credit_balance
thresholds: [500, 1000, 5000]
- name: "Credits Used Today"
type: stat
metric: increase(clay_credits_used_total[24h])
- name: "Email Hit Rate"
type: gauge
metric: clay_enrichment_hit_rate{field="email"}
thresholds: [40, 60, 80]
row_2:
- name: "Credit Burn Rate (hourly)"
type: timeseries
metric: rate(clay_credits_used_total[1h])
- name: "ICP Score Distribution"
type: histogram
metric: clay_icp_score
row_3:
- name: "Lead Tier Breakdown"
type: piechart
metric: clay_enrichments_total by (tier)
- name: "Cost per Enriched Lead"
type: stat
metric: clay_credits_used_total / clay_enrichments_total{status="enriched"}
Step 5: Daily Summary Report
// src/clay/daily-report.ts — generate daily enrichment summary
function generateDailyReport(collector: ClayMetricsCollector): void {
console.log(collector.getReport());
// Post to Slack
if (process.env.SLACK_WEBHOOK_URL) {
fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `*Daily Clay Enrichment Report*\n\`\`\`\n${collector.getReport()}\n\`\`\``,
}),
}).catch(console.error);
}
}
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Credits depleting fast | High waterfall depth or uncapped tables | Add credit burn alert, reduce waterfall |
| Hit rate near 0% | Invalid input data (personal domains, typos) | Add data quality monitoring, pre-filter |
| Missing metrics | Webhook handler not instrumented | Add metrics collection to callback handler |
| Dashboard shows stale data | Metrics not being pushed | Verify Prometheus scrape config |
Resources
Next Steps
For incident response, see clay-incident-runbook.
Prerequisites
Limitations
- →Credits depleting fast
- →Hit rate near 0%
- →Missing metrics
How it compares
It focuses specifically on the credit-based pricing model of Clay to provide cost-control observability alongside standard performance monitoring.
Compared to similar skills
clay-observability side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| clay-observability (this skill) | 1 | 27d | Caution | Intermediate |
| agent-session-monitor | 2 | 6mo | Review | Intermediate |
| ideogram-observability | 1 | 27d | Review | Intermediate |
| coralogix-analysis | 1 | 5mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by jeremylongshore
View all by jeremylongshore →You might also like
agent-session-monitor
alibaba
Real-time agent conversation monitoring - monitors Higress access logs, aggregates conversations by session, tracks token usage. Supports web interface for viewing complete conversation history and costs. Use when users ask about current session token consumption, conversation history, or cost statistics.
ideogram-observability
jeremylongshore
Set up comprehensive observability for Ideogram integrations with metrics, traces, and alerts. Use when implementing monitoring for Ideogram operations, setting up dashboards, or configuring alerting for Ideogram integration health. Trigger with phrases like "ideogram monitoring", "ideogram metrics", "ideogram observability", "monitor ideogram", "ideogram alerts", "ideogram tracing".
coralogix-analysis
incidentfox
Coralogix log analysis with DataPrime query language. Use when querying Coralogix logs, metrics, or traces. Provides syntax reference and intelligent investigation scripts.
dt-app-notebooks
TechShady
Work with Dynatrace notebooks - create, modify, query, and analyze notebook JSON. Derives from the dt-app-dashboards skill with notebook-specific differences documented here.
distributed-tracing
wshobson
Implement distributed tracing with Jaeger and Tempo to track requests across microservices and identify performance bottlenecks. Use when debugging microservices, analyzing request flows, or implementing observability for distributed systems.
service-mesh-observability
wshobson
Implement comprehensive observability for service meshes including distributed tracing, metrics, and visualization. Use when setting up mesh monitoring, debugging latency issues, or implementing SLOs for service communication.