API

NAME

OpenRouter::API - Raku client for OpenRouter's non-inference REST API

SYNOPSIS


use OpenRouter::API;

# Reads OPENROUTER_API_KEY from %*ENV by default.
my $or = OpenRouter::API::Client.new;

# Full model catalogue, cached in-process for 5 minutes.
my @models = $or.get-models;

# Keyword / capability / cost filtering (all client-side; OR has no
# server-side name search). Hits the cached catalogue.
my @claude = $or.search-models(
    :keyword<claude-opus>,
    :supports-tool-use,
    :min-context-length(200_000),
);

# Credit balance.
my $credits = $or.get-credits;
say "${$credits.remaining} USD left";

# Daily spending log — last 30 UTC days. REQUIRES A MANAGEMENT KEY.
my @rows = $or.get-activity(:date<2026-04-23>);
say @rows.map(*.cost).sum, " USD spent on 2026-04-23";

# Per-call cost lookup. Pass a Str gen-id or any object with a
# .generation-id method (e.g. LLM::Chat::Backend::Response::OpenRouter).
my $gen = $or.get-generation('gen-abc123');
my $g2  = $or.get-generation($llm-chat-response);   # duck-typed

DESCRIPTION

Thin wrapper over OpenRouter's REST surface for everything that isn't chat / text inference. Inference lives in LLM::Chat::Backend::OpenRouter; this module is for tooling that needs to read models, track spend, or look up generations after the fact.

Design goals:

  • Typed results with an escape hatch. Every endpoint returns a Result::* object with named accessors and derived helpers (Model.cheapest-endpoint, ActivityRow.cost-per-1k-tokens, ...). .raw exposes the wire hash verbatim for fields we haven't typed yet.

  • Tier 0 dependency. The only external deps are Cro::HTTP::Client and JSON::Fast. The LLM::Chat::Backend::Response::OpenRouter integration is duck-typed via .can('generation-id') so you get the convenience without the dependency direction being inverted.

  • Cached model catalogue. search-models goes through a 5-minute TTL cache — the catalogue is hundreds of KB and rarely changes, so repeated filters don't round-trip. Disable with :cache(False) on the Client, or call .clear-cache to invalidate.

  • No inference. POST /chat/completions is deliberately absent. Use LLM::Chat::Backend::OpenRouter for that.

SEE ALSO

OpenRouter::API v0.1.1

Raku client for OpenRouter's non-inference REST API

Authors

  • Matt Doughty

License

Artistic-2.0

Dependencies

Cro::HTTP:ver<0.8.11>:auth<zef:cro>JSON::Fast:ver<0.19>:auth<cpan:TIMOTIMO>

Test Dependencies

Provides

  • OpenRouter::API
  • OpenRouter::API::Client
  • OpenRouter::API::Filter
  • OpenRouter::API::Result::ActivityRow
  • OpenRouter::API::Result::Credits
  • OpenRouter::API::Result::Endpoint
  • OpenRouter::API::Result::Generation
  • OpenRouter::API::Result::Model
  • OpenRouter::API::Result::Provider

The Camelia image is copyright 2009 by Larry Wall. "Raku" is a trademark of the Yet Another Society. All rights reserved.

Built with Podlite — the markup and publishing tools behind this site.