---
sidebar:
  hidden: true
title: roboto.experimental.boards.board
---
## Module Contents

### Board

```python
class roboto.experimental.boards.board.Board(
    record: roboto.experimental.boards.record.BoardRecord,
    roboto_client: Optional[roboto.http.RobotoClient] = None,
)
```

`from roboto.experimental.boards import Board`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/experimental/boards/board.py#L28-L405)

A board: panels arranged on a canvas, and the stages that provide their data.

A board is stored on the platform as a named JSON document, its definition, which the Roboto web app reads to draw the board. A board is created personal to its creator, and [`share_with_org()`](/docs/reference/python-sdk/roboto/experimental/boards/board#roboto.experimental.boards.board.Board.share_with_org) shares it with every member of its organization. Sharing a board does not share data: each viewer sees only the data they could already reach.

A definition is given either as a [`BoardDefinition`](/docs/reference/python-sdk/roboto/experimental/boards/definition#roboto.experimental.boards.definition.BoardDefinition), which checks the definition's outline as it is built, or as a `dict`. A `dict` is refused before any request is made if [`BoardDefinition`](/docs/reference/python-sdk/roboto/experimental/boards/definition#roboto.experimental.boards.definition.BoardDefinition) refuses its top level. The panels and stages in a definition are stored as given.

Each write of a board's definition advances its [`revision`](/docs/reference/python-sdk/roboto/experimental/boards/board#roboto.experimental.boards.board.Board.revision). [`update()`](/docs/reference/python-sdk/roboto/experimental/boards/board#roboto.experimental.boards.board.Board.update) sends the revision this instance last read, so a change made from an outdated copy of the board is refused instead of replacing someone else's edit.

**Parameters**

- **record** (`roboto.experimental.boards.record.BoardRecord`)
- **roboto_client** (`Optional[roboto.http.RobotoClient]`)

**Properties**

- **Board.accessibility** (`roboto.experimental.boards.record.BoardAccessibility`): Who can open this board: only its owner and the organization's admins, or every member.

- **Board.board_id** (`str`): Unique identifier of this board.

- **Board.created** (`datetime.datetime`): Timestamp when this board was created.

- **Board.created_by** (`str`): User ID of this board's creator.

- **Board.definition** (`dict[str, Any]`): This board's definition as a JSON object.

  The object is a copy, so changing it does not change this board. Pass a changed copy to [`update()`](/docs/reference/python-sdk/roboto/experimental/boards/board#roboto.experimental.boards.board.Board.update) to save it.

- **Board.modified** (`datetime.datetime`): Timestamp when this board was last modified.

- **Board.modified_by** (`str`): User ID of the last user to modify this board.

- **Board.name** (`str`): The name the board list and board page show.

- **Board.org_id** (`str`): ID of the organization that owns this board.

- **Board.owner_principal_id** (`str`): Principal that owns this board: `org:<org_id>` for a shared board, `user:<user_id>` for a personal one.

- **Board.record** (`roboto.experimental.boards.record.BoardRecord`): The wire-transmissible representation of this board.

- **Board.revision** (`int`): How many times this board's definition had been written when this instance last read it.

#### Board.create()

```python
@classmethod
def create(
    definition: Union[roboto.experimental.boards.definition.BoardDefinition, dict[str, Any]],
    name: Optional[str] = None,
    caller_org_id: Optional[str] = None,
    roboto_client: Optional[roboto.http.RobotoClient] = None,
) -> Board
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/experimental/boards/board.py#L49-L123)

Create a board that is personal to the caller.

**Parameters**

- **definition** (`Union[roboto.experimental.boards.definition.BoardDefinition, dict[str, Any]]`): The board's definition.
- **name** (`Optional[str]`): The name the board list and board page show. Defaults to the definition's `title`. When both are given they must match.
- **caller_org_id** (`Optional[str]`): Organization to create the board in. Required when the caller belongs to more than one.
- **roboto_client** (`Optional[roboto.http.RobotoClient]`): Roboto client instance. Uses the default if omitted.

**Returns**

- `Board`: The board.

**Raises**

- [`RobotoIllegalArgumentException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoIllegalArgumentException): No name is given and the definition has no title to take one from. Raised before any request is made.
- `pydantic.ValidationError`: `name` is empty, is longer than 120 characters, or differs from the definition's title, or [`BoardDefinition`](/docs/reference/python-sdk/roboto/experimental/boards/definition#roboto.experimental.boards.definition.BoardDefinition) refuses the definition's top level. Raised before any request is made.
- [`RobotoConflictException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoConflictException): The caller already owns a board with this name in the organization.
- [`RobotoFeatureNotAvailableException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoFeatureNotAvailableException): Boards are not available to the caller.

**Usage**

Check a definition's outline, then save it as a board named after its title:

```python
from roboto.experimental.boards import Board, BoardDefinition
definition = BoardDefinition.model_validate(
    {
        "schema_version": 1,
        "title": "Event overview",
        "time_range": "90d",
        "stages": [
            {
                "id": "stage-event-counts",
                "name": "EventCounts",
                "body": {
                    "kind": "entity.query",
                    "target": "events",
                    "aggregate": {"op": "count", "groupBy": "name"},
                },
            }
        ],
        "panels": [
            {
                "kind": "table",
                "id": "event-counts-table",
                "bindings": [{"name": "event_counts", "stage": "stage-event-counts"}],
            }
        ],
    }
)
board = Board.create(definition)
board.name
# 'Event overview'
```

#### Board.delete()

```python
def delete() -> None
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/experimental/boards/board.py#L279-L296)

Delete this board.

**Raises**

- [`RobotoNotFoundException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoNotFoundException): The board no longer exists.
- [`RobotoUnauthorizedException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoUnauthorizedException): The caller is not an admin of the board's organization, and the board is shared or is another member's personal board.

**Returns**

- `None`

**Usage**

```python
from roboto.experimental.boards import Board
Board.from_id("bd_abc123").delete()
```

#### Board.for_org()

```python
@classmethod
def for_org(
    org_id: Optional[str] = None,
    roboto_client: Optional[roboto.http.RobotoClient] = None,
) -> collections.abc.Generator[Board, None, None]
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/experimental/boards/board.py#L126-L170)

List an organization's shared boards and the caller's own personal boards, ordered by name.

Another member's personal board is never listed. An admin of the organization can still load one with [`from_id()`](/docs/reference/python-sdk/roboto/experimental/boards/board#roboto.experimental.boards.board.Board.from_id).

**Parameters**

- **org_id** (`Optional[str]`): Organization whose boards to list. Required when the caller belongs to more than one.
- **roboto_client** (`Optional[roboto.http.RobotoClient]`): Roboto client instance. Uses the default if omitted.

**Yields**

- Each of those boards.

**Raises**

- [`RobotoFeatureNotAvailableException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoFeatureNotAvailableException): Boards are not available to the caller.

**Returns**

- `collections.abc.Generator[Board, None, None]`

**Usage**

```python
from roboto.experimental.boards import Board
for board in Board.for_org():
    print(board.name)
```

#### Board.from_id()

```python
@classmethod
def from_id(
    board_id: str,
    roboto_client: Optional[roboto.http.RobotoClient] = None,
) -> Board
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/experimental/boards/board.py#L173-L201)

Load a board by ID.

**Parameters**

- **board_id** (`str`): Unique identifier of the board.
- **roboto_client** (`Optional[roboto.http.RobotoClient]`): Roboto client instance. Uses the default if omitted.

**Returns**

- `Board`: The board.

**Raises**

- [`RobotoNotFoundException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoNotFoundException): No board with this ID exists, or the caller cannot open it.
- [`RobotoFeatureNotAvailableException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoFeatureNotAvailableException): Boards are not available to the caller.

**Usage**

```python
from roboto.experimental.boards import Board
board = Board.from_id("bd_abc123")
board.name
# 'Event overview'
```

#### Board.refresh()

```python
def refresh() -> Board
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/experimental/boards/board.py#L298-L319)

Re-read this board from the platform, replacing every property backed by its record.

Call it when something other than this instance may have changed the board, for example before retrying an [`update()`](/docs/reference/python-sdk/roboto/experimental/boards/board#roboto.experimental.boards.board.Board.update) that was refused because the board had changed.

**Returns**

- `Board`: This board.

**Raises**

- [`RobotoNotFoundException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoNotFoundException): The board no longer exists, or the caller can no longer open it.

**Usage**

```python
from roboto.experimental.boards import Board
board = Board.from_id("bd_abc123")
board.refresh().revision
# 4
```

#### Board.share_with_org()

```python
def share_with_org() -> Board
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/experimental/boards/board.py#L321-L348)

Share this board with every member of its organization, permanently.

Ownership moves to the organization, and no request makes a shared board personal again. From then on every member can open and change the board, and only an admin of the organization can delete it. The definition and the revision stay as they are.

**Returns**

- `Board`: This board.

**Raises**

- [`RobotoConflictException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoConflictException): The organization already has a shared board with this name.
- [`RobotoNotFoundException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoNotFoundException): The board no longer exists.
- [`RobotoUnauthorizedException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoUnauthorizedException): The board is personal, and the caller is neither its owner nor an admin of its organization.

**Usage**

```python
from roboto.experimental.boards import Board
board = Board.from_id("bd_abc123").share_with_org()
board.accessibility
# <BoardAccessibility.Organization: 'organization'>
```

#### Board.update()

```python
def update(
    definition: Union[roboto.experimental.boards.definition.BoardDefinition, dict[str, Any], roboto.sentinels.NotSetType] = NotSet,
    name: Union[str, roboto.sentinels.NotSetType] = NotSet,
) -> Board
```

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/experimental/boards/board.py#L350-L405)

Replace this board's definition, rename it, or both.

The change is made only if the board is still at the [`revision`](/docs/reference/python-sdk/roboto/experimental/boards/board#roboto.experimental.boards.board.Board.revision) this instance last read. Otherwise it is refused with [`RobotoBoardRevisionConflictException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoBoardRevisionConflictException), whose `current_board` holds the stored board's record as a JSON object. Call [`refresh()`](/docs/reference/python-sdk/roboto/experimental/boards/board#roboto.experimental.boards.board.Board.refresh), apply the change to the refreshed definition, and update again.

**Parameters**

- **definition** (`Union[roboto.experimental.boards.definition.BoardDefinition, dict[str, Any], roboto.sentinels.NotSetType]`): The definition that replaces the stored one whole. When it has a `title` and no `name` is given, the board takes the title as its name.
- **name** (`Union[str, roboto.sentinels.NotSetType]`): The board's new name. A `title` the stored definition already has is rewritten to match. When a definition with a title is also given, the two must match.

**Returns**

- `Board`: This board.

**Raises**

- `pydantic.ValidationError`: Neither a definition nor a name is given, `name` is empty or longer than 120 characters, `name` differs from the given definition's title, or [`BoardDefinition`](/docs/reference/python-sdk/roboto/experimental/boards/definition#roboto.experimental.boards.definition.BoardDefinition) refuses the definition's top level. Raised before any request is made.
- [`RobotoBoardRevisionConflictException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoBoardRevisionConflictException): The board's definition was written after this instance last read it.
- [`RobotoConflictException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoConflictException): The board's owner already has another board with this name.
- [`RobotoNotFoundException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoNotFoundException): The board no longer exists.
- [`RobotoUnauthorizedException`](/docs/reference/python-sdk/roboto/exceptions/domain#roboto.exceptions.domain.RobotoUnauthorizedException): The board is personal, and the caller is neither its owner nor an admin of its organization.

**Usage**

Change the time range a board opens with:

```python
from roboto.experimental.boards import Board
board = Board.from_id("bd_abc123")
definition = board.definition
definition["time_range"] = "30d"
board = board.update(definition=definition)
```
