Authentication
Every request to Proxyify must be authenticated with an API key passed in the Authorization header.
API keys
API keys are created from Dashboard → Keys. Each key:
- Is shown only once at creation — copy and store it securely
- Is stored as a SHA-256 hash on our servers — not in plaintext
- Is scoped to your account's credit balance
Never expose a prx- key in client-side code. Use ephemeral tokens for browser environments.
Bearer header
Pass your key in the standard HTTP Authorization header:
Authorization: Bearer prx-xxxxxxxxxxxxxxxx
When using the OpenAI SDK, pass the key as api_key — the SDK handles the header automatically:
client = OpenAI(api_key="prx-xxxxxxxxxxxxxxxx", base_url="https://proxyify.dev/v1")
Key restrictions
Every restriction is optional. When not set, no restriction applies. Restrictions can be set at creation time or edited later from the key's Settings modal.
| Restriction | Description |
|---|---|
expires_at | Key TTL — automatically deactivates after this datetime |
allowed_models | Allowlist of model slugs (e.g. ["openai/gpt-4o"]). Empty = all models allowed |
allowed_categories | Restrict to modalities: text, image, video, stt, tts |
allowed_ips | IP allowlist — supports CIDR notation (e.g. 10.0.0.0/24) |
allowed_origins | Origin/Referer allowlist (e.g. myapp.com, localhost) |
blocked_countries | ISO country codes to block (e.g. RU, CN) |
active_hours | Time window in UTC, e.g. 09:00-18:00 — requests outside are rejected |
spending_limit | Maximum credits this key can spend per period |
spending_period | daily / weekly / monthly |
webhook_url | URL to POST when credit threshold or rate limit is exceeded |
Security chain
Every incoming request passes through these checks in order. The first failure returns immediately:
| # | Check | Error |
|---|---|---|
| 0 | Account is active, not banned or suspended | 403 |
| 1 | Key exists, is active, TTL has not expired | 401 |
| 2 | Request is within active_hours window | 403 |
| 3 | Caller IP is in allowed_ips | 403 |
| 4 | Origin / Referer is in allowed_origins | 403 |
| 5 | Caller's country is not in blocked_countries | 403 |
| 6 | Requested model is in allowed_models / allowed_categories | 403 |
| 7 | No prompt injection pattern detected | 400 |
| 8 | Rate limit (RPM / RPD) not exceeded | 429 |
| 9 | Key spending limit not reached | 402 |
| 10 | Account has sufficient credits | 402 |
Rate limits
Rate limits are applied per account, not per key. RPM = requests per minute, RPD = requests per day.
| Plan | RPM | RPD |
|---|---|---|
| Free | 20 | 200 |
| Starter | 100 | Unlimited |
| Pro | 300 | Unlimited |
| Scale | Unlimited | Unlimited |
When a rate limit is exceeded the response is 429 with a Retry-After header indicating when the limit resets.