# Send Avro Record: `When record from file based on schema is sent`

> Produce an Avro-serialised message to a Kafka input topic from a JSON file.

Source: https://docs.ktestify.xyz/docs/write-tests/actions/send-avro-record

Produces an Avro-serialised message to a Kafka **input** topic. KTestify reads the payload from a JSON file, serialises it using the specified Avro schema, and registers the schema in Schema Registry if needed.

---

## Syntax

```gherkin
When record from file based on schema is sent
  | topicName  | file         | schemaName | recordKey |
  | orders-in  | order.json   | Order      | ord-001   |
```

| Column | Type | Required | Description |
|---|---|---|---|
| `topicName` | `string` | ✅ | Name or alias of a declared **input** topic |
| `file` | `string` | ✅ | Path to a JSON payload file, relative to assets directory |
| `schemaName` | `string` | ❌ | Schema name declared via `Given schema`; if omitted, resolved via TopicNameStrategy |
| `recordKey` | `string` | ❌ | Kafka record key; omit to send with `null` key |

---

## Payload file format

The payload must be valid JSON that matches the Avro schema fields:

```json title="assets/order.json"
{
  "orderId": "ord-001",
  "product": "Widget A",
  "quantity": 3,
  "createdAt": "{{DATE:yyyy-MM-dd}}"
}
```

Date fields are normalised automatically by `AvroUtils` before serialisation.

---

## Schema resolution

KTestify resolves the Avro schema in this order:

1. If `schemaName` is set → looks up subject `schemaName-value` in Schema Registry.
2. If `schemaName` is empty → uses TopicNameStrategy: `namespace.topicName-value`.

---

## Prerequisites

- Schema Registry URL configured: `ktestify.schema-registry.url`
- Schema declared in Background:

```gherkin
Given schema
  | schemaName | schemaAlias |
  | Order      | order       |
```

---

## Multiple records in one step

Add multiple rows to the DataTable to produce several Avro records in sequence, in row order:

```gherkin
When record from file based on schema is sent
  | topicName | file           | schemaName | recordKey |
  | orders-in | order-001.json | Order      | ord-001   |
  | orders-in | order-002.json | Order      | ord-002   |
```

:::info[Same topic required]
Every row must resolve to the **same physical topic**. Mixing topics in one DataTable throws `TopicMismatchException` before any record is sent, split into separate step invocations instead. See [Multi-row DataTables](../advanced/multi-row-datatables) for the full rules.
:::

---

## See also

- [Avro assertions →](../assertions/avro-matchers)
- [Schemas background step →](../background/schemas)
- [Configuration →](../../getting-started/configuration)
- [Multi-row DataTables →](../advanced/multi-row-datatables)
