# Miro

Miro is a visual collaboration and online whiteboard platform used for brainstorming, planning, and project management. The Sling Miro connector extracts data from the Miro REST API v2, supporting boards, board items, members, tags, connectors, and groups.

{% hint style="success" %}
**CLI Pro Required**: APIs require a [CLI Pro token](https://docs.slingdata.io/sling-cli/cli-pro) or [Platform Plan](https://docs.slingdata.io/sling-platform/platform).
{% endhint %}

## Setup

The following credentials are accepted:

**Secrets:**

* `access_token` **(required)** -> Your Miro OAuth access token

### Getting Your Access Token

1. Log in to [Miro](https://miro.com)
2. Go to **Profile Settings** > **Your apps** tab
3. Click **Create new app**
4. Enter an app name (e.g., "Sling Data Integration")
5. Under **Permissions**, enable the following scopes:
   * `boards:read` — Read boards you have access to
   * `identity:read` — Read profile information
   * `team:read` — Read team information
6. Click **Install app and get OAuth token**
7. Select your team and click **Add**
8. Copy the generated access token

{% hint style="warning" %}
**Important:** Keep your access token secure and never share it publicly. If you need to regenerate a token, repeat the installation step above.
{% endhint %}

### Using `sling conns`

Here are examples of setting a connection named `MIRO`. We must provide the `type=api` property:

{% code overflow="wrap" %}

```bash
sling conns set MIRO type=api spec=miro secrets='{ access_token: your_access_token }'
```

{% endcode %}

### Environment Variable

See [here](https://docs.slingdata.io/sling-cli/environment#dot-env-file-.env.sling) to learn more about the `.env.sling` file.

{% code overflow="wrap" %}

```bash
export MIRO='{ type: api, spec: miro, secrets: { access_token: "your_access_token" } }'
```

{% endcode %}

### Sling Env File YAML

See [here](https://docs.slingdata.io/sling-cli/environment#sling-env-file-env.yaml) to learn more about the sling `env.yaml` file.

```yaml
connections:
  MIRO:
    type: api
    spec: miro
    secrets:
      access_token: "your_access_token"
```

## Replication

Here's an example replication configuration to sync Miro data to a PostgreSQL database:

```yaml
source: MIRO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: miro.{stream_name}

streams:
  # sync all endpoints
  '*':
```

**Incremental sync for boards, items, and connectors:**

```yaml
source: MIRO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: miro.{stream_name}

streams:
  boards:
    mode: incremental
  board_members:
  board_items:
    mode: incremental
  board_tags:
  board_connectors:
    mode: incremental
  board_groups:
```

## Endpoints

| Endpoint           | Description                                                         | Incremental | Depends On |
| ------------------ | ------------------------------------------------------------------- | ----------- | ---------- |
| `boards`           | All boards accessible to the authenticated user                     | Yes         | —          |
| `board_members`    | All members/collaborators for each board                            | No          | `boards`   |
| `board_items`      | All items (sticky notes, shapes, text, cards, images) on each board | Yes         | `boards`   |
| `board_tags`       | All tags defined on each board                                      | No          | `boards`   |
| `board_connectors` | All connectors (lines between items) on each board                  | Yes         | `boards`   |
| `board_groups`     | All groups (collections of items) on each board                     | No          | `boards`   |

The connector uses a **queue-based architecture** to handle parent-child relationships. The `boards` endpoint runs first and populates board IDs, which are used by `board_members`, `board_items`, `board_tags`, `board_connectors`, and `board_groups`.

To discover available endpoints:

```bash
sling conns discover MIRO
```

### Endpoint Details

**`boards`** — Returns all boards the authenticated user has access to. Includes board metadata such as name, description, owner, team, permissions, sharing policies, creation and modification timestamps. Board IDs are queued for all child endpoints.

**`board_members`** — Returns all members and collaborators for each board, including member name, role (owner, editor, viewer), and membership details.

**`board_items`** — Returns all items on each board, including sticky notes, shapes, text elements, cards, images, and other item types. Each item includes position, geometry, style, data content, and modification timestamps.

**`board_tags`** — Returns all tags defined on each board, including tag title and fill color.

**`board_connectors`** — Returns all connectors (lines/arrows between items) on each board, including start and end item references, style, and modification timestamps.

**`board_groups`** — Returns all groups (collections of items) on each board, including the list of grouped item IDs.

## Rate Limiting

The Miro API enforces credit-based rate limits:

* **100,000 credits per minute** per OAuth token
* Different endpoints consume different credit amounts

The connector automatically:

* Uses rate limiting (5 requests/second with concurrency of 3)
* Retries with exponential backoff on 429 (rate limit) responses
* Allows up to 5 retry attempts
* Retries with exponential backoff on 5xx server errors

## Common Use Cases

### Sync All Miro Data

```yaml
source: MIRO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: miro.{stream_name}

streams:
  '*':
```

### Sync Board Items Incrementally

```yaml
source: MIRO
target: MY_POSTGRES

defaults:
  object: miro.{stream_name}

streams:
  boards:
    mode: full-refresh
  board_items:
    mode: incremental
```

### Extract Board Structure and Members

```yaml
source: MIRO
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: miro.{stream_name}

streams:
  boards:
  board_members:
  board_tags:
  board_groups:
```

If you are facing issues connecting, please reach out to us at <support@slingdata.io>, on [discord](https://discord.gg/q5xtaSNDvp) or open a Github Issue [here](https://github.com/slingdata-io/sling-cli/issues).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.slingdata.io/connections/api-connections/miro.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
