Skip to content

Manage Layouts

Layouts are the saved dashboard configurations you build in the Zelos App. agent.layouts gives you the same CRUD surface from Python — useful for provisioning team dashboards from code, backing them up, or generating them from templates.

Layouts live in Zelos Cloud, so the agent must be logged in (zelos login). The snippets below assume an agent connected via connect():

from zelos_sdk.agent import connect

with connect() as agent:
    ...

List and inspect

for layout in agent.layouts.list():
    scope = "personal" if layout.is_personal else "team"
    print(f"{layout.name:30} {scope:8} {layout.id}")

Each Layout carries id, name, data (the panel configuration as a dict), is_personal, team_id, created_at, updated_at, and the owning email. Fetch one by id with agent.layouts.show(id).

Create

created = agent.layouts.create("My Dashboard", {"panels": []})
print(created.id)

# Scope to yourself instead of the team
personal = agent.layouts.create("Scratch", {"panels": []}, is_personal=True)

data accepts any JSON-serializable dict. The easiest way to author one is to build the layout in the app, then copy its data from show().

Update

update() patches only what you pass — omitted fields keep their current values (the SDK fetches the current layout first when needed):

agent.layouts.update(created.id, name="Renamed Dashboard")
agent.layouts.update(created.id, data={"panels": []}, is_personal=True)

Passing no fields at all raises ValueError.

Delete

agent.layouts.delete(created.id)

Version history

Every content-changing save records a version (create is version 1; no-op saves and personal/shared toggles don't version). The last 100 versions are kept per layout.

for v in agent.layouts.versions(created.id):
    marker = f" (restored from v{v.restored_from_version})" if v.restored_from_version else ""
    print(f"v{v.version:<4} {v.name:30} {v.created_at} {v.created_by_email or ''}{marker}")

versions() returns metadata only, newest first. Fetch a specific version's full data snapshot with show_version():

snapshot = agent.layouts.show_version(created.id, 1)
print(snapshot.data)

Restore a previous version with restore(). The restored state is appended to the history as a new version (with restored_from_version provenance) — history is never rewritten, so the pre-restore state stays restorable. Restoring a version identical to the current state is a no-op:

restored = agent.layouts.restore(created.id, 1)
print(restored.updated_at)  # the restored Layout

Name a version

Label a version worth keeping with set_version_label(). Named versions show their label in versions() and are kept forever — the 100-version retention never prunes them. Each layout can hold at most 40 named versions; naming another raises ValueError from the server until you clear an existing label:

agent.layouts.set_version_label(created.id, 3, "Golden config")

# Pass None to clear the label (the version becomes prunable again)
agent.layouts.set_version_label(created.id, 3, None)

Layouts saved before version history

Layouts created before this feature have an empty versions() list. Their next update records the pre-update state as version 1 before the new state, so nothing is lost.

Errors

Exception When
ValueError Malformed layout id, non-JSON-serializable data, an update() with no fields, or a version number outside 1–4294967295 — all raised before any network call. Also raised when the server rejects a set_version_label(): a label longer than 100 characters, or a layout that already has 40 named versions.
AgentError Layout or version not found, agent not logged in, or the call failed.