{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/przypominamy-com/json-schema/przypominamy-com-send-message-request-schema.json",
  "title": "SendMessageRequest",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/przypominamy-com-openapi.json#/components/schemas/SendMessageRequest",
  "type": "object",
  "required": [
    "to"
  ],
  "properties": {
    "to": {
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          },
          "minItems": 1,
          "maxItems": 500
        }
      ],
      "description": "Numer odbiorcy, `\"group:<id lub nazwa grupy>\"` albo tablica numerów i grup (łącznie do 500 odbiorców po rozwinięciu, duplikaty usuwane)"
    },
    "text": {
      "type": "string",
      "maxLength": 1000,
      "description": "Treść. Polskie znaki dozwolone (UCS-2, 70/67 znaków na część). Placeholdery: `{{imie}}`, `{{nazwisko}}`, `{{email}}`, `{{<pole_własne>}}` (z kontaktów - dla grup i dla numerów, które są w książce) i `{{opt_out}}` / `{{wypisz}}` (osobisty link wypisu) oraz `{{link:https://…}}` (śledzony krótki link per odbiorca, do 2 różnych adresów). Wymagane, chyba że podajesz `template_id`."
    },
    "template_id": {
      "type": "string",
      "description": "Id szablonu (`tpl_…`, z `GET /v1/templates`) zamiast `text`. Szablon musi być typu `sms` (w `POST /v1/mms` - `mms`, w `POST /v1/voice` - `vms`), inaczej 400 z `param: \"template_id\"`; nieznany → 404. Placeholdery `{{klucz}}` podstawiane z `params`, pozostałe z kontaktów albo pustym ciągiem."
    },
    "params": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Wartości placeholderów szablonu, np. `{ \"kiedy\": \"jutro 10:00\" }` → `{{kiedy}}`. Klucze bez rozróżniania wielkości liter. Tylko z `template_id`."
    },
    "from": {
      "type": "string",
      "maxLength": 11,
      "description": "Nadpis (nazwa nadawcy). Musi być aktywny na liście `GET /v1/senders`. Domyślnie nadpis konta."
    },
    "send_at": {
      "type": "string",
      "format": "date-time",
      "description": "Zaplanowana wysyłka (ISO 8601), do 90 dni w przód. Daty w przeszłości = wysyłka natychmiast."
    },
    "send_window": {
      "type": "string",
      "pattern": "^\\d{1,2}:\\d{2}-\\d{1,2}:\\d{2}$",
      "description": "Okno godzin wysyłki w czasie polskim (`HH:MM-HH:MM`, min. 15 minut, koniec wyłączny). Wysyłka spoza okna (teraz albo `send_at`) jest przesuwana na najbliższy początek okna i dostaje status `scheduled`. Pominięte = domyślne okno konta z `PATCH /v1/account`."
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "Ważność: po tym czasie dostawca przestaje próbować doręczyć (status `expired`). Od 15 minut do 72 godzin po czasie wysyłki."
    },
    "reference": {
      "type": "string",
      "maxLength": 128,
      "description": "Twój identyfikator (np. id wizyty). Wraca w odpowiedzi, webhookach i jako filtr w `GET /v1/messages`."
    },
    "priority": {
      "type": "boolean",
      "default": false,
      "description": "SMS priorytetowy: osobna, szybka kolejka u operatora (kody OTP, alerty). Cena za część × 2. Tylko SMS - w `POST /v1/mms` i `POST /v1/voice` ignorowane. Wartość inna niż `true`/`false` → 400."
    }
  }
}