Apigee Integration (Shared Flow)
Deploy the Aforo Shared Flow to your Apigee Organization. Decouple monetization logic from individual API proxies.
Task Overview#
Why Shared Flow?#
Aforo uses an Apigee Shared Flow to decouple monetization logic from individual API proxies. This means:
Prerequisites#
One-Click Install from Aforo#
If your Apigee organization is already connected under Governance → Integrations, you don't need Steps 1–3. Open the connection, turn on metering and deploy. Aforo runs the same Management API calls you would:
Deploy again after changing a setting: the KVM is refreshed every time, and the flow picks the change up within five minutes (it caches KVM reads for 300 seconds). Removing metering detaches the hook, undeploys the flow and deletes the entries Aforo wrote. The shared flow is deleted once no environment has it deployed.
PostProxyFlowHook slot. If another shared flow already holds it, Aforo does not replace it: the deploy stops and names that flow. Call aforo-metering from it with a FlowCallout policy, set meteringAttachMode to none on the connection, and deploy again.One-click install uses the Apigee X and hybrid Management API. It does not cover Apigee Edge; follow the manual steps below there. The rest of this page is the same install by hand.
Step 1: Import the Shared Flow Bundle#
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:
$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).Step 2: Configure the Key Value Map (KVM)#
The Shared Flow reads its configuration from an encrypted KVM. Create the KVM and set the Aforo credentials:
Step 3: Attach via Flow Hook#
Attach the Shared Flow to the environment's Post-Proxy Flow Hook. Every API proxy in the environment then sends a usage event after its response is built — no individual proxy edits. The flow reads the response status, so it belongs on the response path; it can't run in PostClientFlow, which accepts only FlowCallout, MessageLogging and ServiceCallout policies.
continueOnError: true so a metering failure never changes the API response. The event is sent before the client receives the response: a healthy ingest endpoint adds tens of milliseconds. When Aforo ingest is unreachable the API call still succeeds, and the wait is bounded: each attempt gives up after 1 second to connect and 2 seconds for the response, and there is one retry, only after a connection failure or a 5xx that failed within 1.2 seconds. That is about 2 seconds added per call while ingest is unreachable, about 3 seconds if it accepts the connection and never answers, and about 4 seconds at the limit. The usage event for that call is not delivered: the flow sets aforo.meteringDeliveryFailed and prints USAGE EVENT DROPPED to the debug session. Set the KVM entry max_retries to 0 to send once (about 1 second). The two timeouts are fixed in the shared flow's send policies; Apigee does not read ServiceCallout timeouts from a variable.How Calls Get an Outcome#
Read this if any rate plan behind this gateway uses Outcome-Based pricing — it bills each call at a weight for its executionStatus. Every other pricing model ignores the field. The plugin sets it from the upstream response status:
| Upstream status | executionStatus |
|---|---|
| 2xx, 3xx | SUCCESS |
| 408, 504 | TIMEOUT |
| 499 (client closed the request, where the gateway reports it) | CANCELLED |
| 400, 422 | VALIDATION_FAILED |
| 401, 403, 429 | BLOCKED |
| Every other 4xx and 5xx (404 included) | ERROR |
| Missing, 0, 1xx | Not sent — the call bills at full weight |
BLOCKED and CANCELLED at 0, but plans saved before those two statuses were added to the wizard (September 30, 2026) have no weight for them, so the gateway's BLOCKED and CANCELLED calls on those plans bill in full until you give them one — open the plan in the wizard and enter a weight (the fields show blank), or set it through the rate-plan API (outcomeWeights). See Outcome-Based pricing.Override the status for specific codes
When the default table is wrong for your API — say a 404 is a normal answer, not a failure — map exact codes with the status_outcomes entry in the aforo-metering-config KVM. Format: comma-separated code=STATUS pairs:
Keys are exact HTTP codes from 200 to 599. Values must be one of the 11 statuses: SUCCESS, PARTIAL, TIMEOUT, ERROR, VALIDATION_FAILED, FAILED, FAILURE, CANCELLED, PENDING, BLOCKED, HITL_REQUIRED. Invalid entries are ignored without a warning. If a code is listed twice, the last valid entry wins. An override can't give a status to a missing, 0 or 1xx code.
Requests that aren't metered
By default, responses with status 401, 403 or 429 and requests to /health, /ready or /metrics produce no event at all — they cost nothing whatever the rate plan says. All five gateway plugins share this default. A path is skipped when it equals an entry or starts with it, so /health also covers /health/live.
| Setting | Default | To meter everything |
|---|---|---|
KVM entry exclude_status_codes in aforo-metering-config | 401,403,429 | The word none |
KVM entry exclude_paths | /health,/ready,/metrics | The word none |
Leave an entry out to get its default. A KVM entry can't be stored empty, which is why metering everything takes the word none. KVM reads are cached for five minutes. Entries that aren't whole numbers from 100 to 599 are ignored. A list you set replaces the default rather than adding to it: a status list of 404,500 skips only those two and starts metering 401, 403 and 429. A status you choose to meter bills as BLOCKED unless you override it above.
Margin Guard Enforcement#
The PreProxy Flow Hook executes all three Margin Guard levels before traffic reaches your backend target:
RaiseFault policy. The request is rejected at the gateway — your backend never sees it. This protects compute costs from unprofitable traffic.Verification#
Verify the deployment by checking the Flow Hook attachment and sending a test request:
aforo-metering Shared Flow execution after the proxy response (look for the aforo.eventPayload variable). Common issues: KVM not found (wrong environment), expired Aforo API key, or network policy blocking outbound HTTPS to api.aforo.ai.