# Get a board

Read one board: pinned apps with stored evidence, saved ads, the seven-day pulse and activity.

## Contract status

Preview contract: these routes and tools are implemented in the shared contract, but the public host, customer API access and OAuth flow have not been deployment verified.

## Endpoint: GET /v1/boards/{boardId}

- Method: `GET`
- Path: `/v1/boards/{boardId}`
- Authentication: Bearer API credential or OAuth access token
- Required scope: `context:read`
- MCP tool: `boards`
- MCP action: `get`

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `boardId` | path | uuid | yes | Board id. |

## Known errors

- 400 invalid_request for an invalid filter, identity or limit.
- 401 authentication_required for a missing or invalid credential.
- 402 subscription_required when access is not entitled.
- 403 authorization_required for a missing scope or unavailable preview access.
- 403 workspace_not_accessible when x-genviral-tenancy names a workspace the credential cannot reach.
- 404 not_found when the record is outside the accessible catalogue.
- 429 rate_limited; honor Retry-After when present.

## Request

Render saved ad creatives with `GET /v1/paid-ads?savedToBoardId=`. `watch` is the caller's own watchlist entry for the app, or null.

```
curl --get 'https://api.peekpanda.com/v1/boards/66666666-6666-4666-8666-666666666666' \
  --header "Authorization: Bearer $PEEKPANDA_TOKEN" \
  --header 'x-genviral-tenancy: personal'
```

## MCP request

Call boards with action get. Path fields go in params, filters in query, and a write body in body.

```
{
  "name": "boards",
  "arguments": {
    "request": {
      "action": "get",
      "params": {
        "boardId": "<boardId>"
      }
    }
  }
}

```

## Response

Zero ads means none collected yet, never that an app runs no ads. New ads count ads whose run started that UTC day.

```
{
  "id": "66666666-6666-4666-8666-666666666666",
  "name": "Top food apps",
  "color": "#5cb427",
  "scope": "personal",
  "workspaceId": null,
  "ownerUserId": "99999999-9999-4999-8999-999999999999",
  "appCount": 1,
  "adCount": 1,
  "createdAt": "2026-09-06T00:00:00.000Z",
  "updatedAt": "2026-09-06T00:00:00.000Z",
  "apps": [
    {
      "id": "77777777-7777-4777-8777-777777777777",
      "kind": "app",
      "storeId": "0000000000",
      "name": "Example Recipe Planner",
      "iconUrl": null,
      "note": null,
      "addedByUserId": "99999999-9999-4999-8999-999999999999",
      "createdAt": "2026-09-06T00:00:00.000Z",
      "watch": null,
      "evidence": {
        "liveAds": 4,
        "newAdsThisWeek": 1,
        "savedAdsOnBoard": 1,
        "inCatalogue": true
      }
    }
  ],
  "ads": [
    {
      "id": "88888888-8888-4888-8888-888888888888",
      "kind": "ad",
      "platform": "meta",
      "archiveId": "example-archive-id",
      "storeId": "0000000000",
      "advertiserName": "Example Labs",
      "note": "Hook: \"dinner in 10 minutes\"",
      "addedByUserId": "99999999-9999-4999-8999-999999999999",
      "createdAt": "2026-09-06T00:00:00.000Z"
    }
  ],
  "pulse": {
    "apps": 1,
    "savedAds": 1,
    "liveAds": 4,
    "newAdsThisWeek": 1,
    "newAdsByDay": [
      {
        "date": "2026-08-31",
        "newAds": 0
      },
      {
        "date": "2026-09-01",
        "newAds": 0
      },
      {
        "date": "2026-09-02",
        "newAds": 0
      },
      {
        "date": "2026-09-03",
        "newAds": 0
      },
      {
        "date": "2026-09-04",
        "newAds": 0
      },
      {
        "date": "2026-09-05",
        "newAds": 0
      },
      {
        "date": "2026-09-06",
        "newAds": 1
      }
    ]
  },
  "activity": [
    {
      "kind": "new_ads",
      "date": "2026-09-06",
      "storeId": "0000000000",
      "appName": "Example Recipe Planner",
      "count": 1
    },
    {
      "kind": "ad_saved",
      "at": "2026-09-06T00:00:00.000Z",
      "platform": "meta",
      "archiveId": "example-archive-id",
      "advertiserName": "Example Labs",
      "byUserId": "99999999-9999-4999-8999-999999999999"
    }
  ]
}

```

## Source

Boards are the caller's own organization, stored in PeekPanda. Pinned apps carry the listing name and icon as pinned; evidence counts are stored paid-ad observations.

## Refresh

Board reads and writes never call a provider or start collection. Pinning an app does not watch it; watching stays on the ASO tracked-app list.
