Schedule icon
Request icon
Return icon
Switch icon
Log icon
SlackIncomingWebhook icon

OpenRouter Credit Runway Sentinel

Read the OpenRouter credit balance every 3 hours, call no model, and alert Slack before agents and flows fail because prepaid credits ran out.

Categories
AI

Many agents, RAG pipelines and AI flows reach dozens of models through OpenRouter on prepaid credits. When the balance hits zero, every call returns a payment-required error at once: the support bot stops answering, the nightly summarization job fails, and the first sign is a wave of errors. OpenRouter shows the balance on its credits page, but nothing pages the team as it runs down. This blueprint turns a scheduled, read-only call to the OpenRouter credits endpoint into a spend gate: io.kestra.plugin.core.http.Request reads credits purchased and used, one jq query works out the remaining balance, and the result routes to a quiet log or a Slack alert.

How it works

  1. get_credits (io.kestra.plugin.core.http.Request) calls GET /api/v1/credits with a bearer management key. It is a read: no model is called and nothing is purchased. Retries cover short network blips, and allowFailed plus allowFailure keep an API error from aborting the flow so it can be reported instead.
  2. summarize_credits (io.kestra.plugin.core.debug.Return) first guards for a missing or non-200 response (UNREACHABLE; OpenRouter answers 403 if the key is not a management key). Otherwise one jq query computes data.total_credits - data.total_usage and the share used, and classifies: a remaining balance at or below critical_remaining_usd is CRITICAL, at or below warning_remaining_usd is WARNING, otherwise HEALTHY.
  3. route_by_credits (io.kestra.plugin.core.flow.Switch) branches on that classification: HEALTHY logs quietly, WARNING posts a Slack note, CRITICAL and UNREACHABLE page Slack. A defaults fallback logs anything unexpected.
  4. log_audit_result (io.kestra.plugin.core.log.Log) writes one audit line per run with the HTTP status and the full summary.
  5. The flow-level errors block pages Slack if the flow itself fails, and the credit_check trigger runs every 3 hours, shipped disabled: true.

What you get

  • A read-only credit check with no custom scripting and no extra plugin to install.
  • status and remaining_usd outputs other flows can gate on, for example to pause expensive batch jobs or switch an agent to a cheaper model when credits are low.
  • Slack messages with the remaining balance and the share used.
  • An audit line on every run, separate from Slack, which doubles as a spend history.

Who it's for

  • Teams running agents, chatbots and AI flows through OpenRouter on prepaid credits.
  • Solo builders and small startups who cannot afford their product going silent because a balance hit zero.
  • Kestra users whose own AI flows call OpenRouter and want the guard next to them.

Why orchestrate this with Kestra

The flows that spend the credits often already run in Kestra. Kestra turns a plain, read-only API call into a scheduled, typed classification with retries, a failure path and an execution history, and the remaining_usd output lets those same flows throttle themselves before the balance runs out.

Prerequisites

  • An OpenRouter account with purchased credits.
  • A management key (created under Settings > Management Keys); ordinary inference keys get HTTP 403 on the credits endpoint.
  • A Slack incoming webhook for the WARNING, CRITICAL, UNREACHABLE and flow-failure alerts.

Secrets

  • OPENROUTER_MANAGEMENT_KEY: an OpenRouter management key.
  • SLACK_WEBHOOK: Slack incoming webhook used for every alert branch and the flow-failure alert.

In Kestra OSS, secrets are supplied as environment variables prefixed SECRET_ and base64-encoded, for example SECRET_OPENROUTER_MANAGEMENT_KEY=$(echo -n 'sk-or-v1-xxxxxxxx' | base64), and read back with {{ secret('OPENROUTER_MANAGEMENT_KEY') }}. Use the Enterprise secrets backend for encryption at rest and access control.

Quick start

  1. Create a management key in OpenRouter and add OPENROUTER_MANAGEMENT_KEY and SLACK_WEBHOOK as secrets.
  2. Run the flow manually and compare remaining_usd with the balance on the OpenRouter credits page.
  3. Raise warning_remaining_usd above your current balance to see the WARNING path, then set it back.
  4. Enable credit_check.

How to extend

  • Store each run's total_usage in a KV store to compute the daily burn and alert when the balance will run out within N days, not only when it is low.
  • Gate expensive batch flows on status == HEALTHY with a Flow trigger.
  • List per-key usage with OpenRouter's key-management endpoints to find which app is spending the most.
  • Alert only on status changes, using a KV store.

Inputs

  • warning_remaining_usd: type FLOAT, default 20.0.
  • critical_remaining_usd: type FLOAT, default 5.0.

Outputs

  • status: one of HEALTHY, WARNING, CRITICAL, UNREACHABLE.
  • remaining_usd: remaining credit balance in USD.

Links

Pitfalls

  • The credits endpoint needs a management key; an inference key returns 403 and the run is reported as UNREACHABLE with that hint.
  • Balances are account-wide; per-key spending limits are separate and are not checked here.
  • Usage can lag a little behind very recent requests, so treat the balance as approximate during heavy bursts.
  • This flow only reads; it never calls a model or buys credits.
See How

New to Kestra?

Use blueprints to kickstart your first workflows.