# auth.md You are an agent that wants to call the DeployHQ API on a user's behalf. This file describes how to obtain credentials and how to handle them safely. Three hosts are relevant: - **Resource server** -- `https://{account}.deployhq.com` -- the API you will call. Every DeployHQ account has its own subdomain; you must know the account name to address it. - **Dashboard** -- `https://www.deployhq.com` -- where the user manages their account. - **Identity provider** -- `https://identity.deployhq.com` -- the OAuth 2.0 authorisation server used for "Log in with DeployHQ" integrations. Discoverable via `https://www.deployhq.com/.well-known/oauth-authorization-server`. ## Current state DeployHQ supports agentic registration. You can create a new account on a user's behalf via `POST /api/v1/signup` on `api.deployhq.com` and receive working API credentials in the response. You can also use credentials a user has already issued -- both flows are described below. ## Use the existing tooling first Before you do anything credential-shaped, check whether the user has already wired DeployHQ into your environment. 1. **DeployHQ MCP server** -- if you are an MCP client (Claude Desktop, Claude Code, Cursor, Codex, etc.), DeployHQ ships an official MCP server that exposes projects, deployments, servers, build pipelines, and more as tools. The user configures it once with their account and key; you call the tools without ever seeing the key. Repository: `https://github.com/deployhq/deployhq-mcp-server`. Discovery: `https://www.deployhq.com/.well-known/mcp/server-card.json`. 2. **DeployHQ CLI** -- if you are running shell commands, prefer `deployhq` over hand-rolled `curl`. It resolves account + credentials, handles retries, and exposes non-interactive flags. Install: `https://deployhq.ai` (one-liner installer with content negotiation for agents). Repository: `https://github.com/deployhq/deployhq-cli`. 3. **Agent landing page** -- `https://deployhq.ai` serves Markdown by default to agents and HTML to browsers. It walks an agent through CLI install + first deploy in one document. 4. **Site index for agents** -- `https://www.deployhq.com/llms.txt` and `llms-full.txt` enumerate every public URL on the marketing site, including support articles and guides. If any of these is already configured, use it and stop. Do not ask the user for credentials you do not need. ## Login options ### Option A -- Agentic signup (preferred for new users) If the user does not already have a DeployHQ account, you can create one for them. There is no authentication required for this endpoint; it is rate-limited per IP, per email, and globally. ```http POST /api/v1/signup HTTP/1.1 Host: api.deployhq.com Content-Type: application/json { "email": "user@example.com", "password": "{secure-password-the-user-supplies}", "terms_accepted": true, "account_name": "acme-engineering", "full_name": "Engineer Person", "package": "pro", "signup_source": "claude-code", "client": "claude-code" } ``` Field notes: - `email`, `password`, and `terms_accepted: true` are required. - `account_name` is auto-generated from the email if you omit it; the user cannot change it later, so confirm it with them before sending. - `package` defaults to `pro`; pass `business` or `enterprise` if the user has asked for it. - `client` is for attribution -- set it to your tool name (`claude-code`, `cursor`, `codex`, `your-agent-name`). Including it helps DeployHQ understand which agents drive signups. - **Never invent a password.** Have the user supply it through whatever secret-passing mechanism your environment provides (`.env`, MCP config, CLI flag). The user is the one signing the terms; they are the one who chooses the credential. The response (`201 Created`) returns an `AccountApiKeySshPublicKeyObject`: - The **API key** for HTTP Basic auth (see Option B below). - The **SSH public key** for the account. Add it as a deploy key on every repository the new account should pull from. - The **account subdomain** to use as the API host. After signup, switch to Option B for all subsequent API calls. Rate limits: signup is throttled per IP, per email, and globally. A `429` means slow down; honour `Retry-After`. A `403` means the request was blocked (suspicious pattern, banned IP, disposable email domain). ### Option B -- User-supplied API key (HTTP Basic auth) The DeployHQ API authenticates with HTTP Basic. The user issues an API key from their account dashboard (Settings -> API) and supplies it to you through a secure channel -- never by pasting it into chat. #### How to pick credentials up You need two values: the **account subdomain** and the **API key**. Look for them in this order. Stop at the first source that has both: 1. `--account` and `--api-key` flags on the `deployhq` CLI, if the user passed them for this invocation. 2. `DEPLOYHQ_ACCOUNT` and `DEPLOYHQ_API_KEY` in your process environment. 3. A project `.env` file the user has told you to read. 4. The user's CLI config, populated via `deployhq login` (used automatically when you invoke the `deployhq` CLI). 5. The MCP server's environment, if you are calling through it. If none of the above is set and you genuinely need credentials, **do not ask the user to paste them into the conversation**. Instead, tell them to: - Issue an API key from `https://{account}.deployhq.com/settings/api`. - Put it in `DEPLOYHQ_ACCOUNT` and `DEPLOYHQ_API_KEY` in their shell, `.env`, MCP client config, or `deployhq login` -- whichever matches how they invoke you. - Resume the task once it is set. This keeps credentials out of your transcript, out of any logs the user shares, and out of the model provider's training data. #### How to use the key Present the API key as HTTP Basic credentials. The username is the DeployHQ login email address and the password is the API key: ```http GET /projects.json HTTP/1.1 Host: {account}.deployhq.com Authorization: Basic {base64(email + ":" + api-key)} Accept: application/json ``` Read both values from the environment at the moment of the call. Do not copy them into variables you log, do not echo them back to the user, do not include them in commit messages, PR descriptions, error reports, or screenshots. If you are running a shell command, never interpolate them inline -- reference the environment variables so they do not appear in command history. API keys do not expire on their own. Treat a `401` on a previously-working key as revocation: drop it from memory and ask the user to refresh whichever source you read it from. ### Option C -- OAuth 2.0 (for "Log in with DeployHQ" integrations) If you are building an integration where a DeployHQ user authorises a third-party application (rather than an agent calling the API on a user's behalf), use the OAuth 2.0 authorisation code flow. - **Authorisation endpoint:** `https://identity.deployhq.com/oauth/authorize` - **Token endpoint:** `https://identity.deployhq.com/oauth/token` - **Token endpoint auth method:** `client_secret_post` - **Grant type:** `authorization_code` - **Scopes:** `email_address`, `assignments` You must register your application with DeployHQ to receive a `client_id` and `client_secret`; contact `support@deployhq.com` to start that process. Full discovery document at `https://www.deployhq.com/.well-known/oauth-authorization-server`. This is **not** the right path for a coding agent that wants to deploy on a user's behalf -- use Option A or B for that. OAuth is for app-to-app integrations where the user is in front of a browser. ## Errors | Status | Meaning | What to do | | --- | --- | --- | | `401` on first use | Credentials are malformed, for the wrong account, or revoked. | Ask the user to confirm `DEPLOYHQ_ACCOUNT` and `DEPLOYHQ_API_KEY` in their secret store. Do not ask them to paste either into chat. | | `401` on previously-working credentials | Revoked or rotated. | Drop the cached value and ask the user to refresh it from the source you loaded it from. | | `403` | Credentials lack permission for this resource, or the account is suspended. | Check whether the user has the relevant permission in their account dashboard (Settings -> User Management). On signup, may indicate the request was blocked for fraud signals. | | `404` on the account subdomain | Wrong account name in the host. | Confirm `DEPLOYHQ_ACCOUNT` matches the account subdomain shown in the dashboard URL. | | `409` on signup | Account name or email already in use. | Ask the user whether they meant to sign up a new account or use an existing one. | | `422` on signup | Validation failed -- password too short, missing terms acceptance, invalid package. | Surface the per-field errors back to the user verbatim. | | `429` | Rate limited. | Back off and retry. Honour `Retry-After` if present. Signup is throttled aggressively; do not retry signup tightly. | | `503` on signup | Signup temporarily disabled. | Surface the message to the user; retry later. | ## Revocation The user revokes API keys from `https://{account}.deployhq.com/settings/api`. You will discover revocation as a `401` on a previously-working credential -- drop it and re-read from the source you loaded it from. Do not cache credentials beyond the lifetime of a single agent invocation. For OAuth tokens, revocation is per-grant in the user's authorised applications list on `https://identity.deployhq.com`. ## See also - API reference (OpenAPI 3.0): `https://api.deployhq.com/docs.json` - API documentation: `https://www.deployhq.com/support/api` - Agent landing page: `https://deployhq.ai` - Agent capabilities manifest: `https://www.deployhq.com/.well-known/agent.json` - MCP server: `https://github.com/deployhq/deployhq-mcp-server` - CLI: `https://github.com/deployhq/deployhq-cli`