{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/hypamoon-com/json-schema/hypamoon-com-call-plan-schema.json",
  "title": "CallPlan",
  "description": "A call plan: a small graph. entry is the first node; every node points to the next by id. At most 50 nodes, and every node must be reachable from entry. Field names inside the plan are camelCase: the plan is stored exactly as you send it.",
  "x-generated": "2026-11-12",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/hypamoon-com-openapi.json#/components/schemas/CallPlan",
  "type": "object",
  "properties": {
    "entry": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{1,64}$",
      "description": "The id of the first node."
    },
    "nodes": {
      "type": "object",
      "additionalProperties": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$"
              },
              "type": {
                "type": "string",
                "const": "announcement"
              },
              "text": {
                "type": "string",
                "minLength": 1,
                "maxLength": 1000,
                "description": "The text to read out."
              },
              "next": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$",
                "description": "The node to go to after the text."
              }
            },
            "required": [
              "id",
              "type",
              "text",
              "next"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$"
              },
              "type": {
                "type": "string",
                "const": "hours"
              },
              "schedule": {
                "type": "object",
                "properties": {
                  "timezone": {
                    "type": "string"
                  },
                  "days": {
                    "type": "object",
                    "properties": {
                      "mon": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "open": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            },
                            "close": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            }
                          },
                          "required": [
                            "open",
                            "close"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 4
                      },
                      "tue": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "open": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            },
                            "close": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            }
                          },
                          "required": [
                            "open",
                            "close"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 4
                      },
                      "wed": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "open": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            },
                            "close": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            }
                          },
                          "required": [
                            "open",
                            "close"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 4
                      },
                      "thu": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "open": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            },
                            "close": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            }
                          },
                          "required": [
                            "open",
                            "close"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 4
                      },
                      "fri": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "open": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            },
                            "close": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            }
                          },
                          "required": [
                            "open",
                            "close"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 4
                      },
                      "sat": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "open": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            },
                            "close": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            }
                          },
                          "required": [
                            "open",
                            "close"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 4
                      },
                      "sun": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "open": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            },
                            "close": {
                              "type": "string",
                              "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                            }
                          },
                          "required": [
                            "open",
                            "close"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 4
                      }
                    },
                    "additionalProperties": false
                  },
                  "closedDates": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                    },
                    "maxItems": 366
                  }
                },
                "required": [
                  "timezone",
                  "days"
                ],
                "additionalProperties": false,
                "description": "Opening hours per day in a time zone, like Europe/London."
              },
              "open": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$",
                "description": "The node to go to when open."
              },
              "closed": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$",
                "description": "The node to go to when closed."
              }
            },
            "required": [
              "id",
              "type",
              "schedule",
              "open",
              "closed"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$"
              },
              "type": {
                "type": "string",
                "const": "forward"
              },
              "strategy": {
                "type": "string",
                "enum": [
                  "sequential",
                  "parallel"
                ],
                "description": "sequential rings the targets one after another, parallel rings them all at once."
              },
              "targets": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "kind": {
                      "type": "string",
                      "const": "external"
                    },
                    "e164": {
                      "type": "string",
                      "pattern": "^\\+[1-9]\\d{7,14}$"
                    }
                  },
                  "required": [
                    "kind",
                    "e164"
                  ],
                  "additionalProperties": false
                },
                "minItems": 1,
                "maxItems": 3,
                "description": "Up to three phone numbers. Team members of the Hypamoon apps (kind user) are not available in the API."
              },
              "ringSeconds": {
                "type": "integer",
                "minimum": 5,
                "maximum": 120,
                "description": "How long to ring before onNoAnswer, 5 to 120 seconds."
              },
              "onNoAnswer": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$",
                "description": "The node to go to when nobody answers."
              }
            },
            "required": [
              "id",
              "type",
              "strategy",
              "targets",
              "ringSeconds",
              "onNoAnswer"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$"
              },
              "type": {
                "type": "string",
                "const": "menu"
              },
              "prompt": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "text"
                ],
                "additionalProperties": false,
                "description": "The text to read out, like \"Press 1 for sales\"."
              },
              "options": {
                "type": "object",
                "additionalProperties": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9_-]{1,64}$"
                },
                "propertyNames": {
                  "enum": [
                    "0",
                    "1",
                    "2",
                    "3",
                    "4",
                    "5",
                    "6",
                    "7",
                    "8",
                    "9"
                  ]
                },
                "description": "The node per key, 0 to 9."
              },
              "onNoInput": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$",
                "description": "The node to go to when the caller presses nothing."
              },
              "timeoutSeconds": {
                "type": "integer",
                "minimum": 1,
                "maximum": 30,
                "description": "How long to wait for a key, 1 to 30 seconds."
              }
            },
            "required": [
              "id",
              "type",
              "prompt",
              "options",
              "onNoInput"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$"
              },
              "type": {
                "type": "string",
                "const": "voicemail"
              },
              "greeting": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "text"
                ],
                "additionalProperties": false,
                "description": "Optional text before the beep."
              },
              "transcribe": {
                "type": "boolean",
                "default": true,
                "description": "Whether to transcribe the message. Default true."
              }
            },
            "required": [
              "id",
              "type"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$"
              },
              "type": {
                "type": "string",
                "const": "ai_agent"
              },
              "onDone": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$",
                "description": "Optional: the node to go to when the assistant is done. The assistant itself is set with PUT /assistant."
              }
            },
            "required": [
              "id",
              "type"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,64}$"
              },
              "type": {
                "type": "string",
                "const": "hangup"
              }
            },
            "required": [
              "id",
              "type"
            ],
            "additionalProperties": false
          }
        ]
      },
      "description": "The nodes by id. The key must be the same as the node's id."
    }
  },
  "required": [
    "entry",
    "nodes"
  ],
  "additionalProperties": false
}