SOLWYN

Surface coverage

What happens when you call each surface through Solwyn — priced, recorded-but-unpriced, untracked under your on_unmetered posture, fail-loud, or structural pass-through.

Solwyn wraps the client you already use, so you keep calling your provider's own methods. When a call reaches the wrapper, exactly one thing happens to it: Solwyn either meters it (budget check plus a cost event), records it without a price, treats it as untracked under your on_unmetered posture (warn once by default), refuses it, or — for a structural attribute that carries no spend — passes it through in silence. This page lists every surface and the posture it gets.

One invariant holds across all of them: Solwyn is a wrapper, not a proxy, so the call still goes directly to the provider, and only bounded metadata — integer and float quantities (token counts, image counts, whole-second durations, character counts) and short selector strings (resolution, quality) — leaves your process. Never a prompt, never media bytes, never a transcript, never generated content. See Privacy for the full wire contract.

The five postures

PostureWhat Solwyn doesCost event
PricedBudget-checks before dispatch, then reports usage so the Cloud API can price itYes, priced
Recorded but unpricedRecords the call when the billable quantity is unobservable — never a fabricated $0Yes, unpriced
Untracked — your posture decideswarn (default): logs one warning per surface per process, then forwards the call. raise: refuses it with UntrackedSpendSurfaceError before any provider I/O. allow: forwards it silently.No
Fails loudRaises rather than let a spend surface bypass tracking silentlyNo (call refused)
Structural pass-throughForwards attributes that carry no spend, and hands back resource namespaces as guarded objects whose members are classified one by oneNo

SDK v0.6.0+: every public attribute path on a wrapped client resolves to one of these. Before 0.6.0 a short allow-list of billable surfaces warned and everything else — files, batches, models.list, the Responses helpers — passed in silence. Now the whole reachable graph is classified, and solwyn.coverage(client) returns the classification for the client you actually hold. See Coverage controls.

Priced

Budget-checked before the request — an over-budget call is denied before the provider is reached — then recorded as a cost event tagged with a modality, which the Cloud API prices per-token or per-unit from the model's price card.

ModalitySurfacesPriced on
chatchat.completions.create (OpenAI, Together, every OpenAI-compatible endpoint), messages.create (Anthropic), models.generate_content (Google), converse / converse_stream (Bedrock)provider-reported token counts
chat — Responses APIresponses.create, responses.parse, and the responses.stream() helper on native OpenAI and Azure OpenAI (SDK v0.6.0+; modality text) — see The Responses APIprovider-reported token counts, read from the response or the stream's terminal response.completed event; when usage is missing or zeroed, a marked input-only estimate (is_estimated) so the call is never a silent $0
embeddingembeddings.create (OpenAI, compat, native Together), models.embed_content (Google)input tokens (usage.prompt_tokens; Google exposes no usage, so counts are length-estimated and flagged is_estimated)
imageimages.generate / images.edit (OpenAI, compat, native Together), models.generate_images (Google Imagen); image-output chat models (e.g. gemini-3-pro-image)token buckets for token-billed models (OpenAI gpt-image, Gemini image-output); request-derived image count × per-image rate for compat, Together, and Imagen
audioaudio.transcriptions.create, audio.speech.create (OpenAI + compat, incl. Groq); Gemini TTS / native-audio via generate_contenttranscription: token buckets (gpt-4o-transcribe) or whole-second duration on a JSON response_format (whisper-1, Groq per-hour); speech: input character count, measured inside the privacy firewall (tts-1 / tts-1-hd, Groq Orpheus)
videovideos.create (OpenAI Sora), models.generate_videos (Google Veo)requested duration × resolution variant's per-second rate

Video generation is asynchronous and the job carries no usage, so — because neither provider charges for a failed or blocked generation — video billing settles at initiation: the cost event is recorded at request time and always flagged is_estimated, a deliberate, conservative over-count. Its pre-flight budget check is nonetheless exact, so an over-budget request is denied before the provider is called.

For each modality, only the quantities and selectors leave your process — never the prompt, never a reference image, never the returned bytes.

Recorded but unpriced

Some calls are genuinely billable but expose no observable quantity to price on. Rather than invent a number or fabricate a $0, Solwyn records the event and leaves it unpriced on the dashboard — an honesty lane, visible but explicitly not costed. This is a settlement outcome of a priced surface, not a separate classification:

  • A whisper-1 or compat transcription with a non-JSON response_format (text, srt, vtt) — the provider returns no usage block. The SDK warns once suggesting a JSON response_format.
  • A Veo generate_videos call with no config.duration_seconds — Google publishes no default duration, so there is no basis to price on and none is guessed.
  • Any unit-priced call whose quantity could not be observed.
  • A Bedrock call whose model is an opaque ARN the Cloud API cannot resolve to a price card.
  • Zero-cost local providers (ollama, vllm, lmstudio) and the generic openai_compatible catch-all — providers with no price book, where any model is recorded for visibility and never silently costed.

Untracked — your posture decides

A capability Solwyn has reviewed and does not meter yet, or one it has never seen (typically new in a provider-SDK release), follows on_unmetered. Under the default warn, the SDK logs one WARNING per provider, client shape, sync/async mode, and dotted surface path per process — naming only the provider and the surface, never request data — and then runs the call untracked: no budget check, no cost event, and an advisory report to Solwyn Cloud so the Providers tab can show what your code touched. raise refuses the call before any provider I/O with UntrackedSpendSurfaceError; allow restores silence. An exact token in acknowledge_untracked exempts one leaf from all three.

Representative untracked leaves — the full list for your client comes from solwyn.coverage(client):

  • OpenAI, Azure OpenAI, and every OpenAI-compatible endpoint: moderations.create, models.list, files.*, batches.*, fine_tuning.*, vector_stores.*, the non-metered Responses leaves (responses.retrieve, .delete, .cancel, .compact, .connect, .input_items.list, .input_tokens.count), audio.translations.create, the with_raw_response / with_streaming_response families, and the admin.* tree. The token-billed TTS model gpt-4o-mini-tts returns no usage of any kind and is untracked under the conditional token audio.speech.create:gpt-4o-mini-tts. On a compatible endpoint other than Azure, every Responses leaf is untracked — create / parse / stream included: they are not budget-checked and produce no cost event (SDK v0.6.0+).
  • Anthropic: messages.count_tokens, models.*, completions.create (pre-1.0 clients only), and Anthropic 1.0's stable files.* and skills.*, plus the beta.* tree.
  • Google (google-genai): files.*, caches.*, batches.*, tunings.*, models.count_tokens, live.connect, and their aio.* mirrors.
  • Amazon Bedrock: apply_guardrail, count_tokens, get_async_invoke, list_async_invokes, and the boto3 plumbing (get_paginator, get_waiter, ...).
  • Together (native client): completions, rerank, code_interpreter, evals, batches, files, fine_tuning, endpoints, and whoami. See Together AI.

Some untracked rules describe an escape rather than an operation — with_options, copy, and the raw get / post / request verbs on OpenAI-dialect and Anthropic clients, aio on Google, the audio.translations resource itself. Their capability scope (client, resource, raw_response, arbitrary_endpoint) appears in the warning, and acknowledging one at exactly its own path hands back the raw provider object.

Fails loud

A primary spend surface Solwyn cannot track without bypassing the budget or buffering customer content raises instead of running silently untracked:

  • On Bedrock, invoke_model, invoke_model_with_response_stream, and start_async_invoke raise ConfigurationError. Their usage lives inside a consume-once body alongside response content (invoke_model), or lands out-of-band in S3 (start_async_invoke), so it cannot be extracted without violating the privacy boundary. Use converse / converse_stream, or call the unwrapped boto3 client directly for deliberately untracked calls.
  • videos.create on an OpenAI-compatible or native Together client raises UnsupportedSurfaceError: Solwyn's video interception is wired for OpenAI's Sora only, and no video seam exists on the OpenAI-compatible dialect those clients speak — so the call fails loud rather than passing through as if untracked.
  • The same rule holds for any media surface an adapter serves no seam for — embeddings.create on a wrapped Anthropic client, for instance, raises UnsupportedSurfaceError rather than running untracked.
  • A metered Responses call in a shape Solwyn cannot meter — background=True, a streaming parse, or an extra_body that overrides model, input, instructions, max_output_tokens, or stream — raises ConfigurationError before the budget check. See The Responses API.
  • Under on_unmetered="raise", every untracked leaf above raises UntrackedSpendSurfaceError before any provider I/O — the opt-in strict posture. See Coverage controls.

Structural pass-through

Two kinds of attribute are forwarded without a warning in any posture, because they cannot carry spend:

  • Metadata and infrastructurebase_url, api_key, timeout, close, and the like. These are the only attributes that are unconditionally silent.
  • Namespacesaudio, beta, responses, chat, and every other resource container. Accessing one returns a guarded resource, not the raw object; each member you then reach is classified on its own. Access to a parent never grants its descendants, and the with protocol is not forwarded on a guard.

Private attributes (any _-prefixed name that is not _solwyn_) belong to the provider client and bypass the guard entirely.

Deliberately-unbilled models

When a pre-flight budget check names a model the Cloud API has deliberately chosen not to price, the API answers the check with a structured 422. The SDK treats that like any non-2xx and resolves it through the standard fail-open path: the call is allowed and proceeds untracked. Solwyn never blocks a call solely because it cannot yet price it.

What leaves your process

Across every posture above, the privacy boundary is identical: bounded metadata only — the MetadataEvent counts, durations, character counts, and selector strings, plus structural labels and any tags you attach yourself. An untracked surface adds one more payload, the advisory report: provider, client shape, the dotted surface path, and an occurrence count — no model names, arguments, or content. No prompt, no media bytes, no transcript, no generated content ever leaves your process. Per-provider detail lives on each provider page.

On this page