Secrets and API connections
A page can't hold an API key (anyone can read page code) and may only fetch its own address. Instead:
- Secret: the key, stored encrypted (AES-256-GCM). Nobody can read it back: not you, not your assistant, not Ginta's screens.
- Connection: which API the site may call with it, and how the key is attached.
- The page calls
/_ginta/api/<connection>/<path>; Ginta adds the key and forwards the call to that API only.
// manage_secrets
{ "site_id": "my-app", "action": "set", "name": "WEATHER_API_KEY", "value": "<pasted by the user>" }
// manage_connections
{ "site_id": "my-app", "action": "save", "name": "weather", "base_url": "https://api.openweathermap.org/data/2.5",
"secret": "WEATHER_API_KEY", "auth": "query", "auth_name": "appid", "methods": ["GET"] }
// in the site's JavaScript
const r = await fetch("/_ginta/api/weather/weather?q=Kaunas&units=metric");
const data = await r.json();
auth: bearer (Authorization: Bearer …, the default), header with auth_name (e.g. X-API-Key), or query with
auth_name (e.g. appid). Prefer bearer or header: query keys end up in the API's own logs.
Owners see and manage both in the site's Settings → Advanced:

What Ginta enforces
- Only
https://APIs on public host names (no IP addresses, ports, local or internal names; DNS answers pointing to private networks are refused). The path can't leave the base URL. Redirects are never followed. - Only the site's own pages may call it (same origin; no CORS, other websites get 403).
- 1 MB per request, 2 MB per answer, 10 seconds. Cookies are never forwarded.
- The key is removed from the API's answer if it echoes it (
[hidden]), and never appears in pages, files, logs or tool output. - Limits: bursts per visitor and per site, and calls a month per site by plan (limits).
Important: anything a public website can call, its visitors can trigger. Use keys that are safe for that (read-only, limited at the API), never an admin key. Running your own server code per site is not available yet.