api-monetization
Use this skill when designing or implementing API monetization strategies - usage-based pricing, rate limiting, developer tier management, Stripe metering integration, or API billing systems. Triggers on tasks involving API pricing models, metered billing, per-request charging, quota enforcement, developer portal tiers, overage handling, and Stripe usage records.
engineering apimonetizationpricingrate-limitingstripebillingWhat is api-monetization?
Use this skill when designing or implementing API monetization strategies - usage-based pricing, rate limiting, developer tier management, Stripe metering integration, or API billing systems. Triggers on tasks involving API pricing models, metered billing, per-request charging, quota enforcement, developer portal tiers, overage handling, and Stripe usage records.
api-monetization
api-monetization is a production-ready AI agent skill for claude-code, gemini-cli, openai-codex, and 1 more. Designing or implementing API monetization strategies - usage-based pricing, rate limiting, developer tier management, Stripe metering integration, or API billing systems.
Quick Facts
| Field | Value |
|---|---|
| Category | engineering |
| Version | 0.1.0 |
| Platforms | claude-code, gemini-cli, openai-codex, mcp |
| License | MIT |
How to Install
- Make sure you have Node.js installed on your machine.
- Run the following command in your terminal:
npx skills add AbsolutelySkilled/AbsolutelySkilled --skill api-monetization- The api-monetization skill is now available in your AI coding agent (Claude Code, Gemini CLI, OpenAI Codex, etc.).
Overview
API monetization is the practice of turning API usage into a revenue stream through pricing models, metering, and billing infrastructure. It spans from defining developer tiers and rate limits to integrating with payment providers like Stripe for usage-based billing. This skill covers the full stack: pricing model design, quota enforcement, metered usage tracking, and Stripe integration for automated invoicing.
Tags
api monetization pricing rate-limiting stripe billing
Platforms
- claude-code
- gemini-cli
- openai-codex
- mcp
Related Skills
Pair api-monetization with these complementary skills:
Frequently Asked Questions
What is api-monetization?
Use this skill when designing or implementing API monetization strategies - usage-based pricing, rate limiting, developer tier management, Stripe metering integration, or API billing systems. Triggers on tasks involving API pricing models, metered billing, per-request charging, quota enforcement, developer portal tiers, overage handling, and Stripe usage records.
How do I install api-monetization?
Run npx skills add AbsolutelySkilled/AbsolutelySkilled --skill api-monetization in your terminal. The skill will be immediately available in your AI coding agent.
What AI agents support api-monetization?
This skill works with claude-code, gemini-cli, openai-codex, mcp. Install it once and use it across any supported AI coding agent.
Maintainers
Generated from AbsolutelySkilled
SKILL.md
API Monetization
API monetization is the practice of turning API usage into a revenue stream through pricing models, metering, and billing infrastructure. It spans from defining developer tiers and rate limits to integrating with payment providers like Stripe for usage-based billing. This skill covers the full stack: pricing model design, quota enforcement, metered usage tracking, and Stripe integration for automated invoicing.
When to use this skill
Trigger this skill when the user:
- Wants to design a pricing model for a public or partner API
- Needs to implement usage-based or metered billing for API calls
- Asks about rate limiting strategies tied to paid tiers
- Wants to integrate Stripe metering or usage records into an API
- Needs to build a developer tier system (free, pro, enterprise)
- Asks about tracking API consumption per customer
- Wants to handle overage billing or throttling for quota breaches
- Needs to design a developer portal with tiered access
Do NOT trigger this skill for:
- General Stripe payments unrelated to API billing (use a Stripe skill)
- API gateway configuration without a monetization component
Key principles
Meter before you bill - Never charge for usage you cannot accurately measure. Instrument every billable endpoint with reliable counters before enabling paid tiers. Lost meter events mean lost revenue or customer disputes.
Tiers define the product, not just the price - Each developer tier should differ in meaningful capabilities (rate limits, endpoints available, SLA, support level), not just volume. This prevents a race-to-the-bottom on price.
Rate limits are a feature, not just protection - Rate limits serve dual duty: they protect infrastructure AND enforce tier boundaries. Design them as a first-class part of the product, with clear headers and upgrade paths.
Idempotent usage reporting - Usage records must be idempotent. Network retries, duplicate webhook deliveries, and reprocessed queues should never double-count usage. Use idempotency keys on every usage report call.
Graceful degradation over hard cutoffs - When a customer hits a quota, prefer throttling or overage billing over immediately blocking access. Hard cutoffs break production systems and destroy trust.
Core concepts
Pricing models fall into three categories: flat-rate (fixed monthly fee per tier), usage-based (pay per API call or resource unit), and hybrid (base fee plus usage overage). Most successful API businesses use hybrid pricing because it provides revenue predictability while rewarding growth.
Metering is the infrastructure that counts billable events. A meter sits between the API gateway and the billing system. It must be durable (no lost events), idempotent (no double-counts), and near-real-time (customers see current usage). Common implementations use a message queue (Kafka, SQS) feeding an aggregation service that reports to Stripe.
Developer tiers are named bundles of quotas, rate limits, and feature flags. A typical structure is Free (heavily rate-limited, basic endpoints), Pro (higher limits, all endpoints, email support), and Enterprise (custom limits, SLA, dedicated support). Each tier maps to a Stripe Price with optional metered components.
Rate limiting enforces tier boundaries at the API gateway level. The standard approach is token bucket or sliding window per API key, returning 429 Too Many Requests with Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.
Stripe metering connects API usage to invoices. The flow is: create a metered Price on a Product, subscribe customers, then report usage via stripe.subscriptionItems.createUsageRecord(). Stripe aggregates usage and generates invoices at the billing cycle end.
Common tasks
Design a tier structure
Define tiers based on target customer segments. Each tier needs: a name, monthly base price, included API calls, rate limit (requests/minute), overage rate, and available endpoints.
tiers:
free:
price: 0
included_calls: 1000/month
rate_limit: 10/min
endpoints: [/v1/basic/*]
support: community
pro:
price: 49/month
included_calls: 50000/month
rate_limit: 100/min
endpoints: [/v1/*]
support: email
overage: $0.002/call
enterprise:
price: custom
included_calls: custom
rate_limit: custom
endpoints: [/v1/*, /v1/admin/*]
support: dedicated
sla: 99.9%Set up Stripe metered billing
Create a Product and a metered Price, then subscribe a customer.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// 1. Create product
const product = await stripe.products.create({
name: 'API Access - Pro Tier',
});
// 2. Create metered price (per-unit usage)
const meteredPrice = await stripe.prices.create({
product: product.id,
currency: 'usd',
recurring: {
interval: 'month',
usage_type: 'metered',
aggregate_usage: 'sum',
},
unit_amount: 0.2, // $0.002 per call (in cents: 0.2)
billing_scheme: 'per_unit',
});
// 3. Create base price for the tier
const basePrice = await stripe.prices.create({
product: product.id,
currency: 'usd',
recurring: { interval: 'month' },
unit_amount: 4900, // $49.00
});
// 4. Subscribe the customer to both prices
const subscription = await stripe.subscriptions.create({
customer: 'cus_xxx',
items: [
{ price: basePrice.id },
{ price: meteredPrice.id },
],
});Report usage to Stripe
Report API call counts to Stripe periodically (hourly or daily). Always use action: 'increment' for safe idempotent reporting.
// Find the metered subscription item
const subscription = await stripe.subscriptions.retrieve('sub_xxx');
const meteredItem = subscription.items.data.find(
(item) => item.price.recurring.usage_type === 'metered'
);
// Report usage - increment by the count since last report
await stripe.subscriptionItems.createUsageRecord(meteredItem.id, {
quantity: 1250, // API calls in this reporting period
timestamp: Math.floor(Date.now() / 1000),
action: 'increment',
});Always use
action: 'increment'rather thanaction: 'set'. With'set', a retry after a network failure would silently overwrite the correct total.
Implement rate limiting middleware
Express middleware that enforces per-tier rate limits using a sliding window with Redis.
const Redis = require('ioredis');
const redis = new Redis(process.env.REDIS_URL);
const TIER_LIMITS = {
free: { rpm: 10, window: 60 },
pro: { rpm: 100, window: 60 },
enterprise: { rpm: 1000, window: 60 },
};
async function rateLimiter(req, res, next) {
const apiKey = req.headers['x-api-key'];
const tier = await getTierForApiKey(apiKey); // your lookup
const limit = TIER_LIMITS[tier];
const key = `ratelimit:${apiKey}`;
const now = Date.now();
// Sliding window using sorted set
await redis.zremrangebyscore(key, 0, now - limit.window * 1000);
const count = await redis.zcard(key);
if (count >= limit.rpm) {
res.set('Retry-After', String(limit.window));
res.set('X-RateLimit-Limit', String(limit.rpm));
res.set('X-RateLimit-Remaining', '0');
return res.status(429).json({ error: 'Rate limit exceeded' });
}
await redis.zadd(key, now, `${now}-${Math.random()}`);
await redis.expire(key, limit.window);
res.set('X-RateLimit-Limit', String(limit.rpm));
res.set('X-RateLimit-Remaining', String(limit.rpm - count - 1));
next();
}Track usage for billing
Middleware that counts API calls per customer and flushes to Stripe on a schedule.
const usageBuffer = new Map(); // apiKey -> count
function usageTracker(req, res, next) {
const apiKey = req.headers['x-api-key'];
usageBuffer.set(apiKey, (usageBuffer.get(apiKey) || 0) + 1);
next();
}
// Flush every hour
setInterval(async () => {
for (const [apiKey, count] of usageBuffer.entries()) {
const subItemId = await getMeteredSubItemForKey(apiKey);
if (subItemId && count > 0) {
await stripe.subscriptionItems.createUsageRecord(subItemId, {
quantity: count,
timestamp: Math.floor(Date.now() / 1000),
action: 'increment',
});
}
}
usageBuffer.clear();
}, 60 * 60 * 1000);In production, use a durable queue (SQS, Kafka) instead of an in-memory buffer to avoid losing usage data on process restarts.
Handle overage notifications
Notify customers when they approach or exceed their included quota.
async function checkUsageThresholds(customerId, currentUsage, includedCalls) {
const percentage = (currentUsage / includedCalls) * 100;
const thresholds = [80, 100, 120];
for (const threshold of thresholds) {
if (percentage >= threshold) {
const alreadyNotified = await hasNotifiedThreshold(customerId, threshold);
if (!alreadyNotified) {
await sendUsageAlert(customerId, {
currentUsage,
includedCalls,
percentage,
threshold,
message: threshold >= 100
? `You have exceeded your included ${includedCalls} API calls. Overage billing is active.`
: `You have used ${percentage.toFixed(0)}% of your included API calls.`,
});
await markThresholdNotified(customerId, threshold);
}
}
}
}Anti-patterns / common mistakes
| Mistake | Why it's wrong | What to do instead |
|---|---|---|
| Billing on gateway logs alone | Gateway logs can be incomplete or delayed; disputes become unresolvable | Use a dedicated metering service with durable event ingestion |
| Hard-cutting access at quota | Breaks customer production systems, causes churn | Throttle or enable overage billing with clear notifications |
Using action: 'set' in Stripe usage records |
Retries overwrite the correct total, causing under-billing | Always use action: 'increment' for idempotent reporting |
| Same rate limit for all endpoints | Expensive endpoints (ML inference) subsidized by cheap ones (health check) | Weight rate limits by endpoint cost or use separate quotas |
| No rate limit headers in 429 responses | Clients cannot implement proper backoff | Always return Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining |
| Reporting usage in real-time per request | Creates enormous Stripe API load, risks rate limiting from Stripe itself | Batch usage reports hourly or daily |
Gotchas
In-memory usage buffers are lost on process restart - Buffering usage counts in a
Mapor similar in-process store means any crash or deploy loses that billing period's data. Use a durable queue (SQS, Redis with AOF, Kafka) as the write-ahead log before aggregating and reporting to Stripe.action: 'set'on retried Stripe usage reports silently under-bills - If a usage record POST fails and you retry withaction: 'set', the retry sets the total to the retry value, discarding any usage already recorded in the current billing period. Always useaction: 'increment'so retries are safe.Redis sorted set race condition in sliding window rate limiter - The
ZREMRANGEBYSCORE+ZCARD+ZADDsequence is not atomic. Under high concurrency, two requests can both pass the check before either adds their entry, allowing a brief burst over the limit. Use a Lua script orMULTI/EXECtransaction to make the check-and-increment atomic.Free tier users who never convert still cost infrastructure - A free tier with no rate limits or usage caps can be abused as free compute. Define hard rate limits even on the free tier, and implement API key rotation or abuse detection before going public.
Stripe metered price
aggregate_usagecannot be changed after creation - If you create a metered price withaggregate_usage: 'sum'and later want'max', you must create a new price and migrate subscribers. Plan the aggregation model before creating prices in production.
References
For detailed content on specific sub-domains, read the relevant file
from the references/ folder:
references/stripe-metering.md- Deep dive into Stripe metered billing setup, tiered pricing, and invoice lifecyclereferences/rate-limiting-patterns.md- Advanced rate limiting algorithms, Redis implementations, and distributed rate limiting
Only load a references file if the current task requires it - they are long and will consume context.
References
rate-limiting-patterns.md
Rate Limiting Patterns
Algorithm comparison
| Algorithm | Accuracy | Memory | Burst handling | Complexity |
|---|---|---|---|---|
| Fixed window | Low | Low | Poor (boundary burst) | Simple |
| Sliding window log | High | High | Good | Medium |
| Sliding window counter | Good | Low | Good | Medium |
| Token bucket | Good | Low | Configurable | Medium |
| Leaky bucket | Good | Low | Smooths bursts | Medium |
Fixed window
Counts requests in fixed time intervals (e.g., per minute starting at :00).
async function fixedWindow(redis, key, limit, windowSec) {
const windowKey = `${key}:${Math.floor(Date.now() / 1000 / windowSec)}`;
const count = await redis.incr(windowKey);
if (count === 1) await redis.expire(windowKey, windowSec);
return { allowed: count <= limit, remaining: Math.max(0, limit - count) };
}Weakness: A burst of requests at the boundary of two windows can allow 2x the intended limit. E.g., 100 requests at 11:59:59 + 100 at 12:00:00 passes a 100/minute limit.
Sliding window counter (recommended for most APIs)
Hybrid of fixed window and sliding log. Uses two adjacent fixed windows weighted by the current position within the window.
async function slidingWindowCounter(redis, key, limit, windowSec) {
const now = Date.now() / 1000;
const currentWindow = Math.floor(now / windowSec);
const previousWindow = currentWindow - 1;
const elapsed = (now / windowSec) - currentWindow; // 0.0 to 1.0
const [prevCount, currCount] = await Promise.all([
redis.get(`${key}:${previousWindow}`).then(Number),
redis.get(`${key}:${currentWindow}`).then(Number),
]);
const estimatedCount = (prevCount || 0) * (1 - elapsed) + (currCount || 0);
if (estimatedCount >= limit) {
return { allowed: false, remaining: 0 };
}
await redis.incr(`${key}:${currentWindow}`);
await redis.expire(`${key}:${currentWindow}`, windowSec * 2);
return {
allowed: true,
remaining: Math.max(0, Math.floor(limit - estimatedCount - 1)),
};
}Token bucket
Tokens are added at a steady rate. Each request consumes one token. Allows controlled bursting up to the bucket capacity.
async function tokenBucket(redis, key, rate, capacity) {
const now = Date.now() / 1000;
const lua = `
local tokens_key = KEYS[1]
local timestamp_key = KEYS[2]
local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local last_time = tonumber(redis.call('get', timestamp_key) or now)
local current_tokens = tonumber(redis.call('get', tokens_key) or capacity)
local elapsed = math.max(0, now - last_time)
local new_tokens = math.min(capacity, current_tokens + elapsed * rate)
if new_tokens < 1 then
return {0, math.ceil((1 - new_tokens) / rate)}
end
new_tokens = new_tokens - 1
redis.call('set', tokens_key, new_tokens)
redis.call('set', timestamp_key, now)
redis.call('expire', tokens_key, math.ceil(capacity / rate) * 2)
redis.call('expire', timestamp_key, math.ceil(capacity / rate) * 2)
return {1, 0}
`;
const [allowed, retryAfter] = await redis.eval(
lua, 2,
`${key}:tokens`, `${key}:ts`,
rate, capacity, now
);
return { allowed: allowed === 1, retryAfter };
}Token bucket is ideal when you want to allow short bursts (e.g., 10 requests instantly) while maintaining a steady-state limit (e.g., 100/min).
Response headers
Always include these headers on every response, not just 429s:
X-RateLimit-Limit: 100 # max requests per window
X-RateLimit-Remaining: 42 # requests left in current window
X-RateLimit-Reset: 1710432000 # Unix timestamp when window resets
Retry-After: 30 # seconds to wait (only on 429)function setRateLimitHeaders(res, limit, remaining, resetTimestamp) {
res.set('X-RateLimit-Limit', String(limit));
res.set('X-RateLimit-Remaining', String(Math.max(0, remaining)));
res.set('X-RateLimit-Reset', String(resetTimestamp));
}Distributed rate limiting
When running multiple API server instances, rate limiting must be centralized.
Redis-based (recommended)
All instances share a single Redis cluster. The algorithms above work as-is because Redis operations are atomic.
Considerations for high scale:
- Redis latency adds to every request. Keep Redis in the same region as your API servers (< 1ms RTT).
- Redis failures - decide on a fail-open or fail-closed policy. Fail-open (allow all requests) is safer for production APIs; fail-closed (deny all) is safer for abuse prevention.
- Lua scripts for multi-step operations (like token bucket) ensure atomicity without requiring distributed locks.
Per-endpoint weighting
Not all endpoints cost the same. An ML inference endpoint might cost 100x more than a data lookup.
const ENDPOINT_WEIGHTS = {
'GET /v1/users': 1,
'POST /v1/analyze': 10,
'POST /v1/generate': 50,
};
async function weightedRateLimit(redis, apiKey, endpoint, tierLimit) {
const weight = ENDPOINT_WEIGHTS[endpoint] || 1;
const key = `ratelimit:${apiKey}`;
// Consume `weight` tokens instead of 1
// Apply to any of the above algorithms
}Rate limiting by tier
Map tiers to limits in a configuration object for easy updates:
const TIER_CONFIG = {
free: {
requests_per_minute: 10,
requests_per_day: 1000,
burst_capacity: 15,
concurrent_requests: 2,
},
pro: {
requests_per_minute: 100,
requests_per_day: 50000,
burst_capacity: 150,
concurrent_requests: 10,
},
enterprise: {
requests_per_minute: 1000,
requests_per_day: null, // unlimited
burst_capacity: 1500,
concurrent_requests: 50,
},
};Apply multiple limits simultaneously - per-minute AND per-day. A request must pass all limit checks to proceed.
Graceful degradation
When a customer exceeds limits, offer a degradation path instead of a hard block:
- Soft limit (80%) - return
X-RateLimit-Warning: approachingheader - At limit (100%) - return
429withRetry-After - Sustained over-limit - queue requests with lower priority instead of rejecting
- Abuse detected - temporary ban with explanation
function getRateLimitResponse(usage, limit) {
const ratio = usage / limit;
if (ratio < 0.8) return { status: 'ok' };
if (ratio < 1.0) return { status: 'warning', header: 'approaching' };
if (ratio < 1.5) return { status: 'throttled', retryAfter: 60 };
return { status: 'blocked', retryAfter: 3600 };
} stripe-metering.md
Stripe Metering Deep Dive
Metered billing flow
The complete lifecycle for Stripe metered billing:
- Create a Product - represents your API service
- Create a metered Price on that Product - defines the per-unit cost
- Subscribe a customer to the metered Price
- Report usage via
subscriptionItems.createUsageRecord() - Stripe aggregates usage over the billing period
- Invoice generated at period end with total usage charges
Price configuration options
Per-unit pricing
Charge a flat rate per API call.
const price = await stripe.prices.create({
product: 'prod_xxx',
currency: 'usd',
recurring: {
interval: 'month',
usage_type: 'metered',
aggregate_usage: 'sum', // sum | last_during_period | last_ever | max
},
unit_amount: 1, // $0.01 per unit
billing_scheme: 'per_unit',
});Tiered pricing (graduated)
Different rates at different volume levels. Use graduated tiers so that the first N calls are at one rate, the next M at another.
const tieredPrice = await stripe.prices.create({
product: 'prod_xxx',
currency: 'usd',
recurring: {
interval: 'month',
usage_type: 'metered',
aggregate_usage: 'sum',
},
billing_scheme: 'tiered',
tiers_mode: 'graduated', // graduated | volume
tiers: [
{ up_to: 10000, unit_amount: 0 }, // first 10k free (included)
{ up_to: 100000, unit_amount: 1 }, // next 90k at $0.01
{ up_to: 'inf', unit_amount: 0.5 }, // everything above at $0.005
],
});Volume pricing
All units charged at the tier the total falls into (not graduated).
const volumePrice = await stripe.prices.create({
product: 'prod_xxx',
currency: 'usd',
recurring: {
interval: 'month',
usage_type: 'metered',
aggregate_usage: 'sum',
},
billing_scheme: 'tiered',
tiers_mode: 'volume',
tiers: [
{ up_to: 10000, unit_amount: 2 },
{ up_to: 100000, unit_amount: 1 },
{ up_to: 'inf', unit_amount: 0.5 },
],
});Aggregate usage modes
| Mode | Behavior | Use case |
|---|---|---|
sum |
Adds all reported quantities | API call counting |
last_during_period |
Uses only the last reported value | Seat-based billing |
last_ever |
Uses the most recent value ever | High-water-mark licensing |
max |
Uses the highest reported value in the period | Peak concurrent connections |
For API monetization, sum is almost always correct.
Usage record reporting
Increment mode (recommended)
await stripe.subscriptionItems.createUsageRecord('si_xxx', {
quantity: 500,
timestamp: Math.floor(Date.now() / 1000),
action: 'increment',
});Each call adds to the running total. Safe to retry - worst case you slightly over-count rather than losing data.
Set mode (use with caution)
await stripe.subscriptionItems.createUsageRecord('si_xxx', {
quantity: 15000,
timestamp: Math.floor(Date.now() / 1000),
action: 'set',
});Replaces the current total. Dangerous if retried after a network timeout - you may overwrite a higher correct value with a stale one.
Reporting frequency
| Frequency | Pros | Cons |
|---|---|---|
| Per-request | Maximum accuracy | Enormous API load, may hit Stripe rate limits |
| Hourly | Good balance of accuracy and efficiency | Up to 1 hour of data at risk if process crashes |
| Daily | Minimal API calls | Significant data loss risk, poor real-time visibility |
Recommendation: Report hourly with a durable queue backing the buffer.
Invoice lifecycle
- Draft invoice created ~1 hour before billing period ends
- Usage finalized - Stripe stops accepting usage records for the period
- Invoice finalized - becomes payable
- Payment attempted - charges the customer's payment method
- Invoice paid or payment failed - webhook events fired
Important: You cannot report usage for a past billing period after the invoice has been finalized. Always report usage promptly.
Webhooks for metered billing
Key events to listen for:
| Event | When | Action |
|---|---|---|
invoice.created |
Draft invoice generated | Verify usage totals look correct |
invoice.finalized |
Invoice ready for payment | Last chance to add manual adjustments |
invoice.payment_succeeded |
Customer charged | Update internal billing status |
invoice.payment_failed |
Charge failed | Notify customer, consider throttling |
customer.subscription.updated |
Plan changed | Update tier limits in your system |
customer.subscription.deleted |
Subscription cancelled | Revoke API access or downgrade to free |
Handling subscription changes mid-cycle
When a customer upgrades from Free to Pro mid-cycle:
// Prorate the base price and add metered component
const subscription = await stripe.subscriptions.update('sub_xxx', {
items: [
{ id: 'si_base', price: 'price_pro_base' },
{ id: 'si_metered', price: 'price_pro_metered' },
],
proration_behavior: 'create_prorations',
});Usage records reported before the upgrade are billed at the old rate. Records after the upgrade use the new rate. Stripe handles the cutover automatically within the same billing period.
Testing metered billing
Use Stripe test mode with test clocks to simulate billing cycles:
// Create a test clock
const testClock = await stripe.testHelpers.testClocks.create({
frozen_time: Math.floor(Date.now() / 1000),
});
// Create customer attached to test clock
const customer = await stripe.customers.create({
test_clock: testClock.id,
email: 'test@example.com',
});
// Subscribe, report usage, then advance the clock
// ... create subscription, report usage records ...
// Advance clock to trigger invoice generation
await stripe.testHelpers.testClocks.advance(testClock.id, {
frozen_time: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60,
}); Frequently Asked Questions
What is api-monetization?
Use this skill when designing or implementing API monetization strategies - usage-based pricing, rate limiting, developer tier management, Stripe metering integration, or API billing systems. Triggers on tasks involving API pricing models, metered billing, per-request charging, quota enforcement, developer portal tiers, overage handling, and Stripe usage records.
How do I install api-monetization?
Run npx skills add AbsolutelySkilled/AbsolutelySkilled --skill api-monetization in your terminal. The skill will be immediately available in your AI coding agent.
What AI agents support api-monetization?
api-monetization works with claude-code, gemini-cli, openai-codex, mcp. Install it once and use it across any supported AI coding agent.