Skip to content

website: add an agent-facing page on driving Anthias over the API - #3426

Merged
vpetersson merged 1 commit into
masterfrom
agent/anthias-claude/04a012ebbe53
Oct 27, 2026
Merged

vpetersson merged 1 commit into
masterfrom
agent/anthias-claude/04a012ebbe53

Conversation

@vpetersson-bot

Copy link
Copy Markdown
Contributor

What

Adds /agents/ to anthias.screenly.io — a page about driving Anthias from an AI agent, written to be consumed by one.

It follows the three-step path a user would actually take:

  1. Install a player. The one-line installer, with the honest note that it is interactive (whiptail dialogs, four prompts) so an agent driving it over SSH needs a PTY — and that image flashing or a Balena fleet is the right route when you want no prompts at all. GET /api/v2/info as the readiness poll.
  2. Turn on API authentication. PATCH /api/v2/device_settings with auth_backend: auth_basic, the current_password rule, and then HTTP Basic on every call.
  3. Publish and schedule content. Web pages, the two-step upload for images and video, YouTube and streams, the scheduling fields, playlist order, and a worked fan-out across N devices.

Plus the limits worth stating up front: no central server, per-device asset ids, a single operator account, device-local timezone.

Why

Anthias is a good fit for this — every player serves its own REST API on the LAN, so a fleet is just a list of base URLs, with no tenant model and no SDK — but nothing on the site said so. An agent pointed at the site had to assemble the workflow from the API reference, the install docs and the scheduling docs, and the two things most likely to trip it up were written down nowhere.

How I know it is right

Every request on the page was run against a real device on the QA rig before it was written down. That turned up the two gotchas the page now calls out:

  • An unauthenticated API call answers 302 to /login/, not 401. A client that follows redirects by default turns a rejected request into a 200 with an HTML login page. Wrong credentials do give a clean 401.
  • Enabling auth needs current_password once an operator account exists, including when re-enabling after a period with auth switched off — a first-time enable does not.

Also verified live: the file_asset → assets upload handshake and the uri/ext round trip, play_days as ISO weekdays with play_time_from/play_time_to, the youtube_asset URI validation, and that /api/schema/ stays readable while auth is on. Test assets were deleted and the device's auth setting restored afterwards.

Also in this PR

The /api/ page claimed the API "does not require an API token" with no mention that Basic auth can be switched on, which has been wrong since the auth backend landed. That section is corrected and links to the new page.

The page is in the footer under Resources; llms.txt and llms-full.txt pick it up automatically from the built output, and it is in the sitemap. hugo build is clean.

🤖 Generated with Claude Code

Anthias is well suited to being operated by an AI agent — every player
serves its own REST API on the LAN, so a fleet is just a list of base
URLs — but nothing on the site said so, and an agent pointed at the
existing pages had to assemble the workflow from the API reference, the
install docs and the scheduling docs.

Add /agents/, written to be read by an agent: the three-step path
(install a player, turn on authentication, publish and schedule
content), complete curl examples for each, the asset and scheduling
field semantics, a fan-out example across N devices, and the limits
worth knowing (no central server, per-device asset ids, single operator
account).

Every request on the page was run against a real device, which turned
up two things worth writing down: an unauthenticated API call answers
302 to the login form rather than 401, so a client that follows
redirects silently turns a rejected request into a 200 with an HTML
body; and enabling auth needs current_password once an operator account
exists, including when re-enabling after a period with it switched off.

The /api/ page claimed the API "does not require an API token" with no
mention that Basic auth can be switched on, which has been wrong since
the auth backend landed. Correct that section and link it to the new
page. Add the page to the footer; llms.txt picks it up automatically
from the built output.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
@vpetersson-bot
vpetersson-bot requested a review from a team as a code owner October 27, 2026 09:49
Copilot AI lite review requested due to automatic review settings October 27, 2026 09:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error: Your billing is not configured or you have Copilot licenses from multiple standalone organizations or enterprises. To use premium requests, select a billing entity via the GitHub site, under Settings > Copilot > Features.

@vpetersson-bot
vpetersson-bot requested a lite review from Copilot October 27, 2026 09:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error: Your billing is not configured or you have Copilot licenses from multiple standalone organizations or enterprises. To use premium requests, select a billing entity via the GitHub site, under Settings > Copilot > Features.

@sonarqubecloud

Copy link
Copy Markdown

@vpetersson
vpetersson merged commit 168b14c into master Oct 27, 2026
4 checks passed
a10kiloham pushed a commit to a10kiloham/Anthias that referenced this pull request Oct 27, 2026
)

47 upstream commits: viewer tick-start wait anchoring (Screenly#3328), WiFi
captive-portal return (Screenly#3399) + cosign image verification (Screenly#3401),
celery/pipeline/webview reliability fixes, core-dump ulimits, fd-table
bound, WAL/startup ordering fixes, dep bumps, website content (inert).

Fork-side resolutions:
- loops x anchoring unified: replay k ends at tick_start + duration*(k+1),
  so a slot takes exactly duration*loops and co-located players stay in
  step; view_video keeps its skip return under the new deadline signature
- cosign: fork images sign/verify under this repo's docker-build identity
  on Docker Hub (hard-fail; no GHCR pass), gated on PUSH_IMAGES
- wifi-connect pinned to ghcr.io/a10kiloham/wifi-connect — a cosign-copy
  mirror (signatures included) so devices verify upstream's release
  identity while pulling from fork-controlled infra; mirror workflow
  extended accordingly
- expiration stays removed (_parse_local_datetime not resurrected);
  compose keeps robkanthias/* images + takes no-core-dumps ulimits;
  balena workflow/templates stay deleted; fork version metadata adopts
  upstream's 2026.10.0
- both sides' new tests kept (loops tests re-pinned to anchored timeouts)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KncEQmFAq9eGUjf7WCGiEw
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants