* feat(api): expand REST coverage for full dashboard automation
Closes#6435.
Boards could only be created empty through the API. The single endpoint for
adding a widget took no geometry, so the size came from the widget default and
the position was always the next free cell. Everything else a setup needs was
reachable from the interface only.
Board composition
- POST /api/boards/items accepts an optional placement: width, height, xOffset,
yOffset and sectionId, or a layouts array for per breakpoint control. Without
it the previous automatic placement is unchanged.
- Adds read, update and delete for items, CRUD for sections, read and replace
for layouts, and GET /api/boards/{id} for the whole board.
- GET /api/boards/{id}/export and POST /api/boards/import make a board
reproducible from version control. onConflict decides what happens when the
name is taken, so a pipeline can be re-run.
- Board access is manageable through GET/PUT /api/boards/{id}/permissions.
Remaining services
- Search engines, integrations, groups, api keys and server settings are
exposed over OpenAPI and registered as MCP tools.
- GET /api/config/export and POST /api/config/import cover the configuration of
a whole instance. Ids are kept so references inside opaque widget options stay
intact, and entities are matched by natural key when the id is unknown, which
is what makes a document from another instance applicable.
- The backup endpoints accept an ApiKey header, so a recovery job no longer
needs a browser session.
Headless bootstrap
- homarr api-keys create prints a key without opening the web interface, which
together with the existing recreate-admin removes the last manual step.
Notes
- No database migration, the schema already stores position and size.
- Grid coordinates and sizes in a document are bounded, and the placement scan
no longer walks every column, so a large grid cannot occupy the server.
- Imports collect their statements first and apply them in one transaction, so a
rejected document never leaves a board half written.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: harden dashboard automation APIs
* fix: validate global home board settings
* fix: validate merged import settings
* docs(api): describe the bounded placement scan accurately
The comment still described the earlier version that walked every row up to the
last occupied one. Both axes now iterate the edges of the occupied areas, so the
cost follows the amount of content rather than the dimensions of the grid.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(api): keep the search engine type narrow and record the new MCP tools
The `.output()` added to `searchEngine.getPaginated` widened `type` back to a
string through the plain select schema, which broke the management page that
switches on it. It now reuses the narrowed union the detail endpoint already has.
`mcp.spec` pins the reviewed tool inventory; the 33 tools this branch exposes are
added to it. The configuration round trip asserted the first layout of an item,
which is the mobile one half of the time and holds the same item clamped, so it
addresses the base layout by id instead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(api): complete Homarr automation endpoints
* refactor(api): consolidate preferences and task docs
* refactor(api): narrow REST to dashboard automation
* refactor(api): expose existing dashboard controls only
* fix(docs): drop removed API key CLI path
---------
Co-authored-by: rfdrew <20803599+rfdrew@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Thomas Camlong <thomas@ajnart.fr>
Co-authored-by: ajnart <thomas@ajnart.dev>
The widget-only integrations refactor incorrectly removed the
ArchiveTeam Warrior integration entirely. It only needed to be
excluded from auto-seeding (by removing defaultUrl), not deleted.
This restores the integration class, reverts the widget/router/handler
to use integration middleware, and removes archiveTeamWarrior from the
widget-only-integrations migration.
- Remove ternary operators from new code (widget-integration-select,
TabsContainer, mock data, members page)
- Remove stale /docs/management/tools/backup from sitemap type
- Add value prop to error-state Select in beszel-system-stats
Merging dev introduced the Gotify integration and ArchiveTeam Warrior
widget/integration, which require entries in the doc-slug maps and the
generated documentation sitemap. Also remove a misplaced non-null
assertion in the group members page flagged by oxlint.
* feat(integrations): add Gotify notifications integration
Closes#4186
> "It would be really useful if Homarr could integrate with Gotify —
> view notifications from Gotify right inside the Homarr dashboard,
> maybe as a widget or a small panel. A widget that displays the latest
> messages from Gotify (with title, message, time)."
> — #4186: feat: Gotify Integration - display notifications in Homarr
- `gotify/gotify-schema.ts` — Zod schema validating the `GET /message`
API response from the Gotify server, including id, date, title,
message body, and optional priority fields.
- `gotify/gotify-integration.ts` — `GotifyIntegration` class extending
the base `Integration` and implementing `INotificationsIntegration`.
Authenticates via HTTP Basic Auth (username + password) and fetches
the latest 100 messages from the `/message` endpoint. Connection
testing hits `/health`.
- `index.ts` — exports `GotifyIntegration` from the package public API.
- `base/creator.ts` — registers `GotifyIntegration` in the integration
creator map so it can be instantiated at runtime.
- `integration.ts` — registers the `gotify` integration definition with:
- `secretKinds: [["username", "password"]]` (Basic Auth credentials)
- `category: ["notifications"]` (picked up automatically by the
Notifications widget via `getIntegrationKindsByCategory`)
- Icon sourced from `homarr-labs/dashboard-icons`
- Documentation URL pointing to `/docs/integrations/gotify`
- `docs/homarr-docs-sitemap.ts` — adds `/docs/integrations/gotify` to
the `HomarrDocumentationPath` union type so the documentation link
passes the TypeScript path validation check.
Because `gotify` is registered under the `notifications` category, the
existing Notifications widget automatically supports it with no widget
code changes required. Users add the integration via Settings →
Integrations, supply their Gotify server URL, username, and password,
then attach it to a Notifications widget on any board.
* refactor(integrations): inline json parse and add error handling in Gotify integration
Address PR review feedback: remove intermediate `as unknown` cast by inlining
response.json() directly, and use safeParseAsync to handle deserialization
failures gracefully instead of throwing unhandled.
The postinstall codegen script crashes CI when homarr.dev/sitemap.xml
is unreachable. Now catches fetch errors and keeps the existing
committed homarr-docs-sitemap.ts instead of crashing.