# Delivery format

Read the little-endian Solana shred headers, data flags and payload offsets used by the UDP datagrams delivered to your receivers.

Source: https://docs.zerocopy.sh/shredstream/format

Each UDP datagram contains one raw Solana shred, byte for byte as the leader signed it.
A datagram is at most 1,228 bytes. Delivery includes only chained Merkle data and coding
shreds for the cluster's current shred version. Legacy and unchained shreds are not delivered.

Shreds are not signature-verified before delivery. Verify the leader's signature in your
receiver before accepting a shred. See [processing the stream](/shredstream/processing).

## Common header [#common-header]

Offsets and sizes are in bytes, measured from the start of the datagram. Multi-byte
integer fields use little-endian encoding. The signature is a byte sequence.
The common header occupies 83 bytes.

| Field | Offset | Size | Meaning |
| --- | --- | --- | --- |
| `signature` | 0 | 64 | Leader signature. |
| `shred_variant` | 64 | 1 | Shred type and Merkle variant. |
| `slot` | 65 | 8 | Slot containing the shred. |
| `index` | 73 | 4 | Shred index within its type in the slot. |
| `version` | 77 | 2 | Shred version. |
| `fec_set_index` | 79 | 4 | Identifier of the FEC set within the slot. |

## Data shred header [#data-shred-header]

The data header follows the common header. Data payload starts at byte 88.

| Field | Offset | Size |
| --- | --- | --- |
| `parent_offset` | 83 | 2 |
| `flags` | 85 | 1 |
| `size` | 86 | 2 |

The data `flags` byte uses Agave's values:

| Value | Meaning |
| --- | --- |
| `0x40` | Data complete: the shred ends a batch of entries. |
| `0xc0` | Last in slot: set with data complete on the slot's last data shred. Test `(flags & 0xc0) == 0xc0`. |

The low six bits hold the reference tick.

These flags describe shred data. They do not establish execution or commitment.

## Coding shred header [#coding-shred-header]

The coding header follows the common header. Coding payload starts at byte 89.

| Field | Offset | Size |
| --- | --- | --- |
| `num_data_shreds` | 83 | 2 |
| `num_coding_shreds` | 85 | 2 |
| `position` | 87 | 2 |

Use these fields with `slot` and `fec_set_index` to collect each FEC set and recover
missing data shreds. Then decode entries and transactions with a decoder for the
Merkle shred format. Reading the common header alone does not decode a block.

## Transport [#transport]

The stream uses plain UDP with no ordering, retransmission or authentication. Source
addresses are supplied at setup; [allowlist them](/shredstream/receivers#firewall).
Handle duplicates and missing shreds as described in [processing the stream](/shredstream/processing).
