---
title: Arena 3D
description: The 3D match viewer included with the WebSocket addon — watch live or replay, and embed the widget on your own site.
badge: addon
---

# Arena 3D

A match rendered as a 3D broadcast, driven by the same pitch-level event
stream that feeds the WebSocket `action` frames. The ball follows the real
on-pitch action, shots arc to goal, and a goal triggers the celebration.

Two modes: **live** while the match is being played, and **replay** for a
finished one.

**It is included with the WebSocket addon** at no extra cost. There is nothing
separate to buy and nothing to activate — if your addon is active, it is on
your [dashboard](/dashboard/).

## Your embed key

The dashboard issues one key per account, alongside a list of the domains
allowed to load the widget. Both live on the **Arena 3D** block of
[/dashboard/](/dashboard/).

- Up to **3 domains**. Subdomains are covered automatically, so `example.com`
  also allows `app.example.com`.
- `sports.bzzoiro.com` always works, with or without a domain listed — leave
  the list empty if you only want to watch, not embed.
- Regenerating the key invalidates the old one immediately. Anything still
  embedding it stops rendering.

The key is not an API token and the two are not interchangeable: it authorises
one widget on one set of domains, and it carries no read access to the API.

## Embedding

```html
<iframe src="https://arena.bzzoiro.com/embed/live/{event_id}/?key=YOUR_EMBED_KEY"
        width="100%" height="520" frameborder="0" allowfullscreen></iframe>
```

Swap `live` for `replay` on a finished match. `{event_id}` is the same id the
REST API uses, so an event from `GET /api/v2/events/live/` drops straight in.

The response carries a `Content-Security-Policy: frame-ancestors` header built
from your own domain list, so a key lifted from your page still will not render
anywhere else.

## Which matches have it

The same ones that carry full per-action WebSocket coverage. From
`GET /api/v2/events/live/`:

- `websocket_plus: true` — the match has pitch-level coverage, so Arena 3D
  renders it
- `websocket_plus: false` — score and stats only; there is nothing to draw

Requesting a match without coverage returns an empty pitch rather than an
error, so check the flag before you build a link to it.

## Responses

| Status | Meaning |
|---|---|
| `200` | Rendered |
| `402` | The WebSocket addon on this account is not active |
| `403` | The page's domain is not on the key's allowlist, or the key does not exist |

A `403` with a key you believe is correct is almost always the referrer: the
widget identifies the embedding page by `Origin`, falling back to `Referer`.
A page served with `Referrer-Policy: no-referrer` sends neither, and the
request cannot be attributed to any domain. Opening the embed URL directly in
the address bar fails the same way, and for the same reason — that is not an
embed, and no domain can be checked.
