{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/bangermail-com/json-schema/bangermail-com-mailchimp-migration-report-schema.json",
  "title": "MailchimpMigrationReport",
  "description": "The move from one Mailchimp connection into a product. Poll GET /mailchimp-migration for live progress:\n`phase` says where it is; `counts`, `audiences`, `segments`, `templates` and `campaigns` grow as it goes.\n",
  "x-generated": "2026-11-02",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/bangermail-com-openapi.json#/components/schemas/MailchimpMigrationReport",
  "type": "object",
  "required": [
    "migration_id",
    "connection_id",
    "product_id",
    "status",
    "phase",
    "started_at",
    "completed_at",
    "connection",
    "progress",
    "counts",
    "audiences",
    "contact_fields",
    "consent",
    "segments",
    "templates",
    "campaigns",
    "automations"
  ],
  "properties": {
    "migration_id": {
      "type": "string",
      "format": "uuid"
    },
    "connection_id": {
      "type": "string",
      "format": "uuid"
    },
    "product_id": {
      "type": "string",
      "format": "uuid"
    },
    "status": {
      "type": "string",
      "enum": [
        "importing",
        "completed"
      ]
    },
    "phase": {
      "type": "string",
      "enum": [
        "importing",
        "copying_designs",
        "finishing",
        "completed",
        "needs_new_key",
        "disconnected"
      ],
      "description": "importing (reading Mailchimp), copying_designs (templates and campaigns), finishing, completed, needs_new_key (Mailchimp rejected the API key; the move is paused until a new key is saved with rotateConnectionCredential), or disconnected (the connection was removed; everything already moved stays in Banger and the counts stay readable)."
    },
    "started_at": {
      "type": "string",
      "format": "date-time"
    },
    "completed_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "connection": {
      "type": "object",
      "required": [
        "display_name",
        "account_name",
        "status",
        "last_error_code",
        "needs_new_key"
      ],
      "properties": {
        "display_name": {
          "type": "string"
        },
        "account_name": {
          "type": [
            "string",
            "null"
          ]
        },
        "status": {
          "type": "string",
          "enum": [
            "pending_validation",
            "active",
            "error",
            "disabled"
          ]
        },
        "last_error_code": {
          "type": [
            "string",
            "null"
          ]
        },
        "needs_new_key": {
          "type": "boolean"
        },
        "message": {
          "type": "string",
          "description": "Present when needs_new_key or disconnected, ready to show."
        }
      }
    },
    "progress": {
      "type": "object",
      "required": [
        "import_streams",
        "import_streams_done",
        "failing_streams",
        "designs_waiting",
        "note"
      ],
      "properties": {
        "import_streams": {
          "type": "integer"
        },
        "import_streams_done": {
          "type": "integer"
        },
        "failing_streams": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "stream",
              "ref",
              "error_code"
            ],
            "properties": {
              "stream": {
                "type": "string"
              },
              "ref": {
                "type": "string"
              },
              "error_code": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        },
        "designs_waiting": {
          "type": "integer"
        },
        "note": {
          "type": "string"
        }
      }
    },
    "counts": {
      "type": "object",
      "required": [
        "contacts",
        "subscribed",
        "unsubscribed",
        "bounced",
        "contact_lists",
        "contact_fields",
        "segments_converted",
        "segments_kept_as_lists",
        "templates_imported",
        "templates_to_rebuild",
        "campaigns_imported_as_designs",
        "automations_imported"
      ],
      "properties": {
        "contacts": {
          "type": "integer"
        },
        "subscribed": {
          "type": "integer"
        },
        "unsubscribed": {
          "type": "integer"
        },
        "bounced": {
          "type": "integer"
        },
        "contact_lists": {
          "type": "integer"
        },
        "contact_fields": {
          "type": "integer"
        },
        "segments_converted": {
          "type": "integer"
        },
        "segments_kept_as_lists": {
          "type": "integer"
        },
        "templates_imported": {
          "type": "integer"
        },
        "templates_to_rebuild": {
          "type": "integer"
        },
        "campaigns_imported_as_designs": {
          "type": "integer"
        },
        "automations_imported": {
          "type": "integer"
        }
      }
    },
    "audiences": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "mailchimp_id",
          "name",
          "list_id",
          "list_name",
          "members_in_banger",
          "subscribed",
          "unsubscribed",
          "bounced",
          "members_in_mailchimp"
        ],
        "properties": {
          "mailchimp_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "list_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "list_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "members_in_banger": {
            "type": "integer"
          },
          "subscribed": {
            "type": "integer"
          },
          "unsubscribed": {
            "type": "integer"
          },
          "bounced": {
            "type": "integer"
          },
          "members_in_mailchimp": {
            "type": "integer"
          }
        }
      }
    },
    "contact_fields": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "mailchimp_tag",
          "name",
          "field_key",
          "type"
        ],
        "properties": {
          "mailchimp_tag": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "field_key": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "number",
              "boolean",
              "date",
              "choice",
              "choices"
            ]
          }
        }
      }
    },
    "consent": {
      "type": "string"
    },
    "segments": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/MailchimpMigrationOutcome"
      }
    },
    "templates": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/MailchimpMigrationOutcome"
      }
    },
    "campaigns": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/MailchimpMigrationOutcome"
      }
    },
    "automations": {
      "type": "object",
      "required": [
        "imported",
        "why",
        "next_steps",
        "help_call_url"
      ],
      "properties": {
        "imported": {
          "type": "boolean",
          "const": false
        },
        "why": {
          "type": "string"
        },
        "next_steps": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "help_call_url": {
          "type": "string",
          "format": "uri"
        }
      }
    }
  },
  "$defs": {
    "MailchimpMigrationOutcome": {
      "type": "object",
      "description": "What one Mailchimp segment, template or campaign became.",
      "required": [
        "mailchimp_id",
        "became",
        "name"
      ],
      "properties": {
        "mailchimp_id": {
          "type": "string",
          "description": "Segments: <audience id>:<segment id>. Templates and campaigns: their Mailchimp id."
        },
        "became": {
          "type": "string",
          "enum": [
            "segment",
            "contact_list",
            "template",
            "needs_rebuild"
          ]
        },
        "id": {
          "type": "string",
          "format": "uuid",
          "description": "The Banger segment",
          "contact list or design (template) it became. Absent for needs_rebuild.": null
        },
        "name": {
          "type": "string"
        },
        "reason": {
          "type": "string",
          "description": "Why a segment stayed a static list",
          "or why a design needs rebuilding.": null
        },
        "dropped_merge_tags": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Mailchimp merge tags with no Banger equivalent, removed from the design (conditions on merge fields keep their first branch and are listed here)."
        },
        "replaced_footer": {
          "type": "boolean",
          "description": "Mailchimp's footer section (view in browser, preferences, address, badge) became the product's brand footer."
        },
        "removed_links": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Links to Mailchimp-only pages outside the footer (such as view in browser) that were removed, by their words."
        },
        "links_to_fill": {
          "type": "array",
          "description": "Links left empty in Mailchimp; each is now a URL slot of the design to fill before it can be sent.",
          "items": {
            "type": "object",
            "required": [
              "key",
              "label"
            ],
            "properties": {
              "key": {
                "type": "string"
              },
              "label": {
                "type": "string"
              }
            }
          }
        },
        "kept_edits": {
          "type": "boolean",
          "description": "A re-run found the design edited in Banger and left it as it is."
        }
      }
    }
  }
}