--- title: "VLM Run Authentication" description: "How agents obtain a VLM Run API key and where to use it." --- # VLM Run Authentication Agents can create an account, or authorize an existing account, over HTTP. The human supplies an email and agrees to the terms. Read the six-digit code from their inbox when a mail tool is already connected to that address; otherwise ask them for it. Signup does not use a browser. | Surface | URL | | --- | --- | | Signup API | `https://prod-vlm-cloud-nfsnfpr33q-uc.a.run.app` | | Inference API | `https://api.vlm.run` | | Studio | `https://app.vlm.run` | | Signup OpenAPI | `https://prod-vlm-cloud-nfsnfpr33q-uc.a.run.app/api/v1/agent/openapi.json` | The CLI, the gateway skill, and the website examples read `VLMRUN_API_KEY` from the process environment. They do not load a `.env` file on their own. ## 1. Check for a saved key Look in the approved secret store or the process environment. Do not print the key. If `VLMRUN_API_KEY` is set, check it: ```bash curl -sS "https://api.vlm.run/v1/models" \ -H "Authorization: Bearer $VLMRUN_API_KEY" ``` - **200:** the key works. Setup is done. Continue at [Use the key](#5-use-the-key). - **401** `Missing Authorization bearer token`: `VLMRUN_API_KEY` is empty in this shell. Export it and retry. - **403** `Invalid API Key`: the saved key is wrong. The human can copy a key from [Studio](https://app.vlm.run), or approve a new key for their existing email in the steps below. `https://api.vlm.run/v1/openai/models` returns 200 with no key. Do not use it as a credential check. ## 2. Request a verification code If there is no working key, ask for the human's email. POST JSON (`Content-Type: application/json`) to `https://prod-vlm-cloud-nfsnfpr33q-uc.a.run.app/api/v1/agent/accounts`: ```json {"email":"ada@example.com"} ``` A 200 response is: ```json { "signup_token": "", "account_status": "new", "expires_in_seconds": 600, "message": "Verification code sent to your email. Valid for 10 minutes." } ``` `account_status` is `"new"` or `"existing"`. An existing account gets a message that the code authorizes a new API key. This call does not create an account and does not issue a key. Keep `signup_token` private. The code expires in 10 minutes. Wait 60 seconds before requesting another code for the same email. On HTTP 429, wait `detail.retry_after` seconds. A new request returns a new `signup_token`. Use the latest token. The previous token stays valid until it expires, is used, or runs out of attempts. ## 3. Read the code, then ask the human once If a mail tool is already connected to this address, read the message that arrived after the request: - New account subject: `Verify your email for VLM Run` - Existing account subject: `Authorize AI assistant for your VLM Run account` - Code line: `vlm-verification-code: 849201` Use that code only. Do not print the code. If you cannot read that inbox, ask the human for it. If the first and last name are already known, use them. Never invent a name. Both fields are optional when the human does not provide them. Ask, in one question, for anything still missing and for terms agreement: Do you agree to the [terms of service](https://vlm.run/terms-of-service) and acknowledge the [privacy policy](https://vlm.run/privacy)? Agreeing authorizes account creation, or a new API key on the existing account, and delivery of that key to this assistant. Terms agreement always requires an explicit answer from the human. Do not infer consent from the code, from a prior session, or from silence. When `account_status` is `"existing"`, the code authorizes a new API key on the current organization. It grants no credits. ## 4. Verify the code and receive the key POST JSON to `https://prod-vlm-cloud-nfsnfpr33q-uc.a.run.app/api/v1/agent/accounts/verify`: ```json { "signup_token": "", "code": "849201", "first_name": "Ada", "last_name": "Lovelace", "terms_accepted": true } ``` Send the code as a string. Send `terms_accepted: true` only after the human agrees. Omit `first_name` and `last_name` when they were not provided. HTTP 200 for a new account: ```json { "api_key": "", "api_key_id": "", "organization_id": "", "credits_granted_dollars": 0.5, "account_status": "new", "studio_url": "https://app.vlm.run", "message": "Account created successfully." } ``` An existing account returns the same fields with `"account_status": "existing"` and `"credits_granted_dollars": 0`. Do not print this response or paste the key into chat. Save `api_key` as `VLMRUN_API_KEY` in the process environment or the approved secret store. Never commit it or place it in a URL. ```bash export VLMRUN_API_KEY="" ``` Tell the human the account is ready. Do not display the key. - **New account.** No password was set. The code only verified the email. $0.50 in trial credit is active. Sign in at `studio_url` (https://app.vlm.run) and choose "Email me a sign-in code" to receive the rest of the welcome credit. - **Existing account.** A new API key was issued for the existing organization. No additional credits were granted. The same Studio sign-in is available at `studio_url`. ## 5. Use the key Confirm the saved key before calling the product: ```bash curl -sS "https://api.vlm.run/v1/models" \ -H "Authorization: Bearer $VLMRUN_API_KEY" ``` A 200 response means the key works. Stop and fix auth if it does not. | Task | Follow | | --- | --- | | Orion CLI for images, video, and documents | https://vlm.run/SKILL.md | | Gateway: parse, chat, embeddings, transcription | https://vlm.run/gateway/SKILL.md | | Docs index | https://docs.vlm.run/llms.txt | | Machine-readable skill index | https://vlm.run/.well-known/agent-skills/index.json | Share results with the human. Do not share the key. ## Signup errors Signup responses are JSON and send `Cache-Control: no-store`. The error body is `{"detail":{"code":"...","message":"..."}}`. `detail.field`, `detail.retry_after`, `detail.attempts_left`, and `detail.studio_url` are present when they apply. Show `detail.message` and `detail.field` when present. | HTTP | `detail.code` | Agent action | | --- | --- | --- | | 400 | `invalid_input` | Show the field and message. Ask for a corrected value. Send `terms_accepted: true` only after the human agrees. | | 400 | `invalid_code` | Re-read the inbox once for `vlm-verification-code`. If it matches the code you sent, ask the human. Do not guess. `detail.attempts_left` is how many tries remain. | | 400 | `inactive_account` | Stop automated signup. Show the message and `detail.studio_url`. | | 404 | `invalid_token` | The token is unknown or already used. Request a new code after the 60 second cooldown. | | 410 | `verification_expired` | The code expired, or three incorrect attempts were used. Request a new code after the cooldown. | | 422 | | The JSON body was rejected. Ask for a corrected email or body. | | 429 | `cooldown_active` | Wait `detail.retry_after` seconds, then request a new code. | Three incorrect codes are allowed. The third failure returns HTTP 410. Revoke or replace keys in [Studio](https://app.vlm.run).