# Run an agent without signing in (/docs/agents/automation)



A coding agent in CI or a sandbox has nobody to approve `domino login`. Give it an **automation key** instead: an organization key that no person owns, so it keeps working when people leave. It can build, stage and test in the test environment of the projects you choose. Going live still needs a person in Console.

## Create a key [#create-a-key]

### 1. Open the API keys settings [#1-open-the-api-keys-settings]

In Console, open **Settings** → **API keys**. Only organization administrators see **Create an automation key**.

### 2. Choose what the agent may do [#2-choose-what-the-agent-may-do]

* **Projects:** **All projects**, which includes projects created later, or **Chosen projects**.
* **Permissions:** any of Read, Publish, Inventory, Points, Ingest and Enroll. Pushing code, staging and test members need Publish.
* **Create projects:** lets the agent start new projects on your plan. A key limited to chosen projects can also work on the projects it creates.
* **Expiry:** the key never expires unless you choose one.

### 3. Save the secret [#3-save-the-secret]

Select **Create automation key**. Console shows the secret once. Store it in your CI's or agent's secret settings as `RELAY_MANAGEMENT_TOKEN`, and keep it out of chat and source control.

> [!DEV]
> Automation keys start with `dak_`. Administrators manage them with `management.automationKeys` in the SDK (`list`, `create`, `addSecret`, `revokeSecret`, `revoke`), from a Console session only. The request body of `create` is `{ name, permissions, projects?, createProjects?, expiresInDays? }`; omit `projects` for every project.

## Use it [#use-it]

The CLI reads `RELAY_MANAGEMENT_TOKEN`, so the agent runs the usual commands:

```sh
export RELAY_MANAGEMENT_TOKEN=dak_...
domino whoami --json
domino create launch-week --template campaign --json
cd launch-week
npx --yes pnpm@10.34.5 install --frozen-lockfile
# make the changes and commit them
git push
domino stage
```

A project name uses letters, numbers, underscores and hyphens. Use the install command `domino create` prints in `packageManager.installCommand` if its pnpm version differs from this example.

`domino login --token-stdin` saves the key instead, for a machine that keeps a home directory. The Git credential helper `domino checkout` installs uses the same key, so `git push` to `git.domino.run` works without a password prompt.

> [!DEV]
> `domino whoami --json` prints `credential` for an automation key: `{ kind: "automation", id, name, projects, createProjects, permissions }`, where `projects` is `null` for every project. Audit history names the key as `automation:<id>`.

## What it can't do [#what-it-cant-do]

| Refused                                                                         | Answer                            |
| ------------------------------------------------------------------------------- | --------------------------------- |
| Any change in live, including drafts, previews and secrets                      | `403` `console-approval-required` |
| Managing people, roles, personal keys, projects' settings, deletion or transfer | `403` `credential-not-allowed`    |
| Creating any key or approving a CLI sign-in                                     | `403`                             |
| Creating a project without **Create projects**                                  | `403` `permission-required`       |
| A project it was not given                                                      | `403` `scope-mismatch`            |

It can read live data when it has Read. [What each credential may do in live](/docs/concepts/access#what-each-credential-may-do-in-live) compares it with the other credentials. Staging links it creates also open the [test toolbar](/docs/build/staging#try-quests-with-the-test-toolbar) when the key holds Publish and reaches the project, acting as the key: toolbar actions are audited as the key, and revoking the key, or the secret that created the link, ends the toolbar on its next request.

## Rate limits [#rate-limits]

Domino sets no general limit on how many management calls a key, a project or an organization makes. Test-member calls and attempt reads have no limit of their own, except linking a test member's X account by handle, which counts as an X handle lookup. This is today's behavior, not a promised throughput.

A few calls have their own limits, because each spends a shared outside quota or starts something costly. "Per caller" counts, within one organization, each person once, whichever session or personal key they use, and each automation, service or hosted app key on its own.

| Call                                                                                                                                           | Limit                                                                                                                                                                                                        |
| ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Looking up an X handle, including linking a test member's X account by handle                                                                  | 30 a minute per caller, 300 an hour per organization                                                                                                                                                         |
| [Previewing an X search](/docs/build/trackers#preview-an-x-search)                                                                             | 6 a minute per caller, 60 an hour per organization                                                                                                                                                           |
| [Adding, re-checking or removing a domain](/docs/build/hosted-app#use-your-own-domain)                                                         | 30 an hour per organization, together                                                                                                                                                                        |
| Starting `domino dev`                                                                                                                          | 10 a minute per caller                                                                                                                                                                                       |
| Sending feedback                                                                                                                               | 10 an hour per caller                                                                                                                                                                                        |
| Signing in with a personal key or an AI assistant connection that doesn't exist, such as a mistyped key (expired and revoked ones don't count) | 30 every 10 minutes per network address, counting a whole IPv6 /64 as one, on each Domino server; past it, personal keys and AI assistant connections from that address are refused until the 10 minutes end |

Any call can still be refused when Domino is busy. Wait as long as the answer asks before trying again. The CLI and the SDK already do this within each call's deadline. For a long run, such as a rehearsal with hundreds of test members, keep a fixed number of calls in flight and slow down when calls are refused.

> [!DEV]
> Past a limit, a call answers HTTP 429 with `code: "rate-limited"`. Any call can answer 429 or 503 with a `Retry-After` header when the wait is known; the CLI reports it as `details.retryAfter` in milliseconds. Give each write that takes an `actionId` a deterministic one, so a retry replays the first answer instead of applying the change twice. An action ID is 1–100 letters, digits, `_` or `-`; derive one as a hex SHA-256 of what makes the write itself, such as each record's ID and observation time (`sync-` followed by the hash), rather than joining IDs with `:`, which is refused with an error that names `actionId`. Responses carry no `RateLimit-*` headers. `domino reference automation` describes the CLI's retries.

## Rotate or revoke [#rotate-or-revoke]

To rotate, select **Add secret** on the key, move your CI to the new secret, then revoke the old one once its last use stops advancing. Both work until then. **Revoke** ends the key and every secret on the next request. Creating, rotating and revoking keys appear in each project's access history.
