Direct API integration

There is no proprietary API to learn. The optimizer is an OpenAI-compatible gateway: point a stock OpenAI client — or curl — at it, and every feature works over plain HTTP. This page is the whole surface for a team that does not want a dependency.

The one change

Swap the base URL to the edge, send your optimizer key as the bearer token, and send your provider key in x-provider-key. That is the integration.

curl https://rfa-labs.com/v1/chat/completions \
  -H "Authorization: Bearer $SHIMMY_API_KEY" \
  -H "x-provider-key: $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [{ "role": "user", "content": "Say hello." }]
  }'
  • Authorization: Bearer sk-opt-… — your optimizer key. It identifies the tenant and is stored only as a hash; it is not your provider key.
  • x-provider-key — the upstream key the gateway calls the model with (your OpenAI, Anthropic, etc. key). Alternatively, store per-tenant provider keys once and omit this header.
  • model: "auto" — hands model choice to the gateway. A pinned model name is honored verbatim and turns routing off (and no saving is claimed on that call). "discover" makes the gateway search for the cheapest model that holds this step’s quality.

Any provider works from the same client — naming a Claude model is enough, because the edge translates OpenAI’s wire format to each provider server-side:

{ "model": "claude-haiku-4-5", "messages": [{ "role": "user", "content": "hi" }] }

Telling the gateway what it can’t see

The gateway sees independent HTTP requests. Three things about your workload it otherwise has to guess — how calls nest into runs, what each step is for, and whether the answer was good — you can state outright by attaching an optimizer object to the request body. This is the wire contract; the SDK simply builds it for you.

curl https://rfa-labs.com/v1/chat/completions \
  -H "Authorization: Bearer $SHIMMY_API_KEY" \
  -H "x-provider-key: $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [{ "role": "user", "content": "Classify: is this spam?" }],
    "optimizer": {
      "run":  { "id": "job-1042", "seq": 0, "is_start": true },
      "step": { "id": "classify_intent", "kind": "classification" }
    }
  }'
The optimizer block is stripped before the request reaches your provider — a provider that rejects unknown keys never sees it.

The block is fully optional and every field within it is too. A request with no optimizer object behaves exactly as a plain OpenAI call. The fields:

FieldMeaning
run.idStable id grouping the calls of one execution. Any string you can reproduce for the run — a job id, a trace id.
run.seq0-based position of this call in the run.
run.parentThe step this call was made from. The one field that separates a fan-out from a chain.
run.is_startWhether this call opens the run (gates plan-cache lookup).
step.idStable identity for this step, surviving prompt edits — so its learned routing is not reset when you reword.
step.kindWhat kind of work it is (classification, extraction, reasoning, …) — a difficulty prior, not a pin.
step.quality.min_scoreRaise this step’s quality bar. Can only tighten the tenant floor, never loosen it.
intent.objectivecost, quality, or latency — which way to lean when they conflict.
source.file / line / releaseWhere in your code the call was made, so a dashboard row points at a line and evidence is scoped per deploy.

Reading what a call cost

The response carries an optimizer block alongside the usual choices:

# The response carries an `optimizer` block alongside the usual choices:
{
  "choices": [ ... ],
  "optimizer": {
    "cache_hit": false,
    "baseline_cost": 0.0121,
    "served_cost": 0.0018,
    "actual_cost": 0.0018,
    "exploration_cost": 0.0,
    "saving": 0.0103
  }
}
FieldMeaning
savingBaseline cost minus what was actually spent.
baseline_costWhat this call would have cost on your pinned/declared model.
served_costThe optimized path alone.
exploration_costWhat was paid to learn whether a downshift was safe — converges toward zero as a step settles.
cache_hitWhether it was served from cache.

Reporting outcomes

The quality gate can buy a signal by dispatching a second call and paying a judge — that spend reaches you as exploration_cost. Your own code already knows whether the JSON parsed or the tool ran. Report it, and free observation replaces bought grading:

curl https://rfa-labs.com/v1/outcomes \
  -H "Authorization: Bearer $SHIMMY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "run_id": "job-1042",
    "step_id": "classify_intent",
    "signals": { "schema_valid": true, "tool_executed": true }
  }'
POST /v1/outcomes — attributed to the step, so report it after you know the result.

Signals you can send (any subset): schema_valid, tool_executed, retried, run_completed, human_verdict (accepted / edited / rejected), and score (a [0,1] number from your own eval). A hard failure you observed outranks any score.

Not double-billing a retry

If your client retries a completion (timeout, dropped connection), send an Idempotency-Key so the gateway replays the first attempt’s result instead of dispatching — and metering — a second time.

curl https://rfa-labs.com/v1/chat/completions \
  -H "Authorization: Bearer $SHIMMY_API_KEY" \
  -H "x-provider-key: $OPENAI_API_KEY" \
  -H "Idempotency-Key: 8f3c…-per-logical-request" \
  -H "Content-Type: application/json" \
  -d '{ "model": "auto", "messages": [ ... ] }'

Reading savings

Everything the dashboard shows is a plain authenticated GET. The savings total, split by source:

curl https://rfa-labs.com/v1/dashboard/savings \
  -H "Authorization: Bearer $SHIMMY_API_KEY"

For the per-call detail — what each request was routed to, what it saved, why — GET /v1/calls. The full set of control-plane reads and writes (billing statement, agents, settings) is listed in the control-plane reference; every method there is a thin wrapper over a /v1 endpoint you can call directly the same way.

Next

  • SDK vs direct API — what you give up by staying on raw HTTP, and what you don’t.
  • Concepts — what runs, steps and outcomes mean, and why the gateway cannot infer them.
  • Control plane — every /v1 read and write.