Docs Developers

REST API

Automate content and screens over HTTP — authentication, conventions and the main endpoints.

Everything the editor does goes through a JSON REST API, and you can use the same API from your own scripts and systems — for example to update a menu from your point-of-sale system or publish a daily bulletin automatically.

The base URL is https://signage.8w.fi/api/v1.

Authentication

Sign in with an email and password to get a session token:

curl -s https://signage.8w.fi/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"bot@example.com","password":"…"}'

The response contains your user, memberships and a token. Send it on every request:

curl -s https://signage.8w.fi/api/v1/clients -H "Authorization: Bearer $TOKEN"

Sessions last 30 days. POST /auth/logout ends one early.

Tip

Create a dedicated user (e.g. signage-bot@yourcompany.com) with the editor role in just the client it needs, rather than using a personal account.

Conventions

  • Requests and responses are JSON. State-changing requests must send Content-Type: application/json — this is part of the CSRF protection.
  • IDs are UUIDs.
  • Lists return { "items": [...] }.
  • Errors return a status code and { "error": { "code": "…", "message": "…" } }, e.g. 401 invalid_credentials, 404 not_found, 409 media_in_use, 429 rate_limited.
  • Anything you don't have access to returns 404, exactly as if it didn't exist.
  • Failed sign-ins are rate limited; after repeated failures an account is locked for 15 minutes.

Endpoints

Account and organisations

Method Path Description
POST /auth/login Sign in.
POST /auth/logout Sign out.
GET / PATCH /auth/me Your user, memberships; change name, language or password.
GET /clients Clients you can access, with your role in each.
GET /clients/:id/members People in a client.
GET / POST /clients/:id/invites List or create invites.

Media

Method Path Description
GET /clients/:id/media List media.
POST /clients/:id/media/uploads Start an upload; returns an upload URL.
POST /media/:id/complete Mark the upload finished; processing starts.
GET / PATCH / DELETE /media/:id Read, rename or delete.

Uploading is three steps: create the upload with the file name, MIME type and size; PUT the file to the returned URL; then call complete.

Content

Method Path Description
GET / POST /clients/:id/slides List or create slides.
GET / PUT / DELETE /slides/:id Read, replace or delete a slide. PUT takes the whole slide.
GET / POST /clients/:id/playlists List or create playlists.
GET / PATCH / DELETE /playlists/:id Read, update or delete a playlist.
PUT /playlists/:id/items Replace a playlist's slide order and duration overrides.
POST /playlists/:id/slides Create a slide and append it to the playlist.

Screens and schedules

Method Path Description
GET / POST /clients/:id/screen-groups List or create screen groups.
GET / PATCH / DELETE /screen-groups/:id Read, update or delete a group.
POST /clients/:id/schedules Create a schedule rule for a screen group.
PUT / DELETE /schedules/:id Replace or delete a rule.
GET /clients/:id/devices List screens and their status.
GET / PATCH / DELETE /devices/:id Read, rename, move or unpair a screen.
POST /devices/:id/commands Send a command: identify, reload, screenshot, restart-player, maintenance, reboot, update.
GET /devices/:id/screenshot Latest screenshot.

Publishing

Method Path Description
POST /clients/:id/publish Publish all screen groups in the client.
GET /screen-groups/:id/preview What the group would play if you published now.

Example: update a text slide and publish

# Change the soup of the day (PUT replaces the whole slide)
curl -s -X PUT https://signage.8w.fi/api/v1/slides/$SLIDE_ID \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"type":"text","title":"Soup of the day","body":"Creamy salmon soup — 9.50 €"}'

# Send it to the screens
curl -s -X POST https://signage.8w.fi/api/v1/clients/$CLIENT_ID/publish \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{}'

Slide bodies follow the same fields as the editor — see slides for every type and option.

Fair use

The API is meant for automation, not for high-frequency polling. Publishing more than once a minute rarely makes sense: screens pick up changes within about 15–30 seconds anyway.

Something unclear or out of date? Tell us.