Zuplo
Metrics, Billing & Quotas

Amberflo Metering / Billing Policy

Seamlessly integrate usage-based metering and billing into your API with Amberflo integration. This policy automatically tracks API usage and sends metering data to Amberflo for accurate billing and consumption analytics.

With this policy, you'll benefit from:

  • Usage-Based Billing: Easily implement consumption-based pricing models for your API
  • Granular Metering: Track usage at the customer and endpoint level with customizable dimensions
  • Flexible Configuration: Define meter names, values, and customer identification at the policy or code level
  • Batch Processing: Efficiently send usage data with automatic batching for optimal performance
  • Real-Time Analytics: Monitor API consumption patterns through Amberflo's dashboard

Add the policy to each route you want to meter, with the ability to customize meter names, values, and dimensions per endpoint or dynamically in your code.

Configuration

The configuration shows how to configure the policy in the 'policies.json' document.

Code(json)
{ "name": "my-amberflo-metering-inbound-policy", "policyType": "amberflo-metering-inbound", "handler": { "export": "AmberfloMeteringInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "apiKey": "$env(AMBERFLO_API_KEY)", "customerIdPropertyPath": ".sub", "meterApiName": "$env(AMBERFLO_METER_API_NAME)", "meterValue": "$env(AMBERFLO_METER_VALUE)", "statusCodes": "200-299", "url": " https://app.amberflo.io/ingest" } } }

Policy Configuration

  • name <string> - The name of your policy instance. This is used as a reference in your routes.
  • policyType <string> - The identifier of the policy. This is used by the Zuplo UI. Value should be amberflo-metering-inbound.
  • handler.export <string> - The name of the exported type. Value should be AmberfloMeteringInboundPolicy.
  • handler.module <string> - The module containing the policy. Value should be $import(@zuplo/runtime).
  • handler.options <object> - The options for this policy. See Policy Options below.

Policy Options

The options for this policy are specified below. All properties are optional unless specifically marked as required.

  • apiKey (required) <string> - The API key to use when sending metering calls to Amberflo.
  • meterApiName <string> - The name of the meter to use when sending metering calls to Amberflo (overridable in code).
  • meterValue <number> - The value to use when sending metering calls to Amberflo (overridable in code).
  • customerIdPropertyPath <string> - The path to the property on request.user contains the customer ID. For example .data.accountNumber would read the request.user.data.accountNumber property. Defaults to ".sub".
  • customerId <string> - The default customerId for all metering calls - overridable in code and by customerIdPropertyPath.
  • dimensions <object> - A dictionary of dimensions to be sent to Amberflo (extensible in code).
  • statusCodes <undefined> - A list of successful status codes and ranges "200-299, 304" that should trigger a metering call to Amberflo. Defaults to "200-299".
  • url <string> - The URL to send metering events. This is useful for testing purposes. Defaults to " https://app.amberflo.io/ingest".

Using the Policy

This policy integrates with Amberflo to enable usage-based metering and billing for your API. It automatically tracks API usage and sends metering data to Amberflo when requests match your configured success criteria.

How It Works

The policy performs the following operations:

  1. Monitors API requests and captures successful responses based on configured status codes
  2. Collects metering data including customer ID, meter name, and value
  3. Batches metering events for efficient processing
  4. Sends the data to Amberflo's ingest endpoint
  5. Provides error handling and logging

Policy Configuration

Configure the policy with your Amberflo API key and metering parameters:

Code(json)
{ "name": "amberflo-metering", "export": "AmberfloMeteringInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "apiKey": "$env(AMBERFLO_API_KEY)", "meterApiName": "api-requests", "meterValue": 1, "customerIdPropertyPath": ".sub", "statusCodes": "200-299", "dimensions": { "environment": "production" } } }

Customer Identification

You can identify customers in three ways:

  1. Dynamic Property Path: Extract customer ID from the request user object (recommended)
  2. Static Default: Set a global customer ID at the policy level (not recommended)
  3. Programmatic Setting: Set customer ID in code for complete flexibility

Using customerIdPropertyPath

The customerIdPropertyPath extracts the customer ID from the request.user object. For example, with a JWT token or API Key metadata containing:

Code(json)
{ "sub": "bobby-tables", "data": { "email": "bob@example.com", "name": "Bobby Tables", "accountNumber": 1233423, "roles": ["admin"] } }

You can access properties using dot notation (note the required leading dot):

  • For the sub property: ".sub"
  • For nested properties: ".data.accountNumber"

Programmatic Configuration

You can dynamically set metering properties in your code using the AmberfloMeteringPolicy helper class:

Code(ts)
import { AmberfloMeteringPolicy, ZuploContext, ZuploRequest, } from "@zuplo/runtime"; export default async function ( request: ZuploRequest, context: ZuploContext, options: MyPolicyOptionsType, policyName: string, ) { AmberfloMeteringPolicy.setRequestProperties(context, { customerId: request.user.sub, meterApiName: request.params.color, meterValue: request.params.quantity || 1, dimensions: { region: request.headers.get("x-region") || "default", }, }); return request; }

Configuration Options

OptionTypeRequiredDescription
apiKeystringYesYour Amberflo API key for authentication
meterApiNamestringYes*The name of the meter to use when sending metering calls
meterValuenumberYes*The value to increment the meter by (typically 1 for counting API calls)
customerIdPropertyPathstringNoPath to extract customer ID from request.user object
customerIdstringNoDefault customer ID if not using customerIdPropertyPath
dimensionsobjectNoAdditional dimensions to include with metering data
statusCodesstring/arrayYesStatus codes that trigger metering (e.g., "200-299" or [200, 201])
urlstringNoCustom URL for the Amberflo ingest endpoint (defaults to "https://app.amberflo.io/ingest")

*Can be set programmatically if not provided in policy configuration

Usage Examples

Basic API Request Metering

Apply the policy to routes you want to meter:

Code(json)
{ "paths": { "/api/products": { "get": { "x-zuplo-route": { "policies": { "inbound": ["jwt-auth", "amberflo-product-api-metering"] }, "handler": { "export": "forwardToOrigin", "module": "$import(@zuplo/runtime)" } } } } } }

Different Meters for Different Endpoints

Create separate policy instances for different meters:

Code(json)
[ { "name": "amberflo-read-metering", "export": "AmberfloMeteringInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "apiKey": "$env(AMBERFLO_API_KEY)", "meterApiName": "api-reads", "meterValue": 1, "customerIdPropertyPath": ".sub", "statusCodes": "200-299" } }, { "name": "amberflo-write-metering", "export": "AmberfloMeteringInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "apiKey": "$env(AMBERFLO_API_KEY)", "meterApiName": "api-writes", "meterValue": 1, "customerIdPropertyPath": ".sub", "statusCodes": "200-299" } } ]

Best Practices

  • Store your Amberflo API key as an environment variable using $env(AMBERFLO_API_KEY)
  • Use customerIdPropertyPath instead of hardcoding customer IDs
  • Consider creating different meters for different types of API operations
  • Add relevant dimensions to your metering data for better analytics
  • Monitor your Amberflo dashboard to track API usage patterns

Read more about how policies work

Last modified on