Skip to main content
Each schema is a JSON file in your schemas directory, named {eventName}.json.

Directory structure

vela/schemas/
  order.placed.json
  order.cancelled.json
  payment.failed.json
  user.signup.json

File structure

{
  "eventName": "order.placed",
  "description": "Emitted when a checkout completes",
  "fields": [
    {
      "id": "fld-order-id",
      "name": "orderId",
      "type": "string",
      "required": true,
      "description": "Opaque order identifier",
      "validation": { "min": 1, "max": 128 }
    },
    {
      "id": "fld-amount",
      "name": "amountCents",
      "type": "number",
      "required": true
    },
    {
      "id": "fld-currency",
      "name": "currency",
      "type": "enum",
      "required": true,
      "enumValues": ["USD", "EUR", "GBP"]
    },
    {
      "id": "fld-items",
      "name": "itemCount",
      "type": "number",
      "required": false,
      "defaultValue": 1
    }
  ],
  "metadataFields": [
    {
      "id": "meta-env",
      "name": "environment",
      "type": "string",
      "description": "e.g. production, staging"
    }
  ]
}

Top-level fields

FieldRequiredDescription
eventNameyesEvent name that must match when ingesting
descriptionnoHuman-readable description
fieldsyesArray of field definitions (min 1)
metadataFieldsnoArray of metadata field definitions

Field properties

PropertyRequiredDescription
idyesUnique identifier for the field
nameyesField name in the event payload
typeyesData type (see below)
requiredyesWhether the field must be present
descriptionnoHuman-readable description
defaultValuenoDefault value if field is omitted
enumValuesnoAllowed values (only for enum type)
validationnoValidation rules (min, max, pattern)

Field types

TypeDescriptionValidation options
stringText valuemin, max (length), pattern (regex)
numberNumeric valuemin, max
booleantrue or false
dateISO-8601 date string
enumFixed set of stringsProvide enumValues array
objectNested JSON object

Metadata fields

Metadata fields define optional contextual data (environment, trace ID, etc.). They have the same structure as regular fields but without required, defaultValue, or validation.
{
  "id": "meta-env",
  "name": "environment",
  "type": "string",
  "description": "e.g. production, staging"
}

How diffing works

When you run vela diff or vela push, schemas are matched by eventName:
  • No remote match — schema will be created
  • Remote existsdescription, fields, and metadataFields are compared
  • Fields are compared by name (not id) — you can change IDs without triggering an update
  • When updating, the full fields array replaces the remote version entirely