{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://uplevelre.com/setup-packs/schema.json",
  "title": "Uplevel Setup Pack",
  "type": "object",
  "description": "An Uplevel Setup Pack.",
  "required": [
    "format",
    "schemaVersion",
    "packId",
    "name",
    "version"
  ],
  "properties": {
    "$schema": {
      "type": "string",
      "description": "This schema's URL, https://uplevelre.com/setup-packs/schema.json, so an editor checks the file as it's written. The importer doesn't read it."
    },
    "format": {
      "type": "string",
      "const": "uplevelre.setup-pack"
    },
    "schemaVersion": {
      "type": "integer",
      "description": "2. A pack without a brand may also say 1.",
      "minimum": 1,
      "maximum": 2
    },
    "packId": {
      "type": "string",
      "format": "uuid",
      "description": "Generated once and kept for every version, so installing a newer version upgrades the earlier install."
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 160
    },
    "description": {
      "type": "string",
      "maxLength": 2000
    },
    "author": {
      "type": "string",
      "maxLength": 160
    },
    "version": {
      "type": "string",
      "description": "Such as 1.0.0.",
      "minLength": 1,
      "maxLength": 40
    },
    "exportedAt": {
      "type": "string",
      "description": "When the file was made, as an RFC 3339 timestamp."
    },
    "automations": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "An automation. It always installs as a draft that is off.",
        "required": [
          "key",
          "document"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Stable within the pack and across its versions; unique among items of its kind. Other items refer to it by this key.",
            "minLength": 1,
            "maxLength": 200
          },
          "document": {
            "type": "object",
            "description": "A portable automation document.",
            "required": [
              "format",
              "version",
              "name",
              "graph"
            ],
            "properties": {
              "format": {
                "type": "string",
                "const": "uplevelre.automation-template"
              },
              "version": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1
              },
              "exported_at": {
                "type": "string"
              },
              "name": {
                "type": "string",
                "minLength": 1
              },
              "description": {
                "type": "string"
              },
              "category": {
                "type": "string"
              },
              "graph": {
                "type": "object",
                "description": "The workflow: blocks and the connections between them. It must be acyclic and include a trigger.",
                "required": [
                  "nodes"
                ],
                "properties": {
                  "nodes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "description": "One block.",
                      "required": [
                        "id",
                        "kind"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Unique within the graph.",
                          "minLength": 1
                        },
                        "kind": {
                          "type": "string",
                          "description": "A trigger, action or control from the block catalog.",
                          "enum": [
                            "trigger.transaction_created",
                            "trigger.transaction_status_changed",
                            "trigger.transaction_closed",
                            "trigger.transaction_fell_through",
                            "trigger.contact_created",
                            "trigger.tag_added",
                            "trigger.stage_changed",
                            "trigger.contact_field_changed",
                            "trigger.sms_received",
                            "trigger.manual",
                            "trigger.website_form_submitted",
                            "trigger.website_visit",
                            "trigger.listing_viewed",
                            "trigger.consumer_registered",
                            "trigger.listing_favorited",
                            "trigger.search_saved",
                            "trigger.newsletter_signup",
                            "trigger.listing_match",
                            "trigger.date_reached",
                            "trigger.schedule",
                            "trigger.webhook_received",
                            "trigger.task_completed",
                            "trigger.task_overdue",
                            "trigger.appointment_scheduled",
                            "trigger.appointment_upcoming",
                            "trigger.appointment_completed",
                            "trigger.appointment_cancelled",
                            "trigger.appointment_no_show",
                            "trigger.showing_requested",
                            "trigger.meeting_booked",
                            "trigger.email_opened",
                            "trigger.email_clicked",
                            "trigger.email_bounced",
                            "trigger.email_replied",
                            "trigger.deal_created",
                            "trigger.deal_stage_changed",
                            "trigger.deal_won",
                            "trigger.deal_lost",
                            "trigger.deal_stuck_in_stage",
                            "trigger.program_subscribed",
                            "trigger.program_unsubscribed",
                            "action.create_transaction",
                            "action.send_sms",
                            "action.send_email",
                            "action.create_task",
                            "action.add_tag",
                            "action.set_field",
                            "action.mark_do_not_contact",
                            "action.set_email_subscription",
                            "action.remove_tag",
                            "action.set_stage",
                            "action.create_deal",
                            "action.move_deal_stage",
                            "action.assign_owner",
                            "action.return_to_pond",
                            "action.set_relationship",
                            "action.add_collaborator",
                            "action.remove_collaborator",
                            "action.run_automation",
                            "action.stop_automations",
                            "action.add_note",
                            "action.ai_extract",
                            "action.ai_message",
                            "action.webhook",
                            "action.notify",
                            "control.wait",
                            "control.if",
                            "control.ai_branch",
                            "control.loop"
                          ]
                        },
                        "config": {
                          "type": "object",
                          "description": "The block's settings, as the block catalog describes."
                        },
                        "position": {
                          "type": "object",
                          "description": "Where the editor draws it: {\"x\": 0, \"y\": 0}."
                        }
                      }
                    },
                    "maxItems": 200
                  },
                  "edges": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "description": "One connection.",
                      "required": [
                        "id",
                        "source",
                        "target"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "minLength": 1
                        },
                        "source": {
                          "type": "string",
                          "description": "The block it leaves."
                        },
                        "target": {
                          "type": "string",
                          "description": "The block it enters. Never a trigger."
                        },
                        "handle": {
                          "type": "string",
                          "description": "The source's output: next, true/false (control.if), each/done (control.loop), or an AI branch outcome. Defaults to next."
                        }
                      }
                    }
                  }
                }
              },
              "settings": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "Delivery settings. All three of allow_reenrollment, stop_on_reply and daily_send_limit are needed when settings are set.",
                "required": [
                  "allow_reenrollment",
                  "stop_on_reply",
                  "daily_send_limit"
                ],
                "properties": {
                  "allow_reenrollment": {
                    "type": "boolean",
                    "description": "Let a contact enroll again after a completed run."
                  },
                  "stop_on_reply": {
                    "type": "boolean",
                    "description": "End a contact's run when they reply."
                  },
                  "daily_send_limit": {
                    "type": "integer",
                    "description": "Most sends a day for the workspace.",
                    "minimum": 1,
                    "maximum": 10000
                  },
                  "send_window_start": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "Minutes after midnight, workspace time, when sending may start. Set with send_window_end.",
                    "minimum": 0,
                    "maximum": 1439
                  },
                  "send_window_end": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "Minutes after midnight when sending stops; different from send_window_start.",
                    "minimum": 0,
                    "maximum": 1439
                  },
                  "send_window_days": {
                    "description": "Days sending may happen, 0 = Sunday to 6 = Saturday, each once. Every day when left out.",
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 6
                    },
                    "minItems": 1,
                    "uniqueItems": true
                  },
                  "send_window_skip_holidays": {
                    "type": "boolean",
                    "description": "Hold sends on the workspace's holidays."
                  }
                },
                "additionalProperties": false
              },
              "references": {
                "type": "array",
                "items": {
                  "type": "object",
                  "description": "One item the graph refers to, so the installer can match it by name in the installing workspace.",
                  "required": [
                    "type",
                    "id"
                  ],
                  "properties": {
                    "type": {
                      "type": "string",
                      "description": "What kind of item it is.",
                      "enum": [
                        "tag",
                        "stage",
                        "smart_list",
                        "user",
                        "team",
                        "pond",
                        "website",
                        "form",
                        "email_template",
                        "custom_field",
                        "pipeline",
                        "deal_stage",
                        "appointment_type",
                        "appointment_outcome",
                        "program",
                        "relationship_label",
                        "automation",
                        "lead_source"
                      ]
                    },
                    "id": {
                      "type": "string",
                      "description": "The id or pack key exactly as the graph writes it."
                    },
                    "name": {
                      "type": "string",
                      "description": "Its name, used to find a match when the pack doesn't carry it."
                    },
                    "detail": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": false
                }
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "maxItems": 100
    },
    "smartLists": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "A smart list.",
        "required": [
          "key",
          "name",
          "filters"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Stable within the pack and across its versions; unique among items of its kind. Other items refer to it by this key.",
            "minLength": 1,
            "maxLength": 200
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "description": {
            "type": "string"
          },
          "filters": {
            "type": "object",
            "description": "A version 2 filter document: {\"version\": 2, \"root\": <and/or/not group or cond>}. Fields and operators are in the format guide.",
            "required": [
              "version",
              "root"
            ]
          },
          "color": {
            "type": "string",
            "description": "A hex color such as #ef4444."
          },
          "icon": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "maxItems": 100
    },
    "messageTemplates": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "A reusable one-to-one message template.",
        "required": [
          "key",
          "name",
          "channel",
          "body"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Stable within the pack and across its versions; unique among items of its kind. Other items refer to it by this key.",
            "minLength": 1,
            "maxLength": 200
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "channel": {
            "type": "string",
            "description": "Where it can be used.",
            "enum": [
              "sms",
              "email",
              "both"
            ]
          },
          "category": {
            "type": "string",
            "maxLength": 60
          },
          "subject": {
            "type": "string",
            "description": "Email subject, one line.",
            "maxLength": 300
          },
          "body": {
            "type": "string",
            "description": "The text, with merge tags. Required.",
            "minLength": 1,
            "maxLength": 20000
          },
          "richTextDoc": {
            "type": [
              "object",
              "null"
            ],
            "description": "The email's rich text document. Leave it out and the email is built from body."
          }
        },
        "additionalProperties": false
      },
      "maxItems": 100
    },
    "pipelines": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "A deal pipeline. It needs at least one CLOSED_WON and one CLOSED_LOST stage, and stage names are unique.",
        "required": [
          "key",
          "name",
          "stages"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Stable within the pack and across its versions; unique among items of its kind. Other items refer to it by this key.",
            "minLength": 1,
            "maxLength": 200
          },
          "name": {
            "type": "string",
            "minLength": 1
          },
          "description": {
            "type": "string"
          },
          "stages": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "A deal stage.",
              "required": [
                "key",
                "name"
              ],
              "properties": {
                "key": {
                  "type": "string",
                  "description": "Stable within the pack and across its versions; unique among items of its kind. Other items refer to it by this key.",
                  "minLength": 1,
                  "maxLength": 200
                },
                "name": {
                  "type": "string",
                  "minLength": 1
                },
                "color": {
                  "type": "string",
                  "description": "A hex color such as #22c55e."
                },
                "probability": {
                  "type": "integer",
                  "description": "Win probability. Won stages are 100 and lost stages 0 whatever this says.",
                  "minimum": 0,
                  "maximum": 100
                },
                "stageType": {
                  "type": "string",
                  "description": "OPEN when left out.",
                  "enum": [
                    "OPEN",
                    "CLOSED_WON",
                    "CLOSED_LOST"
                  ]
                }
              },
              "additionalProperties": false
            },
            "minItems": 1,
            "maxItems": 50
          }
        },
        "additionalProperties": false
      },
      "maxItems": 100
    },
    "resources": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "A tag, contact stage, lead source, custom field or email template the other items use. The data each kind takes is in the format guide.",
        "required": [
          "key",
          "kind",
          "name"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Stable within the pack and across its versions; unique among items of its kind. Other items refer to it by this key.",
            "minLength": 1,
            "maxLength": 200
          },
          "kind": {
            "type": "string",
            "enum": [
              "tag",
              "contact_stage",
              "lead_source",
              "custom_field",
              "email_template"
            ]
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "data": {
            "type": "object"
          }
        },
        "additionalProperties": false
      },
      "maxItems": 500
    },
    "brand": {
      "type": [
        "object",
        "null"
      ],
      "description": "A brand pack's brand. Build it with ComposeBrandPack or by exporting a workspace's brand."
    },
    "assets": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "A file the brand or an email template uses, embedded as base64 data or linked by https url. An email_image names the address its email templates use in sourceUrl; installing copies the file into the workspace's media library and replaces that address with the copy's.",
        "required": [
          "key",
          "role",
          "fileName",
          "mimeType",
          "byteSize",
          "sha256"
        ],
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1
          },
          "role": {
            "type": "string",
            "enum": [
              "logo",
              "favicon",
              "social_share_image",
              "brokerage_logo",
              "team_photo",
              "source_document",
              "email_image"
            ]
          },
          "fileName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "mimeType": {
            "type": "string"
          },
          "byteSize": {
            "type": "integer",
            "minimum": 0
          },
          "sha256": {
            "type": "string",
            "description": "Lower-case hex SHA-256 of the file."
          },
          "data": {
            "type": [
              "string",
              "null"
            ],
            "description": "Base64 file contents."
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "A public https link to the file."
          },
          "stagedFileId": {
            "type": [
              "string",
              "null"
            ]
          },
          "sourceUrl": {
            "type": [
              "string",
              "null"
            ],
            "description": "email_image only, and required for it: the full web address the pack's email templates use for the image, written exactly as in their designDocument, htmlContent or thumbnail.",
            "maxLength": 2048
          }
        },
        "additionalProperties": false
      }
    }
  },
  "additionalProperties": false
}
