OpenAI-compatiblepaid in native VAGAdurable · idempotent

Agents don’t hold credit cards.
They hold VAGA — and settle for exactly what they use.

VAGA Router gives VagaChain agents an OpenAI-compatible inference endpoint. Every request reserves a maximum VAGA bound on-chain, forwards to EUrouter, reconciles the provider’s actual EUR cost, settles actual + markup — and releases the unused reservation back to the agent.

Open the PlaygroundIssue a credential
01 · reserving maximum bound02 · forwarding to eurouter03 · settling actual cost + markup04 · releasing the remainder
EUROUTERinference · eur pricingESCROW · VAGAmax bound reservedAGENTvaga agentTREASURYactual + markupreservesettlerequest / usagerelease remainder
chat/completions · openai-compatiblecurl
curl http://127.0.0.1:8787/v1/chat/completions \
  -H "Authorization: Bearer vcomp_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: demo-0001" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [{ "role": "user", "content": "Explain escrow in one line." }],
    "max_completion_tokens": 64
  }'

The bearer token authenticates only. Payment happens on VagaChain: the router reserves first, settles the real cost after inference, and is safe to retry with the same Idempotency-Key.

POST /v1/chat/completions·POST /v1/responses·GET /v1/models·POST /v1/credentials·POST /v1/credentials/:id/revoke·GET /healthz·Authorization: Bearer vcomp_…·Idempotency-Key·x-vaga-compute-operation-id·1 VAGA = 10¹² base units·
01 /the flow

Seven steps between a prompt and a settled receipt.

Every inference is a durable operation with persisted state transitions — reserved before the provider call, reconciled against real usage, settled or released on-chain.

  1. 01

    Credential

    The agent authenticates with a bearer credential (vcomp_…), issued by a controller-signed Ed25519 request and revocable at any time. The token authenticates only — payment never touches it.

  2. 02

    Quote

    Before any VAGA moves, the router performs an authenticated live lookup of the exact EUrouter model record. It must expose EUR prompt/completion pricing and support the requested endpoint and capabilities.

  3. 03

    Reserve

    A conservative upper bound — UTF-8 input bytes ×2 + 64 tokens plus the requested output limit — is converted to VAGA base units with one upward rounding and reserved on VagaChain with a block TTL.

  4. 04

    Infer

    Exactly one forward to EUrouter. Streaming is passed through as raw SSE. Once the provider window opens, the request is never retried — ambiguity is marked, not guessed.

  5. 05

    Reconcile

    The provider's actual EUR cost is extracted from the generation or response usage. An unverifiable cost releases the full reservation — the agent is never charged for uncertainty.

  6. 06

    Settle

    On-chain settlement of actual cost + configured markup, derived from deterministic quote, settlement, review, and run hashes. Reserve, settle, and release are idempotent and durable across restarts.

  7. 07

    Release

    The unused remainder of the reservation returns to the agent's escrow — back to zero — and the OpenAI-compatible response is returned with an x-vaga-compute-operation-id reference.

02 /settlement math

Exact money, to the 12th decimal.

VAGA settles in integer base units — 10¹² per token. The router reserves the worst case, then charges one final, upward-rounded conversion of the provider's actual EUR cost.

native unit precision
1VAGA =
1000000000000

Micro-charges survive the rounding: even 10⁻²⁰ EUR converts to at least one base unit — every settlement is an exact integer amount on VagaChain, never a float.

reservation bound estimator
illustrative
Input tokens
Output limit
Expected completion
Request fee €
Prompt €/1M
Completion €/1M
EUR per VAGA
Operator markup
100%
reserve bound 0.0004536 EUR · worst caseexpected actual 0.00039 EUR · + markup
0.009072VAGA reserved (max)
9072000000 base units
settled 0.0078 VAGA · 86.0%released 0.001272 VAGA · 14.0%

Mirrors the backend conversion ceil(cost · (1+markup) · 10¹² ÷ eur_per_vaga). The reservation uses the output limit; after inference the router settles EUrouter’s returned actual cost and releases the remainder. Rate, markup, and prices here are illustrative (.env.example defaults); the real request bound also uses canonical-JSON input bytes ×2 + 64 tokens.

03 /live catalog

Models come from /v1/models — nothing else.

The catalog is the authenticated, live EUrouter listing filtered by the router to models with verifiable EUR pricing and bounded text inference. No hardcoded model lists, no cached catalogs.

Bearer credential · vcomp_…

Connect with a vcomp_ credential — issue one below in the Credential Studio.

04 /credential studio

Issue a vcomp_ credential — signed outside the browser.

Credentials are issued from a controller-signed Ed25519 request against the agent's registered controller key. This frontend never accepts private key material: you sign with your agent CLI or the documented node one-liner, and the signature is verified locally against the public key before anything is sent.

Agent ID
Controller key · Ed25519 public, 0x + 64 hex
Label · optional, ≤ 80 chars
Lifetime
Expires at · UTC ms
Nonce · canonical decimal
Signature · 128 hex over the message on the right

This frontend never accepts seeds or private keys. The signature is checked locally against your public controller key, then verified server-side by the backend.

Canonical message · sign exactly these UTF-8 bytes
Fill in agent id and controller key…
Sign externally · node one-liner (localhost tooling)

what the backend checks

  • · the controller key is registered on the VagaChain agent
  • · the Ed25519 signature over the canonical message verifies
  • · the nonce is canonical and the issue hash was never used before (replay protection)
  • · expiry is a millisecond UTC ISO timestamp within the configured max lifetime
05 /api reference

Speak OpenAI. Settle on VagaChain.

Three OpenAI-compatible endpoints, two signed credential endpoints, one health probe. Everything below mirrors the running backend contract — including what happens when things go wrong.

inference
  • GET
    /v1/models

    Authenticated live model catalog (EUrouter-shaped, filtered to safe models).

  • POST
    /v1/chat/completions

    OpenAI-compatible chat. Requires Idempotency-Key (recommended).

  • POST
    /v1/responses

    OpenAI Responses API shape. Same billing pipeline.

  • GET
    /v1/operations/:id

    Settlement & receipt status for the caller's own operations — foreign or unknown ids are a non-enumerable 404.

credentials
  • POST
    /v1/credentials

    Controller-signed issue. Returns the raw vcomp_ token exactly once.

  • POST
    /v1/credentials/:id/revoke

    Controller-signed revocation. Immediate 401s afterwards.

  • GET
    /healthz

    Unauthenticated process health check.

headers that matter
Authorization
Bearer vcomp_… — authentication only; payment is on-chain VAGA.
Idempotency-Key
Recommended. Same key + same body replays the settled response; different body with same key → 409.
x-vaga-compute-operation-id
Returned on every inference response — the durable operation reference (op_…).
Retry-After
Present on retryable 503s; retry with the identical Idempotency-Key.
openai sdk · drop-in
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.VAGA_ROUTER_TOKEN, // vcomp_… (auth only)
  baseURL: "https://api.vagarouter.dnsstack.pro/v1"
});

const completion = await client.chat.completions.create(
  {
    model: "openai/gpt-4o-mini",
    messages: [{ role: "user", content: "ping" }],
    max_completion_tokens: 64
  },
  { headers: { "Idempotency-Key": "agent-run-42" } }
);

Point any OpenAI SDK at the router base URL and pay with VAGA. The local backend listens on http://127.0.0.1:8787/v1; the public gateway is served via Cloudflare in front of the same process.

response shape
{
  "id": "resp-…",
  "model": "openai/gpt-4o-mini",
  "choices": [{
    "message": { "role": "assistant", "content": "Escrow = " … },
    "finish_reason": "stop"
  }],
  "usage": { "prompt_tokens": 21, "completion_tokens": 14 }
}
failure is a first-class citizen
HTTPCodeMeaningRetry
401invalid_bearer_token / credential_expired_or_revokedCredential missing, unknown, expired, or revoked.no
402insufficient_balanceAgent liquid VAGA is below the reservation bound.no
400model_not_found / model_capability_unsupportedLive catalog rejected the model or its pricing.no
400unsupported_request / unsupported_input_modalityBounded-inference rules: text only, n=1, no unbounded features.no
409Idempotency-Key conflictSame key used with a different request body.no
409provider_call_ambiguousProvider outcome unknown — never blindly retried.no
503reservation_pending / settlement_pendingDurable operation in progress.yes · same key
502provider_request_failedNo billable result; reservation fully released.new request

Streaming requests are raw SSE passthrough: after the provider window opens, nothing is retried. Interrupted provider calls become recovery_required — visible as 409 with the operation id, reconciled by the backend, never duplicated.

06 /playground

Run a real request. Watch it settle.

This talks to the live VAGA Router backend: real reservation, real EUrouter inference, real settlement. Every run carries an Idempotency-Key and returns its durable operation id.

Bearer credential · vcomp_…

The playground sends your credential only as an Authorization header to the API base.

Model
System · optional
Prompt
max_completion_tokens
Idempotency-Key
no request yet

reserve → infer → settle → release

connect a credential and run

No keys, ever

The frontend holds no private keys and no provider secrets. Your controller seed signs in memory and is gone when the tab closes.

Auth-only tokens

The vcomp_ credential is sent only as an Authorization header. It never touches analytics, logs, or third parties — payment runs over VagaChain.

Internal by default

The VagaChain RPC and the backend database stay on loopback. The public gateway fronts the router process only — never the chain node.

Verifiable operations

Every request yields a durable operation id and a hash-only inference receipt commitment — evidence without exposing payload content.