{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/coldrig-dev/json-schema/coldrig-dev-setup-infrastructure-input-schema.json",
  "title": "SetupInfrastructureInput",
  "description": "Exactly one of `inboxesEach` (uniform per-domain count) or `distribution` (per-ordinal counts) is required — supplying neither is rejected naming `inboxesEach`, and `distribution`'s length must equal `domains`.\n",
  "x-generated": "2026-11-04",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/coldrig-dev-openapi.yml#/components/schemas/SetupInfrastructureInput",
  "type": "object",
  "required": [
    "brand",
    "primaryDomain",
    "domains",
    "persona",
    "physicalAddress",
    "senderIdentity"
  ],
  "properties": {
    "brand": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200,
      "description": "One line of plain text: a line break, tab, control character or invisible text-direction mark is refused (400) naming this field."
    },
    "primaryDomain": {
      "type": "string",
      "minLength": 3,
      "maxLength": 253
    },
    "domains": {
      "type": "integer",
      "minimum": 1,
      "maximum": 20,
      "description": "Number of lookalike domains to set up."
    },
    "inboxesEach": {
      "type": "integer",
      "minimum": 1,
      "maximum": 5,
      "description": "Mailboxes to set up per domain, UNIFORM across every ordinal. 3 to 5 mailboxes per domain (3 by default, 5 when you order more than 10 in your first month); on a paying account a new domain needs 3 to 5. Putting 5 on a domain means fewer domains, but if that domain gets burned, 5 mailboxes stop sending instead of 3. Optional only when `distribution` is supplied.\n"
    },
    "distribution": {
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 5
      },
      "minItems": 1,
      "maxItems": 20,
      "description": "The per-ordinal mailbox count directly — one entry per domain ordinal (e.g. `[4, 3]` for 4 mailboxes on domain 0 and 3 on domain 1), for a shape `inboxesEach`'s single uniform number cannot express. Its length must equal `domains`. Alternative to `inboxesEach`, not additive with it.\n"
    },
    "persona": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "physicalAddress": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500,
      "description": "CAN-SPAM-required physical postal address, injected into the footer of every campaign email (replies sent with the reply tool or the dashboard carry no footer)."
    },
    "senderIdentity": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200,
      "description": "Legal sender identity captured at setup, injected into the footer of every campaign email (replies sent with the reply tool or the dashboard carry no footer)."
    },
    "quoteOnly": {
      "type": "boolean",
      "default": false,
      "description": "Quote-before-add. true previews the new mailbox count + projected monthly (returns 200 { quoteOnly, billing }) WITHOUT setup. false (default) sets up and returns { jobId, billing }.\n"
    },
    "registerDomains": {
      "type": "boolean",
      "description": "This account's opt-in consent to real domain purchases made on the platform's own account (the customer's bill is unchanged, mailbox-count-based only). Omitting this field entirely leaves any previously-given consent UNCHANGED; an explicit `false` revokes it. There is no default — an absent field is never treated as `false`. `true` opts in; `registrant` is required only when no complete registrant is already on file from a prior call (see `Registrant`) — a call omitting `registerDomains` (or sending `false`) on a request that needs to buy a domain is refused before any spend: 400 `registrar_optin_missing` once this account has consented at least once, or 503 `registrar_unarmed` if domain registration is not enabled for the platform at all. The 400 is cleared by sending `registerDomains: true`; a request cannot clear the 503.\n"
    },
    "registrant": {
      "$ref": "#/$defs/Registrant"
    },
    "dotComDomains": {
      "type": "boolean",
      "description": "Only when the quote's billing.domainEnding is set: true keeps those new domains on .com for the one-time fee it shows per domain, added to the next bill. Leave it out for .co.\n"
    },
    "prepaySecondMonth": {
      "type": "boolean",
      "description": "Only when the quote's billing.prepay is set (an order making more than 4 new domains in your first billing month): true accepts paying month 2 up front with this order (the amount it shows, charged right after the mailboxes are set up; the next renewal moves one month later; a cancel at any time ends the plan on that date; the prepaid month is not refunded).\n"
    }
  },
  "$defs": {
    "Registrant": {
      "type": "object",
      "description": "The domain registrant-of-record. Optional even when `registerDomains` is true, whenever a complete registrant is already on file from a prior call — supplying one makes it authoritative for THIS call; omitting it re-uses the persisted one. This platform never invents a domain registrant's legal identity, so a `registerDomains:true` call with no registrant anywhere (neither supplied nor persisted) is rejected (400 `incomplete_registrant`) naming the missing fields, before any purchase.\n",
      "required": [
        "firstName",
        "lastName",
        "email",
        "phone",
        "addressLine1",
        "city",
        "state",
        "country",
        "postalCode"
      ],
      "properties": {
        "firstName": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "lastName": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "email": {
          "type": "string",
          "format": "email"
        },
        "phone": {
          "type": "string",
          "minLength": 1,
          "maxLength": 50
        },
        "addressLine1": {
          "type": "string",
          "minLength": 1,
          "maxLength": 500
        },
        "city": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "state": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "country": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100
        },
        "postalCode": {
          "type": "string",
          "minLength": 1,
          "maxLength": 20
        },
        "organization": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200,
          "description": "Optional; defaults to the account's own brand if omitted."
        }
      }
    }
  }
}