New to Kestra?
Use blueprints to kickstart your first workflows.
Read the ElevenLabs subscription every 6 hours, generate nothing, and alert Slack before text-to-speech runs out of characters or the plan lapses.
Voice agents, audiobook pipelines, IVR prompts and read-aloud features built on ElevenLabs all draw from one monthly character quota. When it runs out, or a payment fails and the subscription stops being active, every text-to-speech request starts failing at once, often in the middle of a batch job or a live call. ElevenLabs shows usage on its subscription page, but nothing pages the team as the quota runs down. This blueprint turns a scheduled, read-only call to the ElevenLabs API into a quota gate: io.kestra.plugin.core.http.Request reads the subscription, one jq query works out the share used, the characters left and the days until reset, and the result routes to a quiet log or a Slack alert.
get_subscription (io.kestra.plugin.core.http.Request) calls GET /v1/user/subscription with the xi-api-key header. It is a read: no audio is generated and no plan is changed. Retries cover short network blips, and allowFailed plus allowFailure keep an API error from aborting the flow so it can be reported instead.summarize_quota (io.kestra.plugin.core.debug.Return) first guards for a missing or non-200 response (UNREACHABLE). Otherwise one jq query computes character_count / character_limit, the characters left, and the days until next_character_count_reset_unix, and reads tier and status. A subscription status other than active, trialing or free is CRITICAL; usage at or above critical_used_pct is CRITICAL; at or above warning_used_pct is WARNING; otherwise HEALTHY.route_by_quota (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.log_audit_result (io.kestra.plugin.core.log.Log) writes one audit line per run with the HTTP status and the full summary.errors block pages Slack if the flow itself fails, and the quota_check trigger runs every 6 hours, shipped disabled: true.status output (HEALTHY / WARNING / CRITICAL / UNREACHABLE) other flows can gate on, for example to pause a bulk narration job or switch to a fallback voice when the quota is nearly gone.The quota lives on a settings page and usage spikes come from your own batch jobs, often ones already running 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 status output lets the very flows that use the quota hold back before it runs out.
ELEVENLABS_API_KEY: an ElevenLabs API key with permission to read the user subscription.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_ELEVENLABS_API_KEY=$(echo -n 'sk_xxxxxxxx' | base64), and read back with {{ secret('ELEVENLABS_API_KEY') }}. Use the Enterprise secrets backend for encryption at rest and access control.
ELEVENLABS_API_KEY and SLACK_WEBHOOK as secrets.warning_used_pct below your current usage to see the WARNING path, then set it back.quota_check.character_count in a KV store to compute the daily burn rate and alert when the quota will run out before the reset date.status == HEALTHY with a Flow trigger.warning_used_pct: type FLOAT, default 80.0.critical_used_pct: type FLOAT, default 95.0.status: one of HEALTHY, WARNING, CRITICAL, UNREACHABLE.{{ fromJson(outputs.summarize_quota.value).chars_left }} for the characters left this period.CRITICAL as "expensive from now on" rather than "stopped" in that case.next_character_count_reset_unix against the Kestra server clock in UTC.