# Schema 3.0.0

The complete rewrite of the ObserveRTC schema

Version coverage: /docs/reference/versions/


`3.0.0` was a complete rewrite. It is the baseline every later 3.x release is additive against, and
it is **not** compatible with 2.x data or 2.x tooling.

## What changed conceptually

### The sample mirrors getStats()

2.x modelled monitoring data as a set of hand-designed report types — `InboundAudioTrack`,
`OutboundVideoTrack`, `ClientTransport` and so on — each a curated selection of fields. Every time
the W3C stats spec moved, the mapping had to be renegotiated, and fields drifted in and out (the
2.1.0 changelog removed more than thirty of them in one release).

3.0.0 inverts that. `PeerConnectionSample` carries **the W3C stats dictionaries themselves**, one
array per stats type:

```text
PeerConnectionSample
├─ inboundTracks[]              outboundTracks[]
├─ inboundRtps[]                outboundRtps[]
├─ remoteInboundRtps[]          remoteOutboundRtps[]
├─ mediaSources[]               mediaPlayouts[]
├─ codecs[]                     dataChannels[]
├─ iceTransports[]              iceCandidates[]
├─ iceCandidatePairs[]          peerConnectionTransports[]
└─ certificates[]
```

Adding a field the spec added becomes a minor release, not a design discussion.

### One sample type per producer

`ClientSample`, `SfuSample` and `TurnSample` — the client-side one being the primary path, with
`client-monitor-js` producing it and `observer-js` consuming it.

### Scores and attachments are first-class

Every level — client, peer connection, track — carries:

- `score` (0–5) and `scoreReasons` for computed quality with a machine-readable explanation
- `attachments` for application data, so a track can be *"Alice's screen share"* rather than an
  opaque SSRC

That last one is what makes server-side
[publisher ↔ subscriber correlation](/docs/observer-js/sfu/) possible at all — the resolver reads
`producerId` / `consumerId` out of track attachments.

### Application-level payloads travel with the stats

`clientEvents`, `clientIssues`, `clientMetaItems` and `extensionStats` ride in the same sample as
the WebRTC statistics, so an event and the stats interval it occurred in arrive together and cannot
be misaligned by a separate transport.

## The 3.0.0 record set

| Group | Records |
|---|---|
| Top level | `ClientSample`, `PeerConnectionSample` |
| Tracks | `InboundTrackSample`, `OutboundTrackSample` |
| RTP | `InboundRtpStats`, `OutboundRtpStats`, `RemoteInboundRtpStats`, `RemoteOutboundRtpStats` |
| Media | `MediaSourceStats`, `MediaPlayoutStats`, `CodecStats` |
| Transport | `PeerConnectionTransportStats`, `DataChannelStats`, `IceTransportStats`, `IceCandidateStats`, `IceCandidatePairStats`, `CertificateStats` |
| Application | `ClientEvent`, `ClientIssue`, `ClientMetaData`, `ExtensionStat` |
| Other producers | `SfuSample`, `TurnSample`, `Samples` |

Full field reference: [ClientSample](/docs/schema/clientsample/).

## Generated outputs

| Format | Location |
|---|---|
| TypeScript type definitions | `outputs/typescript/` |
| Protocol Buffers | `outputs/proto/` |
| Flattened Avro (all chunks expanded) | `outputs/avsc/` |
| Markdown field reference | `schemaList.md` |
| npm: core types | the sample-schemas package |
| npm: binary encoding | `@observertc/samples-encoder` *(deprecated in [3.4.0](../v3-4-0/))* |
| npm: binary decoding | `@observertc/samples-decoder` *(deprecated in [3.4.0](../v3-4-0/))* |

## Migrating from 2.x

{{< callout context="caution" title="This is not an in-place upgrade" icon="alert-triangle" >}}
2.x report types have no mechanical mapping to 3.x samples — the model changed, not just the field
names. In practice, migration means:

1. Upgrade the client library to a 3.x-schema `client-monitor-js` (the 4.x line).
2. Treat 2.x archives as a separate, frozen dataset rather than converting them.
3. Rewrite server-side processing against the W3C-shaped stats arrays.
4. Move any custom fields you had added into `attachments` on the appropriate record.
{{< /callout >}}

The 2.x history remains in the
[CHANGELOG](https://github.com/observertc/schemas/blob/master/CHANGELOG.md) if you need to
interpret archived data.

[← Back to version history](/docs/schema/versions/)

