> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devset.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Protobuf Wire Format Configuration Reference

> Reference for Devset's wireFormat block. Configure binary prefix framing for Protobuf messages, with support for schema-resolved and fixed prefix values.

When you publish Protobuf messages, the raw serialized bytes often need a small binary header — a prefix — prepended before the payload so consumers can identify the message type and deserialize it correctly. Devset's `wireFormat` block on a stage lets you configure exactly how that prefix is constructed, giving you compatibility with Confluent Schema Registry and other binary framing conventions without writing any custom serialization code.

<Note>
  The `wireFormat` block only applies when the workflow's `contentType` is `"application/x-protobuf"`. It has no effect on JSON payloads.
</Note>

## What Wire Format Does

A wire format prefix is a short sequence of bytes placed at the front of every outbound binary message. Its purpose is to tell the consumer which schema or message type to use when deserializing the payload. Confluent Schema Registry, for example, expects a 2-byte message type prefix followed by the serialized Protobuf bytes. Without the correct prefix, your consumer will fail to decode the message.

Devset supports two strategies for generating the prefix value:

* **`messageType`** — automatically use the type ID derived from the stage's schema. This is the standard approach for Confluent Schema Registry compatibility.
* **`messagePrefix`** — write a fixed integer value you provide. Use this when your consumers expect a hard-coded identifier rather than a schema-resolved one.

## `wireFormat` Block Fields

<ParamField path="wireFormat.type" type="&#x22;binary-prefix&#x22;" required>
  The framing strategy to apply. Currently the only supported value is `"binary-prefix"`, which prepends a fixed-width integer to the serialized payload.
</ParamField>

<ParamField path="wireFormat.prefix.size" type="integer" required>
  The byte length of the prefix. The only accepted value is `2` (two bytes, supporting values 0–65535).
</ParamField>

<ParamField path="wireFormat.prefix.source" type="&#x22;messageType&#x22; | &#x22;messagePrefix&#x22;" required>
  How the prefix value is determined.

  * `"messageType"` — Devset resolves the type ID from the stage's schema (via `schemaId` or the workflow-level default) and writes that integer as the prefix. This is the correct setting for Confluent Schema Registry compatibility.
  * `"messagePrefix"` — Devset writes the integer you provide in `prefix.value` as the prefix. Use this for consumers with a fixed or manually assigned type identifier.
</ParamField>

<ParamField path="wireFormat.prefix.value" type="integer (0–65535)">
  The fixed prefix value to write. Only used when `prefix.source` is `"messagePrefix"`. Must be an unsigned integer in the range 0–65535.
</ParamField>

***

## Examples

### Using `messageType` — Confluent Schema Registry

This is the most common configuration. Devset resolves the integer type ID from the stage's schema and writes it as a 2-byte prefix, matching the Confluent Schema Registry wire format:

```json theme={null}
{
  "stage": "order-created",
  "event": "order-created",
  "schemaId": "order-created",
  "emit": true,
  "set": {
    "id":     { "$fn": "uuid()" },
    "amount": { "$fn": "int(10, 500)" }
  },
  "wireFormat": {
    "type": "binary-prefix",
    "prefix": {
      "size": 2,
      "source": "messageType"
    }
  }
}
```

The outbound message is structured as:

```
[ 2-byte type ID ][ serialized Protobuf payload ]
```

Your consumer reads the first two bytes to look up the message descriptor, then deserializes the remainder.

***

### Using `messagePrefix` — Fixed Custom Prefix

When your consumers expect a specific hard-coded identifier rather than a schema-resolved one, use `messagePrefix` and supply the value directly:

```json theme={null}
{
  "stage": "payment-processed",
  "event": "payment-processed",
  "emit": true,
  "set": {
    "paymentId": { "$fn": "uuid()" },
    "amount":    { "$fn": "int(100, 5000)" }
  },
  "wireFormat": {
    "type": "binary-prefix",
    "prefix": {
      "size": 2,
      "source": "messagePrefix",
      "value": 42
    }
  }
}
```

Every message produced by this stage will begin with the two-byte prefix `0x002A` (decimal 42), regardless of the schema ID.

<Warning>
  When using `messagePrefix`, make sure the `value` you choose matches what your consumer expects. Mismatched prefix values cause deserialization failures that can be difficult to debug.
</Warning>

***

## Per-Stage vs Workflow-Level Configuration

The `wireFormat` block is configured per stage. This design lets different stages in the same workflow use different framing strategies — for example, one stage publishing with a schema-resolved prefix and another with a fixed custom prefix.

If every stage in your workflow uses identical wire format settings, you can reduce repetition by defining the `wireFormat` block in a shared stage template or by copying the block consistently across stages. There is no workflow-level `wireFormat` shorthand today, but per-stage configuration gives you maximum flexibility for mixed-schema pipelines.

```json theme={null}
{
  "id": "multi-type-flow",
  "messageType": "kafka",
  "contentType": "application/x-protobuf",
  "topic": "events.all",
  "pipeline": [
    {
      "stage": "user-registered",
      "schemaId": "user-registered",
      "emit": true,
      "set": { "userId": { "$fn": "uuid()" } },
      "wireFormat": {
        "type": "binary-prefix",
        "prefix": { "size": 2, "source": "messageType" }
      }
    },
    {
      "stage": "order-placed",
      "schemaId": "order-placed",
      "emit": true,
      "set": { "orderId": { "$fn": "uuid()" } },
      "wireFormat": {
        "type": "binary-prefix",
        "prefix": { "size": 2, "source": "messageType" }
      }
    }
  ]
}
```

<Tip>
  If you are unsure which prefix strategy to use, start with `messageType`. It is the correct setting for any broker stack that uses Confluent Schema Registry, which is the most common Protobuf deployment pattern for Kafka.
</Tip>

***

## Related Pages

* [Stage Fields](/reference/stage-fields) — full reference for the `wireFormat` field and all other stage-level configuration.
* [Workflow DSL](/reference/workflow-dsl) — setting `contentType` to `"application/x-protobuf"` at the workflow level.
