Upfyn gives you three models behind one endpoint. The API speaks the OpenAI Chat Completions dialect, so if you have written against that before, you already know this one — point your existing client at a different base URL and change the model id.
| Approach | Best for |
|---|---|
| The HTTP API | Full control, any language, no dependencies. |
| The OpenAI SDKs | Typed calls from Python or TypeScript with almost no setup. |
| Agent patterns | Tool loops, sessions, and anything that runs more than one turn. |
Get a key#
- 1
Create an API key
Go to API Keys in your dashboard and create one. Keys look likeupfynai-sk-followed by 32 characters. - 2
Copy it now
The key is shown once. Afterwards the dashboard only ever displays the last four characters, because we store a hash rather than the key itself. If you lose it, revoke it and make another. - 3
Keep it server-side
A key carries your credits. Put it in an environment variable and call the API from your own backend — never from a browser or a mobile app, where anyone can read it.
Make your first call#
The base URL is https://ai.upfyn.com/v1. Authentication is a bearer token.
curl https://ai.upfyn.com/v1/chat/completions \-H "Authorization: Bearer $UPFYN_API_KEY" \-H "Content-Type: application/json" \-d {"model": "upfyn-yuva","messages": [{ "role": "user", "content": "Explain what a gateway does, in two sentences." }]}
What comes back#
A standard chat.completion object, plus a few fields of our own so you never have to make a second call to find out what a request cost.
{"id": "chatcmpl-4f1c...","object": "chat.completion","created": 1787950410,"model": "upfyn-yuva","choices": [{"index": 0,"message": { "role": "assistant", "content": "A gateway sits between..." },"finish_reason": "stop"}],"usage": {"prompt_tokens": 18,"completion_tokens": 42,"total_tokens": 60},"credits_used": 0.31,"credits_remaining": 4821.44,"request_id": "req_9a2f...","session_id": null}
Upfyn additions
| Field | Type | Required | Notes |
|---|---|---|---|
| credits_used | number | — | What this request actually cost, after the real token counts came back. |
| credits_remaining | number | — | Your balance after the charge. |
| request_id | string | — | Quote this if you contact support about a specific call. |
| session_id | string | null | — | Set only when you opted into a stored conversation. See Sessions. |
Typed clients
These extra fields sit alongside the standard ones. Strictly-typed SDK models may not surface them — read them off the raw response if your client hides unknown keys.Pick a model#
There are three, and the id is the whole choice — you never name a provider.
| Model | Context | Takes | Reach for it when |
|---|---|---|---|
upfyn-bala | 262K | Text | High volume, plain text, latency matters most. |
upfyn-yuva | 1M | Text, images, audio, documents | The default. Most production work belongs here. |
upfyn-rishi | 1M | Text, images, audio, video, documents | Hard reasoning, or anything involving video. |
Every model is metered
There is no free model. The free plan includes a monthly credit allowance, and Bala is the cheapest of the three — but all three are billed per token. Older documentation that describes Bala as free is out of date.Models covers what each one accepts and produces in full.
Stream the answer#
Set stream: true. Add stream_options.include_usage if you want the final cost — without it, a streaming call never tells you what it settled at.
stream = client.chat.completions.create(model="upfyn-yuva",messages=[{"role": "user", "content": "Write a haiku about latency."}],stream=True,stream_options={"include_usage": True}, # ask for the final usage + credits chunk)for chunk in stream:if chunk.choices and chunk.choices[0].delta.content:print(chunk.choices[0].delta.content, end="", flush=True)
Streaming explains the chunk format, how the stream terminates, and how to resume one that dropped.
Where to go next#
- Tool calling — let the model call your functions.
- Structured outputs — get JSON that matches a schema.
- Errors — every status code and what to do about it.
- Rate limits — the actual numbers, and the headers that report them.
