Operations
What ATM exposes once it is running: per-token rate limits and sensors, global settings, the audit log, the events it fires, and the token-facing proxy routes. The admin API has its own reference.
Rate limiting
Every token has a sliding-window rate limit. The defaults are 60 requests per minute with a burst of 10 per second, both configurable per token. Setting rate_limit_requests to 0 disables rate limiting for that token. Pass-through tokens get the same default limits and are rate limited like any other token; the create dialog hides the inputs while pass-through is selected, so adjust them afterward on the token's detail page.
A rate-limited request returns HTTP 429 with a Retry-After header. Successful responses carry the current limit state.
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1712345678
If Notify on rate limit is enabled in global settings, Home Assistant raises a persistent notification when a token hits its limit, throttled to once per token per minute.
Telemetry & sensors
ATM creates six Home Assistant sensors for each active token. For a token named my_token:
| Entity | Reports |
|---|---|
sensor.atm_my_token_denied_count | Requests blocked by permission rules |
sensor.atm_my_token_expires_in | Days until expiry, or No expiry |
sensor.atm_my_token_last_access | Timestamp of the most recent request |
sensor.atm_my_token_rate_limit_hits | Times this token has been rate limited |
sensor.atm_my_token_request_count | Total requests made with this token |
sensor.atm_my_token_status | active, expired, or revoked |
Sensors are removed automatically when a token is revoked. ATM's own sensors are blocked from all token access, so an external tool cannot read its telemetry through ATM.
Global settings
| Setting | Default | Effect |
|---|---|---|
| Audit log flush interval | 15 min | How often the in-memory log is snapshotted to disk; set to "Never" to disable persistence |
| Disable all logging | Off | Suppresses all auditing |
| Kill switch | Off | When enabled at startup, ATM registers no client routes; enabling it at runtime makes the already-registered proxy, MCP, and skill routes refuse with 503 (HA cannot unregister them) |
| Log allowed requests | On | Record successful requests |
| Log client IP | On | Include caller IP in audit entries |
| Log denied requests | On | Record blocked requests and unsupported MCP methods |
| Log entity names | On | Include entity IDs in audit entries |
| Log rate-limited requests | On | Record rate-limited requests |
| Maximum log entries | 10,000 | Capacity of the buffer and on-disk snapshot; reducing it trims the oldest entries immediately |
| MESA mode | Advisory | Per-entity safety enforcement: off, advisory, or enforced. See MESA |
| Notify on approval | On | Raise an HA notification, with a deep link, when an action needs admin approval |
| Notify on rate limit | Off | Raise an HA notification when a token is rate limited |
| Token settings presets | Off | Lets each token save and switch named snapshots of its full configuration; enabling seeds every token with a preset of its current settings. See the panel guide |
| Theme | Auto | This changes how the panel looks for you and does not sync to other admins or devices |
Advanced token options
Two per-token options sit outside the capability matrix, in the panel's Tool Announcement card on the token detail page (and settable through PATCH).
- Always announce all tools
- Off by default: a token's
tools/listadvertises only the tools its capabilities unlock and hides the rest. Turn it on to advertise the full tool list regardless of gating. Calls are still gated, so this changes what a client sees, not what it can do. - Limit to Assist-exposed entities
- Pass-through tokens only, off by default. A pass-through token normally sees every non-ATM entity; enable this to additionally narrow it to the entities exposed to Home Assistant Assist. It is ignored for scoped tokens, which scope by the permission tree, so the toggle is disabled unless pass-through mode is on.
Audit log
ATM keeps a circular buffer of requests, viewable in the panel's audit tab or through the admin API. Each entry records a request ID (matching X-ATM-Request-ID), timestamp, token ID and name, method, resource path, outcome, and client IP.
| Outcome | Meaning |
|---|---|
| allowed | The request succeeded. |
| denied | Blocked by permission rules, the blocklist, or a RED / NO_ACCESS result. Includes permission-based 404s. |
| invalid_request | The request was structurally malformed and rejected before permission checks, for example a template with a syntax error. |
| not_found | The entity is genuinely absent from both HA state and the registry. Identical to denied for the caller, but distinguished here so you can tell a missing entity from a permission wall. |
| not_implemented | The client called an MCP method ATM does not support. A protocol gap, not a permission block; does not increment the denied counter. |
| rate_limited | The token exceeded its rate limit. |
| pending_approval | A capability set to Confirm queued the action for admin review instead of running it. Always recorded, even with logging toggles that would otherwise suppress it. |
The log is stored in .storage/atm_audit and survives restarts. It is included in HA full backups and in partial backups of .storage. ATM flushes on the configured interval and also on HA stop, reload, and unload. Set the interval to "Never" to keep the log in memory only.
Configuration history
Every agent-made create, edit, or delete of an automation, script, scene, helper, dashboard layout, the raw configuration.yaml, or a scoped file (under www/, themes/, custom_templates/) is recorded as a before/after snapshot, viewable in the panel's Changes tab or through the admin API. The most recent twenty versions per resource are kept, oldest evicted first, so history stays bounded without a sweep. A file or YAML snapshot larger than 100 KB is kept as a metadata-only marker and cannot be restored inline, so a large file cannot bloat storage. Snapshots are stored in .storage/atm_versions and survive restarts; the file is included in HA backups like the rest of .storage. The store is admin-only; restoring a version re-applies it and records a new rollback entry, so the history stays append-only.
HA events
Token-lifecycle event data includes token_id, token_name, and timestamp. Revocation and rotation events also include the HA user ID of the admin who acted. atm_config_changed instead carries resource_type, resource_id, and action.
| Event | Fired when |
|---|---|
atm_approval_resolved | A pending approval is approved, rejected, expired, or cancelled |
atm_config_changed | A configuration version is recorded (agent create/edit/delete, or an admin rollback); drives the panel's live Changes feed |
atm_rate_limited | A token exceeds its rate limit (once per token per minute) |
atm_token_expired | A token's expiry passes and it is first accessed |
atm_token_revoked | A token is revoked |
atm_token_rotated | A token's raw value is rotated |
Route reference
Admin API
The admin routes (tokens, permissions, approvals, MESA profiles, entity hints, settings, and the rest) now have their own Admin API reference, complete with payload schemas. They require a Home Assistant session and the admin role.
Proxy API
Requires an ATM token in the Authorization: Bearer header.
GET /api/atm/states All accessible entity states
GET /api/atm/states/{entity_id} One entity state
POST /api/atm/services/{domain}/{service} Call a service
GET /api/atm/history/period/{timestamp} State history (max 7-day range)
GET /api/atm/statistics Long-term statistics
POST /api/atm/template Render a Jinja2 template
GET /api/atm/config HA configuration
GET /api/atm/events HA event-bus listeners
GET /api/atm/services Accessible service list
GET /api/atm/logs Recent HA system log entries
POST /api/atm/mcp MCP Streamable HTTP endpoint
GET /api/atm/mcp/context Token context summary
There is also an unauthenticated skill route
GET /api/atm/skill serves the agent skill guide with no token. It is generic and contains no token or entity data. See the agent skill.