The shared flow lives in the Aforo SDK distribution repo at aforo-gateway-plugins/apigee/. There is no public registry release, so deploy from source — the apigee/sharedflowbundle/ folder is the source of truth, and apigeecli zips and imports it for you:
terminal
# Clone the SDK distribution repo and enter the Apigee plugin folder
git clone https://github.com/aforoai/SDKs.git
cd SDKs/aforo-gateway-plugins/apigee
# Create the shared flow from the bundle folder
apigeecli sharedflows create bundle \
--name aforo-metering \
--folder sharedflowbundle \
--org "$APIGEE_ORG" \
--token "$(gcloud auth print-access-token)"
# Deploy the imported revision to your environment
apigeecli sharedflows deploy \
--name aforo-metering \
--rev 1 \
--env "$APIGEE_ENV" \
--org "$APIGEE_ORG" \
--token "$(gcloud auth print-access-token)"
INFO
Set $APIGEE_ORG to your Apigee organization name and $APIGEE_ENV to the target environment (e.g., prod, test). The bundle expects an organization-scoped KVM named aforo-metering-config — create it before the first call (next step).
The Shared Flow reads its configuration from an encrypted KVM. Create the KVM and set the Aforo credentials:
terminal
# Create the KVM (encrypted, organization-scoped — the bundle reads it at org level)
curl -X POST "https://apigee.googleapis.com/v1/organizations/{ORG}/keyvaluemaps" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"name": "aforo-metering-config",
"encrypted": true
}'
# Set the API key
curl -X POST "https://apigee.googleapis.com/v1/organizations/{ORG}/keyvaluemaps/aforo-metering-config/entries" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{ "name": "api_key", "value": "sk_live_your_key_here" }'
# Set the ingest endpoint
curl -X POST "https://apigee.googleapis.com/v1/organizations/{ORG}/keyvaluemaps/aforo-metering-config/entries" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{ "name": "aforo_endpoint", "value": "https://ingest.aforo.ai/v1/ingest/batch" }'
# Set the workspace (tenant) id
curl -X POST "https://apigee.googleapis.com/v1/organizations/{ORG}/keyvaluemaps/aforo-metering-config/entries" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{ "name": "tenant_id", "value": "your-workspace-id" }'
WARNING
Always use encrypted KVMs for API keys. Apigee encrypts the values at rest and in transit. Never store credentials in proxy-level variables or environment properties.
Attach the Shared Flow to a Pre-Proxy Flow Hook for global enforcement. This ensures every API proxy in the environment runs the Aforo entitlement and metering logic automatically — no individual proxy edits.
terminal
# Attach to Pre-Proxy Flow Hook (entitlement check BEFORE backend)
curl -X PUT "https://apigee.googleapis.com/v1/organizations/{ORG}/environments/{ENV}/flowhooks/PreProxyFlowHook" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"sharedFlow": "aforo-metering",
"continueOnError": false
}'
# Optional: Also attach to Post-Proxy for async metering
curl -X PUT "https://apigee.googleapis.com/v1/organizations/{ORG}/environments/{ENV}/flowhooks/PostProxyFlowHook" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"sharedFlow": "aforo-metering",
"continueOnError": true
}'
PreProxyFlowHook
Entitlement check + Margin Guard enforcement
Before backend
PostProxyFlowHook
Async usage metering + event enrichment
After response
PRO TIP
Set continueOnError: false on PreProxy to hard-block requests that fail entitlement checks. Set continueOnError: true on PostProxy so metering failures never break the API response.
L3 enforcement uses Apigee's RaiseFault policy. The request is rejected at the gateway — your backend never sees it. This protects compute costs from unprofitable traffic.
Verify the deployment by checking the Flow Hook attachment and sending a test request:
terminal
# Verify Flow Hook is attached
curl -s "https://apigee.googleapis.com/v1/organizations/{ORG}/environments/{ENV}/flowhooks/PreProxyFlowHook" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" | jq .
# Expected: { "sharedFlow": "aforo-metering", "continueOnError": false }
# PaperPlaneTilt a test request through any proxy in the environment
curl -v https://{ORG}-{ENV}.apigee.net/your-api/endpoint \
-H "X-Tenant-Id: test_tenant_123" \
-H "Authorization: Bearer sk_live_customer_key"
# Check for Aforo headers in response:
# X-Aforo-Remaining: 8420
# X-Aforo-Plan: enterprise
# Verify event in Aforo
curl -s "https://api.aforo.ai/v1/events?tenant_id=test_tenant_123&limit=1" \
-H "Authorization: Bearer sk_live_your_admin_key" | jq .
PRO TIP
If events are not appearing, check the Apigee Debug (Trace) tool. Look for the aforo-metering Shared Flow execution in the PreProxy phase. Common issues: KVM not found (wrong environment), expired Aforo API key, or network policy blocking outbound HTTPS to ingest.aforo.ai.