/Websites and apps

Rules and limits

Websites and apps

Use a key from web pages and mobile apps: allowed websites, limits for each visitor and user, and short-lived keys.

Anything a web page or an app ships to a visitor can be read by that visitor, keys included. Vallkey keeps the real key on its side either way; these rules decide what a copied ghost key can still do.

Allow your websites

By default a key refuses requests from web pages, so a key meant for a server never works in a browser. Turn on Websites (browsers) in the key's rules and list the websites whose pages may use it:

Allowed websites
https://app.acme.comhttps://*.acme.com      # every subdomain of acme.comhttp://localhost:3000   # while you develop
  • Requests from any other website are refused, with the reason in Activity. Requests from your servers, which name no website, are not affected.
  • *.acme.com covers your subdomains, not acme.com itself. Wildcards on hosts many people share, such as *.vercel.app, are refused: list your exact address instead.
  • http:// only works for localhost. Adding a website lets browsers in, so it waits for the safety delay like any loosening; removing one applies at once.

Then call the API from the page as usual, with the ghost key and Vallkey's address. The official SDKs ask you to confirm browser use:

In the browser
1import OpenAI from 'openai';2 3const openai = new OpenAI({4  apiKey: 'gk_openai_...',               // a ghost key with your website allowed5  baseURL: 'https://api.vallkey.com/v1',6  dangerouslyAllowBrowser: true,         // the SDK's own check: safe here, the real key is not in the page7});

Limit each visitor

A website list stops other sites from using your key in their visitors' browsers. It cannot stop someone who copies the key into a script and claims to be your site. So for anything that costs money, also set Limits for each visitor: how many requests one visitor (one IP address) may make per minute and per day, on top of the key's own limits. Visitors on IPv6 count per connection (a /64), so changing address does not help.

Note

Keep the key's own daily caps too, such as an AI budget or a daily request limit: they are the ceiling for everyone together. Whatever happens, a copied key can never cost more than that.

Short-lived keys

The safest way, and the way for mobile apps: the ghost key stays on your server, and your server makes a short-lived key for each signed-in user. The page or app uses that one. It expires in minutes, can only do what the ghost key allows, and can be limited per user.

Your server
1const res = await fetch('https://api.vallkey.com/_vallkey/v1/session-keys', {2  method: 'POST',3  headers: { authorization: `Bearer ${process.env.VALLKEY_GHOST_KEY}`, 'content-type': 'application/json' },4  body: JSON.stringify({ user: user.id, ttl_seconds: 900 }), // after your own sign-in check5});6const { session_key, expires_at } = await res.json(); // send session_key to the page or app

Or with our packages, which read the ghost key from VALLKEY_GHOST_KEY:

Node.js (npm install vallkey)
import { createSessionKey } from 'vallkey/session'; const { session_key, expires_at } = await createSessionKey({ user: user.id, ttlSeconds: 900 });
Python (pip install vallkey)
from vallkey.session import create_session_keysession_key = create_session_key(user=user.id, ttl_seconds=900)["session_key"]

Then the page or app uses session_key exactly where the real key would go, with Vallkey's address. When it expires, it asks your server again.

FieldWhat it does
userYour own id for the person, up to 128 characters. Use an id, not an email. Limits for each user and blocking use it, and Activity shows it.
ttl_secondsHow long it works: 60 to 86,400 seconds (one day). 900, fifteen minutes, if left out.
allowOptional: only some of the ghost key's endpoints, such as [{ "method": "POST", "path": "/v1/chat/completions" }].
modelsOptional: only some of the ghost key's AI models.
  • Only your server can make them. Making one needs the ghost key, and a request that comes from a web page is refused, so the ghost key never ends up in one.
  • They follow their ghost key. Killing, tightening or deleting the ghost key applies to every short-lived key at once; rotating it ends the ones it made.
  • Making more does not give more. Limits for each user (per minute, per day, and an AI budget) count across all of a user's short-lived keys.
  • Stop one person. Open one of their requests in Activity and choose Block this user: their keys stop at once, and nobody else is affected.
  • Up to 600 can be made a minute for each ghost key. The Free plan makes up to 1,000 a day for each ghost key; paid plans have no daily cap. Making them is free.

Note

Strangers cannot make short-lived keys, but they can sign up to your app. Protect your own sign-up (an email check, a captcha), and keep limits for each user and the key's daily caps on: together they make the worst case small and known.

Still have a question?

We read every email, usually within a day.

Contact support