Permalink to ModelsModels

The model catalogue is the one place that says, authoritatively, which models your key can reach and what each one costs. Model availability changes as upstream vendors come and go, so read the list at runtime rather than hard-coding it.

Permalink to list-modelsList models

bash
curl https://hypit.ai/v1/models \
  -H "Authorization: Bearer $HYPIT_API_KEY"
json
{
  "object": "list",
  "data": [
    {
      "id": "nano-banana-pro",
      "object": "model",
      "created": 1787824589,
      "owned_by": "hypit",
      "modality": "image",
      "display_name": "Nano Banana Pro",
      "description": "…",
      "tags": ["image", "edit"],
      "endpoints": ["images", "image_edits"],
      "pricing": {
        "mode": "per_image",
        "currency": "usd",
        "per_image_usd": 0.0,
        "credits": { "base": 0.0 }
      }
    }
  ]
}

The first four fields (id, object, created, owned_by) are the OpenAI shape byte for byte, so client.models.list() in an unmodified OpenAI SDK works. Everything after them is ours; clients that do not want the extra keys ignore them.

Permalink to endpointsendpoints

The most useful field. It names which routes will actually accept the model, and it is the answer to "why does this model 404 on /v1/videos". The vocabulary is fixed:

ValueRoute
imagesPOST /v1/images/generations
image_editsPOST /v1/images/edits
videosPOST /v1/videos
chatPOST /v1/chat/completions
geminiPOST /v1beta/models/{model}:{action}
audio_speechPOST /v1/audio/speech
transcriptionsPOST /v1/audio/transcriptions
audio_musicPOST /v1/audio/music

modality is coarser — one of image, video, chat, audio — and is what the job envelope's kind will say.

Permalink to pricingpricing

pricing.mode tells you what the model charges per: per_image, per_request, per_second, per_token, per_k_char or per_audio_second. The *_usd figures are the retail price already including our markup, kept as a reference; the figure that matters is pricing.credits, because credits are the only balance an account holds.

json
"pricing": {
  "mode": "per_second",
  "currency": "usd",
  "per_second_usd": 0.0,
  "resolution_ratio": { "480p": 1, "720p": 2.1579, "1080p": 5.3684 },
  "credits": { "per_second": 0.0 }
}

Token rates inside credits are quoted per thousand tokens (input_per_k, output_per_k, cached_per_k, reasoning_per_k), while the USD fields beside them are per million — that is how vendors publish, and how our rate cards store them. The ratio tables (size_ratio, quality_ratio, resolution_ratio, flag_ratio) are pure multipliers on the headline rate: a 1080p second of a model whose resolution_ratio["1080p"] is 5.3684 costs per_second × 5.3684.

token_tiers is a long-context ladder: each rung carries a min_prompt_tokens threshold and the rates that apply above it. A rate left at zero on a rung inherits the headline one.

Do not re-derive credits from the USD numbers

The projection from dollars to credits involves a per-model multiplier that the API deliberately does not publish. Read pricing.credits; a client that multiplies per_second_usd by a constant will quote promotional and premium models wrong, silently, and only where being wrong costs money.

Permalink to fetch-one-modelFetch one model

bash
curl https://hypit.ai/v1/models/nano-banana-pro \
  -H "Authorization: Bearer $HYPIT_API_KEY"

Model ids may be namespaced with a slash, and the route handles that intact:

bash
curl https://hypit.ai/v1/models/bytedance/seedance-2 \
  -H "Authorization: Bearer $HYPIT_API_KEY"

The response is a single model card — the same object as one element of data above. A model your key cannot route to answers 404 with code model_not_found, which is the same answer an unknown model gets: the catalogue does not confirm that a model exists but is out of your reach.

Permalink to the-public-rate-cardThe public rate card

There is one unauthenticated endpoint, for pricing pages and for evaluating hypit.ai before signing up:

bash
curl https://hypit.ai/api/hub/public/models
json
{
  "object": "list",
  "count": 18,
  "modalities": { "image": 7, "video": 9, "chat": 2, "audio": 0 },
  "updated_at": 1787824589,
  "data": [
    {
      "name": "bytedance/seedance-2",
      "modality": "video",
      "endpoints": ["videos"],
      "pricing": { "mode": "per_second", "unit": "per second", "currency": "usd", "credits": {} }
    }
  ]
}

Note the differences from /v1/models: the model is keyed name rather than id, there is a unit string spelling out what the headline number is charged per, and the envelope carries count, modalities and updated_at so a page can render "prices as of …" without walking the list. It also only ever shows the default routing group — your key may see more models on /v1/models.

It is rate limited to 60 requests per minute per IP, served from a pre-rendered snapshot with an ETag, and honours If-None-Match:

bash
curl -i https://hypit.ai/api/hub/public/models \
  -H 'If-None-Match: "ce323a…"'

Permalink to choosing-a-model-in-codeChoosing a model in code

python
import os, httpx

r = httpx.get(
    f"{os.environ['HYPIT_BASE_URL']}/models",
    headers={"Authorization": f"Bearer {os.environ['HYPIT_API_KEY']}"},
)
r.raise_for_status()

video = [m for m in r.json()["data"] if "videos" in m["endpoints"]]
for m in video:
    print(m["id"], m["pricing"]["credits"].get("per_second"), "credits/second")
js
const r = await fetch(`${process.env.HYPIT_BASE_URL}/models`, {
  headers: { Authorization: `Bearer ${process.env.HYPIT_API_KEY}` },
});
if (!r.ok) throw new Error(await r.text());

const { data } = await r.json();
for (const m of data.filter((m) => m.endpoints.includes("videos"))) {
  console.log(m.id, m.pricing.credits?.per_second, "credits/second");
}