Developers

Documentation

Everything you need to send your first request and to keep it working in production.

Introduction

Vantafold is a single API in front of every model your product might use. You send a request to api.vantafold.ai; we normalise it, pick a model according to your policy, call the provider, and return one response shape with the cost and the route attached.

If you have used a provider SDK before, the mental model is the same. The differences are that the model name is a string you can change freely, and that every response tells you what it cost.

New here? The fastest path is to install an SDK, export a key, and run the snippet under Your first call. It takes about two minutes.

Getting started

Install the SDK for your language. Every client is generated from the same OpenAPI spec, so the method names and field names match across languages.

pip install vantafold

Requirements

  • Python 3.9+, Node 18+, Go 1.21+, or Ruby 3.1+.
  • Outbound HTTPS to api.vantafold.ai on port 443.
  • An API key from the dashboard — the free tier needs no card.

Authentication

Vantafold uses bearer tokens. Create a key per environment, never per developer, and scope it to a project so its spend is capped independently.

shell
export VANTAFOLD_API_KEY="vf_live_8f2c41a9b7e04d31"

Every SDK reads VANTAFOLD_API_KEY from the environment by default, so the client constructor usually takes no arguments. Pass the key explicitly only when you manage several credentials in one process.

Key types

  • Live keys (vf_live_…) bill against your plan and route to real models.
  • Test keys (vf_test_…) return deterministic fixtures, cost nothing, and are safe in CI.
  • Restricted keys can be limited to specific models, endpoints, or a monthly spend ceiling.

Never ship a key to a browser or a mobile app. Call Vantafold from your server. If you need a client-side path, mint a short-lived scoped token with POST /v1/tokens and hand that out instead.

Making your first call

The reason endpoint is the one you will use most. It takes an input, an optional model, and returns text, tool calls, or structured output.

POST api.vantafold.ai/v1/reason
from vantafold import Vantafold

client = Vantafold()   # reads VANTAFOLD_API_KEY from the environment

response = client.reason(
    model="auto",
    input="Summarise this support thread in three bullets.",
    metadata={"project": "support-triage"},
)

print(response.output_text)
print(response.route.selected, response.usage.cost_usd)

A successful response looks like this. Note route and usage — they are on every response, whichever model answered.

200 OK
{
  "id": "req_8f2c41a9",
  "model": "frontier-sm",
  "output_text": "- Customer cannot log in after SSO migration\n- Error is 403 from the IdP\n- Escalated to platform on 12 Aug",
  "usage": { "input_tokens": 1840, "output_tokens": 64, "cost_usd": 0.0021 },
  "route": { "requested": "auto", "selected": "frontier-sm", "attempts": 1,
             "reason": "met quality bar at 14% of frontier-lg cost" },
  "trace_id": "tr_5b1d9e0c"
}

Choosing a model

Pass model="auto" to let the router choose, or name a model from the catalog to pin it. Pinning is the right default while you are still evaluating; auto is the right default once you have an evaluation set.

Streaming

Every model streams, in one event format. Deltas arrive as output_text.delta; tool calls and completion arrive as their own events.

stream.py
stream = client.reason.stream(model="auto", input=prompt)

for event in stream:
    if event.type == "output_text.delta":
        print(event.delta, end="", flush=True)
    elif event.type == "tool_call":
        print(f"\n[tool] {event.name}({event.arguments})")
    elif event.type == "response.completed":
        print(f"\n[done] {event.usage.cost_usd:.4f} USD via {event.route.selected}")

Errors and retries

The SDKs retry idempotent failures with exponential backoff and jitter. What reaches your code is a failure that survived the whole fallback chain.

errors.py
from vantafold import Vantafold, RateLimitError, ProviderError

client = Vantafold(max_retries=3, timeout=30.0)

try:
    response = client.reason(model="auto", input=prompt)
except RateLimitError as err:
    # Your project spend cap or a provider limit. err.retry_after is seconds.
    schedule_retry(after=err.retry_after)
except ProviderError as err:
    # Every fallback in the chain failed. err.attempts lists what was tried.
    log.warning("all routes failed", attempts=err.attempts)

Status codes

CodeMeaningWhat to do
400Malformed requestFix the payload. The message names the offending field.
401Bad or missing keyCheck the Authorization header and the key's environment.
403Key not permittedThe key is restricted from this model or endpoint.
404Unknown modelCheck the model string against the catalog.
422Schema violationStructured output failed validation after one retry.
429Rate or spend limitBack off for retry_after seconds, or raise the cap.
500Vantafold errorRetry. If it persists, check the status page.
529All routes degradedEvery fallback failed. attempts lists what was tried.