api-billing-service-onboarding
API Billing Service Onboarding
Automates the complete process of adding a new third-party API service to the AWS Lambda-based billing and quota monitoring system.
Purpose
This skill provides a step-by-step workflow for integrating new API services into an existing AWS monitoring infrastructure that tracks account balances, quotas, and usage across multiple third-party services. The system monitors services every 30 minutes, pushes metrics to CloudWatch, triggers alerts via SNS to Feishu, and visualizes data on a centralized dashboard.
When to Use
Use this skill when the user requests to:
- Add monitoring for a new API service's balance, quota, or credits
- Set up alerts for low balance/quota on a third-party service
- Integrate a new service into the billing dashboard
- Monitor remaining usage or spending on an external API
Common trigger phrases:
- "Add [Service] to monitoring"
- "Monitor [Service] API balance"
- "Set up quota alerts for [Service]"
- "Track [Service] credits in dashboard"
Project Context
The monitoring system is located in /path/to/monitoring-system/ and consists of:
- Runtime: Node.js 18.x (TypeScript)
- Cloud Platform: AWS Lambda + CloudWatch + Secrets Manager + EventBridge + SNS
- Commands: Managed via
just(seejustfile) - Architecture: EventBridge (30min) → Lambda → CloudWatch Metrics → Alarms → SNS → Feishu
Key Files:
adapters/*.ts- API service adaptersadapters/index.ts- Adapter registrysrc/handler.ts- Lambda entry pointsrc/types.ts- BillingMetric interfacesrc/metrics.ts- CloudWatch metric publishingCLAUDE.md- Project documentation
Workflow
Step 1: Gather Service Information
Before starting implementation, collect the following information from the user:
- Service name (e.g., "resend", "sendgrid")
- API documentation URL (especially balance/quota endpoints)
- API Key/Token (will be stored in Secrets Manager)
- Alert threshold (absolute value or percentage)
- Service display name (for Dashboard labels)
Questions to ask:
- "What is the API endpoint for checking balance/quota?"
- "How does the API authenticate? (Bearer token, API key header, query param?)"
- "What response format does the API return? (JSON structure)"
- "What threshold should trigger an alert? (e.g., remaining < 100, or < 5%)"
- "What unit does the service use? (USD, credits, emails, requests?)"
Step 2: Create API Adapter
Create a new TypeScript adapter file at adapters/<service_name>.ts.
Refer to: references/adapter-templates.md for three common adapter patterns:
- Standard JSON response with balance fields
- Response headers containing quota information
- Prepaid credits with no total amount
The adapter must:
- Call the service's API to retrieve balance/quota
- Mask the API key (show first 6 and last 6 characters)
- Return a
BillingMetricobject with:service: lowercase service identifierapiKeyMask: masked API keytotal: total quota/balanceremaining: remaining quota/balanceremainingRatio: remaining/total (0-1)currency(optional): "USD", "CNY", etc.unit(optional): "credits", "emails", "requests"
Use the Read tool to examine existing adapters for reference:
adapters/resend.ts- Response header quota patternadapters/serper.ts- Prepaid credits patternadapters/scrapedo.ts- Standard JSON response pattern
Step 3: Register Adapter
Edit adapters/index.ts:
- Import the new adapter function
- Add entry to the
adaptersobject
Example:
import { fetchServiceName } from "./service_name";
export const adapters = {
// ... existing adapters
service_name: fetchServiceName,
};
Step 4: Update Lambda Handler
Edit src/handler.ts to add the service call logic.
Location: Insert before console.log("✅ Billing check completed")
Pattern:
// <Service Display Name>
if (apiKeys.<service_name>) {
try {
console.log("🔍 Fetching <Service> quota...");
const metric = await adapters.<service_name>(apiKeys.<service_name>);
await pushMetrics(metric);
results.push({
service: "<service_name>",
status: "success",
remaining: metric.remaining,
total: metric.total,
ratio: metric.remainingRatio
});
} catch (error: any) {
console.error("❌ <Service> error:", error.message);
results.push({ service: "<service_name>", status: "error", error: error.message });
}
}
Step 5: Add API Key to Secrets Manager
Use the helper script to safely add the API key:
scripts/add-secret-key.sh <service_name> <api_key>
Manual alternative:
# Get current secrets
aws secretsmanager get-secret-value \
--secret-id api-billing-monitor/keys \
--query SecretString --output text > /tmp/secrets.json
# Edit /tmp/secrets.json to add: "<service_name>": "<api_key>"
# Update secrets
aws secretsmanager update-secret \
--secret-id api-billing-monitor/keys \
--secret-string file:///tmp/secrets.json
Step 6: Build and Deploy
# Quick deployment (recommended)
just deploy-quick
# Or full deployment with verbose output
just deploy
Verify deployment:
# Trigger Lambda manually
just invoke
# Check logs for the new service
just logs | grep <service_name>
Step 7: Create CloudWatch Alarm
Choose the appropriate alarm strategy:
Strategy A: Absolute Value Threshold (for fixed quotas):
aws cloudwatch put-metric-alarm \
--alarm-name "<Service>-Low-Balance" \
--namespace "ThirdPartyAPIBilling" \
--metric-name "Remaining" \
--dimensions Name=Service,Value=<service_name> \
--statistic Average \
--period 1800 \
--evaluation-periods 1 \
--threshold <absolute_value> \
--comparison-operator LessThanThreshold \
--alarm-actions "arn:aws:sns:us-east-1:830101142436:CloudWatchAlarmsToFeishu" \
--alarm-description "<Service> remaining balance below <threshold>"
Strategy B: Percentage Threshold (for variable quotas):
aws cloudwatch put-metric-alarm \
--alarm-name "<Service>-Low-Ratio" \
--namespace "ThirdPartyAPIBilling" \
--metric-name "RemainingRatio" \
--dimensions Name=Service,Value=<service_name> \
--statistic Average \
--period 1800 \
--evaluation-periods 1 \
--threshold 0.05 \
--comparison-operator LessThanThreshold \
--alarm-actions "arn:aws:sns:us-east-1:830101142436:CloudWatchAlarmsToFeishu" \
--alarm-description "<Service> remaining ratio below 5%"
Verify alarm creation:
just alarms | grep <Service>
Step 8: Update CloudWatch Dashboard
Use the helper script to automatically add the service to the dashboard:
scripts/add-to-dashboard.sh <service_name> "<Service Display Name>" "<masked_api_key>"
Manual alternative:
-
Get current dashboard configuration:
aws cloudwatch get-dashboard \ --dashboard-name "API-Billing-Monitor" \ --query "DashboardBody" \ --output text > /tmp/dashboard.json -
Edit
/tmp/dashboard.jsonto add the service in 4 locations:- "所有服务剩余比例趋势" metrics array
- "当前剩余比例" metrics array
- Create a new widget (optional, for detailed service chart)
- "当前剩余额度/Credits" metrics array
-
Update dashboard:
aws cloudwatch put-dashboard \ --dashboard-name "API-Billing-Monitor" \ --dashboard-body file:///tmp/dashboard.json
Refer to: references/dashboard-widget-template.json for widget JSON structure examples.
Step 9: Update Project Documentation
Edit CLAUDE.md to add the new service to the "已接入服务" table:
| <service_name> | <unit> | <threshold> | <description> |
Step 10: Verification
Run the complete verification checklist:
# 1. Trigger monitoring
just invoke
# 2. Check logs for successful execution
just logs | grep "<service_name>"
# Expected: "✅ Metrics pushed for <service_name>"
# 3. Verify metrics in CloudWatch
aws cloudwatch list-metrics \
--namespace ThirdPartyAPIBilling \
--dimensions Name=Service,Value=<service_name>
# 4. Check alarm status
just alarms | grep "<Service>"
# 5. View current status
just status
# 6. Visit dashboard
echo "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#dashboards/dashboard/API-Billing-Monitor"
Success criteria:
- ✅ Lambda logs show successful metric push
- ✅ CloudWatch metrics exist for the service
- ✅ Alarm is in OK or ALARM state (not INSUFFICIENT_DATA)
- ✅ Dashboard displays the service in all charts
- ✅ Service appears in
just statusoutput
Troubleshooting
Lambda execution fails:
- Check logs:
just logs - Verify API key in Secrets Manager:
just secrets-full - Test API endpoint manually with curl/Postman
Metrics not appearing in CloudWatch:
- Confirm Lambda executed successfully:
just invoke - Check for errors in adapter code
- Verify metric push logic in logs
Dashboard shows no data:
- Wait 30 minutes for first execution cycle
- Confirm metrics exist:
aws cloudwatch list-metrics --namespace ThirdPartyAPIBilling - Verify Dashboard JSON syntax
Alarm not triggering:
- Check alarm configuration:
aws cloudwatch describe-alarms --alarm-names "<Service>-Low-Balance" - Verify metric data points exist
- Test alarm:
just test-alarm <Service>-Low-Balance
Notes
- The system runs on a 30-minute schedule via EventBridge
- All API keys are stored securely in AWS Secrets Manager
- Alarms notify via SNS to Feishu webhook
- The CloudWatch namespace is
ThirdPartyAPIBilling - Common dimension:
Service=<service_name>,APIKey=<masked_key>
For detailed examples and edge cases, refer to references/service-integration-examples.md.