# QVeris authentication and trial lifecycle

Agent entry: [Executable quick start](/plugins/agent.md) — start with a public Discover request, then explicitly activate a bounded trial only when authorized execution is needed.

For human operators, [get started on the website](/playground) or [connect your AI](/plugins) with a formal account. The [Agent trial instructions](/try) provide a copyable handoff; reading or copying them creates no account or credits.

## Choose an existing access path

- **OAuth:** compatible Hosted MCP clients discover authorization from their endpoint and open browser sign-in. CLI users run `qveris auth login`. No API key needs to be copied; authorization is still required. See the [MCP guide](/docs/mcp-server) and [CLI guide](/docs/cli).
- **Existing API key:** supply `QVERIS_API_KEY` privately to the CLI/SDK, or `Authorization: Bearer …` to REST and compatible MCP clients. `qveris login` accepts masked key input; it is distinct from OAuth login. A configured key takes priority over a stored CLI OAuth session. Create/manage keys at [Dashboard / API Keys](/account?page=api-keys).
- **Agent without credentials:** choose explicit public read-only REST for Discover/Inspect only, or explicitly opt into the separate anonymous Agent registration API below. Do not create identities automatically during Discover, installation, or diagnostics.

The API base for this site is `https://qveris.ai/api/v1`. Use this site's endpoint consistently; credentials do not select a different endpoint. Discover is free; the default authenticated path requires valid credentials. Browser trial controls and Agent API credentials are separate access paths. Neither grants unauthenticated MCP access.

## Explicit public read-only REST

For public Discover/Inspect only, use a separate uncredentialed REST client with `X-Qveris-Access-Mode: public-readonly` on `POST /search` or `POST /tools/by-ids`. This does not register an identity, grant credits, execute a tool or authorize Call. See the [REST guide](/docs/rest-api) for input limits and examples. OAuth remains the default Hosted MCP path; local tool listing is not successful unauthenticated Discover.

Do not combine public mode with any Authorization, Cookie or session proof: the result is `400 access_mode_conflict`, including for invalid/empty credentials or unrelated cookies. A client with configured credentials must report the conflict rather than silently drop them. Browser HTTP uses `credentials: "omit"` with no Authorization interceptor. Without the explicit header, ordinary authentication still applies; a bad key never downgrades to public access. Invalid mode/body is `422`; an oversized body is `413`. On `401`, authenticate for the intended operation. On `429`, honor `Retry-After` and a bounded read retry budget; do not issue a trial or rotate credentials to bypass limits.

Public results omit prices, balance and personal data; `public-readonly-v1` identifies the restricted projection. A `pub_` search context is correlation only. To continue with Call, authenticate explicitly, retain the selected tool/input intent and refresh Inspect, permissions and any necessary quote before confirming cost. Never pass public context as Probe/Call authority. An already selected tool does not require another Discover solely to upgrade authentication. CLI/SDK instructions must match a published supporting version; no new client flag or constructor is implied here.

## Explicit read-only Hosted MCP

The separate Hosted MCP path is `/mcp/readonly` by default, on the same Hosted MCP origin as the authenticated endpoint. Use the [MCP guide](/docs/mcp-server) for the correct endpoint. The default `/mcp` OAuth flow and valid-key fallback remain unchanged. Only canonical `discover` and `inspect` are available on the read-only path; no Probe, Call, audit/history, ledger, execution lookup, aliases or resources are exposed. This mode creates no account, trial grant or persistent MCP session.

Use a separate uncredentialed remote connection. A present Origin must be explicitly allowed; native clients without Origin do not require browser-origin configuration. Authorization, Cookie, session/receipt proofs, query strings and any `Mcp-Session-Id` are rejected, including authenticated session IDs. Do not silently discard configured credentials. The endpoint accepts bounded JSON POST, not GET/SSE or DELETE; verify the client's behavior for this mode rather than assuming all remote clients work. Limits are 8192-byte requests, 512-KiB serialized responses and 15-second total lifetime. On `429`, follow returned retry guidance; proxy/common-egress clients may share limits, which are not a per-person allowance.

To Call, explicitly switch to an authenticated connection and recheck the selected tool's Inspect, permissions and any necessary quote before consent. Omit the old public search_id from authenticated Inspect and use its fresh result. Public context is not execution authority. The local MCP package keeps its authenticated setup. Separate explicit public clients are documented in the [CLI guide](/docs/cli) (`--public-read-only`), [TypeScript SDK guide](/docs/js-sdk) (`Qveris.publicReadOnly()`) and [Python SDK guide](/docs/python-sdk) (`PublicDiscoveryClient`). Keep their credential-free configurations separate from authenticated clients.

## Bounded Agent trial (explicit opt-in)

Use an existing valid API key or OAuth session first. With no credentials, public Discover/Inspect is enough until execution is required. Only under explicit trial permission, use published CLI **0.13.1 or later** with `qveris auth trial --bounded`, after checking registry availability and endpoint support. An unsupported endpoint fails explicitly; it must not fall back to legacy registration. The CLI privately persists the original operation before networking and protects existing credentials. Bare `auth trial` remains legacy compatibility with different rules.

For a direct API client, the paths below are relative to `https://qveris.ai/api/v1`:

1. Generate 32 cryptographically random bytes as an unpadded base64url possession token (43 characters). Persist it in private durable credential storage **before** networking. Do not use an API key, website login token, cookie or an existing legacy claim code as this proof.
2. Explicitly `POST /agent/trial/prepare`, then `POST /agent/trial/activate` with optional `{"agentName":"my-agent"}`. Use `Authorization: Bearer <possession token>`; omit cookies, query parameters and browser session headers. Preparation creates no account or grant. Activation returns the actual `trialCredits`, `expiresAt`, and, only on first issuance, `agent_id` and `api_key`. Require a success envelope and save the one-time key privately before continuing. Never print the response into agent context or logs.
3. Use the issued **API key** for ordinary authenticated REST, MCP or SDK operations; possession proof is not an API key. The issued subject's budget applies to native Calls. Alternatively the explicit `/agent/trial/quote` and `/agent/trial/execute` adapter uses possession proof plus signed `quoteConfirmation` and the original operation ID. Read the [quote reference](/docs/api-reference/agent-trial-quote) and [execution reference](/docs/api-reference/agent-trial-execute) for exact payloads. Quotes never execute a tool. Anonymous access excludes the model gateway.
4. With original issued G, confirmed consumption D and fresh exact quote q, admission requires q≤G, D<G and D+q<2G. The server permits one unresolved execution and rejects unsupported pricing or settlement paths. This envelope is not extra credits or a hard cap on final supplier charges. Actual overrun remains real debt; inputs and cost must be authorized before execution.
5. After a lost registration response, query `GET /agent/trial/session` with the **same saved proof**. Do not create a replacement identity. An active session does not re-export the one-time API key. Preserve the proof for safe claim/recovery if the key was lost. Unknown Calls require original operation/execution lookup, not resubmission; an empty lookup alone does not prove cancellation.

### Human claim handoff

Give the human only the safe [claim page](/claim?mode=bounded) link, then transfer the possession proof through a private channel. **Never embed proof in a URL, prompt or analytics event.** The human privately enters it on the page, verifies a new account with email/password or signs into the intended existing account, reviews the target and confirms. Never request a human password, email code or primary website login token in Agent context. Receipt reads use `GET /agent/trial/claim`; the Agent must not automate human account verification.

Claim requires no pending/unknown execution. Confirmed debt does not block claim: formal credits automatically repay it after transfer and any shortfall remains debt. Claim returns transferred grant, trial debt, repayment and remaining debt, including pre-existing receiver debt. It grants no duplicate welcome credits or extra lifetime, revokes the trial key, and does not create a website login session. Continue with explicit formal credentials and recheck the selected tool's permissions and any necessary quote. Keep existing task context; another Discover is not mandatory solely to change identity. Read receipts and original history in [Saved trials](/account?page=saved-trials). A lost claim response must be recovered before another claim; an unclaimed lookup is not proof that an earlier request was cancelled.

The older Agent endpoints below remain compatible and have different claim semantics. Do not silently replace a saved legacy trial or describe its policy as the bounded contract.

## Browser trial: recover existing work

Existing browser trials remain available through their original saved links and **Continue an existing browser trial** controls. A missing session does not offer fresh browser registration here. Humans should use normal website signup; Agents should follow the bounded path above. Opening recovery controls never executes a Call.

This section applies when the page displays browser trial controls. If an action is unavailable, do not bypass it with a private endpoint or create another trial. Reading this guide, viewing a page or preparing a session does not issue trial credits; starting a trial requires an explicit action.

The browser keeps an opaque, HttpOnly session cookie. It does not receive an API key or an Agent claim code. Do not try to extract that cookie or copy browser credentials into an SDK, CLI, prompt or shared configuration. Use the issued allowance and absolute expiry displayed for this trial. A later change to the default allowance does not add credits or extend an existing trial.

### Review and confirm one Call

Discover or inspect a tool, enter the real parameters, and request a quote. Only supported tools with an exact quote can proceed. Review the tool, inputs and quoted credits before explicitly confirming the Call. Changing the inputs or identity, an expired confirmation, or a higher fresh quote requires another review. A quote confirmation does not reserve funds or lock the provider's price. An unavailable action or positive displayed balance is not permission to execute.

The server checks execution eligibility against the original issued allowance. A tolerance of twice that allowance is an admission boundary, not a second grant, extra available balance or a hard cap on final provider cost. Confirmed overrun becomes debt. An unexpected actual-price difference remains unresolved until reconciled; do not treat it as extra trial credit.

A returned tool result and final settlement are separate. A successful result may still be awaiting settlement. After a timeout, cancelled wait, lost response or unknown outcome, preserve the original operation and use the page's recovery controls. Stopping the wait does not undo a submitted Call. Even a “not found” lookup does not prove that an earlier uncertain request never executed. Do not automatically submit again, generate another operation or start a replacement trial. Refresh the server's execution state after reconciliation before another Call.

### Keep work through browser claim

When claim controls are available, choose new-account verification or continue with the existing account that should receive the trial, signing in if needed. An email address alone cannot select or prove ownership of an existing account. Pending or unknown execution must be reconciled before claim; confirmed debt is handled separately.

Claim transfers the remaining original trial grant to the receiving account, or retains it during new-account conversion, without a second welcome/trial grant or an extended grant expiry. Confirmed debt is retained and automatically repaid from the formal account's available credits. Insufficient credits do not prevent claim: the remaining debt stays outstanding under the account's normal rules. There is no automatic cash charge or platform write-off. The receipt's repayment and remaining-debt amounts include any debt already held by the receiving account. Transferred credits describe the grant moved before repayment, not the final spendable balance.

Claim revokes the old trial keys and retires trial execution authority. Its receipt is not a login token. Continue with the formal account explicitly and refresh identity and permissions. Refresh an old discovery context with Discover; if a specific tool is already selected, recheck its inputs, permissions and quote instead of searching again. Reuse a valid formal-account session; sign in only if needed.

Open [Saved trials](/account?page=saved-trials) in Account to read receipts and original execution/search history summaries, up to 10 records per page. This entry uses the verified receiving account and remains accessible after closing the trial panel or clearing its local reference; no trial cookie is required. Records keep their original attribution and are not automatically merged into the receiving account's ordinary usage list. Original provider response bodies are not shown.

If the claim response is lost, recover its receipt before attempting another claim or clearing the session. A claimed session can recover the receipt, but cannot execute or issue more credits. If its cookie is already gone, continue with the verified receiving account, signing in if needed, and use account recovery for that trial. Do not repeat signup or infer success from an email, an expired cookie or a missing receipt. Ending a trial is distinct from claiming it and does not create a formal account.

## Check Agent API trial terms without creating an account

```bash
curl --fail-with-body --silent --show-error https://qveris.ai/api/v1/meta
```

Read `registration.available`, `trial_credits`, `expires_in_days`, `capabilities`, `excluded`, and the registration/claim paths. Metadata describes current issuance policy. The successful registration response's `data.trial_credits` and absolute `data.expires_at` are authoritative for that issued trial; do not hardcode a promotional allowance or extend its expiry from cached docs. Credits are accounting units, not a promise about supplier cost. Anonymous trials exclude the model gateway. Calls remain subject to capability permissions, balance and billing rules; begin with one Discover and review inputs/cost before Call.

## Legacy Agent API anonymous registration (compatibility)

Submit `POST https://qveris.ai/api/v1/agent/anonymous-register` with JSON `{"agent_name":"my-agent"}` (the name is optional). This action creates a trial identity. Check both HTTP status and the API envelope: require `status: "success"` and a non-null `data` object before consuming credentials.

The response contains `agent_id`, `agent_name`, `api_key`, `claim_code`, `trial_credits`, and `expires_at`. **The API key is shown once.** Capture the response directly into secure storage; do not print it into agent context, terminal transcripts or CI output. Save the claim code securely too. Do not put either secret in URLs, prompts, analytics, logs, public configuration or version control. Public summaries should contain only necessary non-secret status, expiry and allowance fields; redact keys, tokens, claim codes and personal data.

Use the issued key in the Authorization header for subsequent authenticated API requests. Save it before continuing: registration is rate-limited and repeated issuance can be rejected. If the response was lost, do not blindly repeat registration or assume you can recover the same key. Report the uncertain issuance and follow the returned error guidance. Never create a second trial to bypass expiry or limits.

## Review costs and recover uncertain execution

A free Discover, Inspect or Probe response does not authorize a paid Call. A Probe quote is not a reserved price or a hard spending cap. Check the selected tool’s billing rule and confirm the real inputs and acceptable cost before submitting. Output limits such as `max_response_size` limit response size, not spending.

For an uncertain outcome, retain the original execution ID and idempotency key where the client provides them. Use the [execution lookup reference](/docs/api-reference/reconcile-call), usage history and the final credits ledger to reconcile. A timeout, an expired login or a missing final ledger entry is not evidence that the provider did no work or that nothing will be charged. Do not replay a paid Call to test whether it completed. After changing identity, refresh identity and permissions. Refresh an old discovery context with Discover; for an already selected tool, recheck inputs, permissions and the quote before executing.

## Claim a legacy Agent API trial before expiry

Open the [claim page](/claim), or use the existing API flow:

1. `POST https://qveris.ai/api/v1/agent/claim` with `claim_code` and `email`; the server sends a six-digit email verification code.
2. `POST https://qveris.ai/api/v1/agent/claim-verify` with the same `claim_code`, `email`, and `code`.

Check the success envelope on both steps. This Agent API flow requires an active, unexpired trial and valid email verification. The email cannot already belong to a formal account: the current flow does not merge trial assets into an existing account. Claim converts the trial into a formal account and keeps its existing API key active; it does not return a browser login session. Complete the normal sign-in flow separately. Do not assume another signup allowance is granted by claiming.

Unclaimed trials expire at the issued `expires_at`; their trial keys are revoked. Save needed work and claim in time. A rejected/expired credential must surface an authentication error, never silently become anonymous access. For unknown Call outcomes, keep the execution ID and reconcile [usage and final charges](/docs/rest-api) before retrying. Never automatically replay a paid Call.
