{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/eusend-dev/json-schema/eusend-dev-batch-contacts-request-schema.json",
  "title": "BatchContactsRequest",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/eusend-dev-openapi.json#/components/schemas/BatchContactsRequest",
  "type": "object",
  "required": [
    "contacts"
  ],
  "additionalProperties": false,
  "properties": {
    "contacts": {
      "type": "array",
      "minItems": 1,
      "maxItems": 1000,
      "items": {
        "type": "object",
        "required": [
          "email"
        ],
        "additionalProperties": false,
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "first_name": {
            "type": "string",
            "maxLength": 100
          },
          "last_name": {
            "type": "string",
            "maxLength": 100
          },
          "unsubscribed": {
            "type": "boolean",
            "description": "Carries an opt-out over from another provider. An import can only ever add an opt-out — `false` will not resubscribe someone."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Original signup time. Applied on insert only."
          },
          "properties": {
            "type": "object",
            "description": "Custom properties, usable as `{{key}}` in a broadcast body. Unlike the single-contact endpoint, an import MERGES these into whatever the contact already has, so a CSV carrying only `plan` will not drop a `company` an earlier import set.",
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            }
          }
        }
      }
    }
  }
}