{
  "openapi": "3.1.0",
  "info": {
    "title": "Groupilot API",
    "version": "1",
    "description": "Automate the WhatsApp communities of your webinars: events, sequences, scheduled messages, broadcasts and webhooks. Authenticate with `Authorization: Bearer gp_live_…`. Full guide: https://docs.groupilot.com/developers",
    "contact": {
      "name": "Groupilot support",
      "email": "contact@groupilot.com"
    }
  },
  "servers": [
    {
      "url": "https://app.groupilot.com/api/v1"
    }
  ],
  "tags": [
    {
      "name": "Meta"
    },
    {
      "name": "Account"
    },
    {
      "name": "Events"
    },
    {
      "name": "Occurrences"
    },
    {
      "name": "Communities"
    },
    {
      "name": "Sequences"
    },
    {
      "name": "Messages"
    },
    {
      "name": "Broadcasts"
    },
    {
      "name": "Media"
    },
    {
      "name": "Webhooks"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key created in Settings > Integrations (`gp_live_…`), or an OAuth access token."
      },
      "partnerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "A partner key (`gp_partner_…`) issued by Groupilot to an integration partner. Not an account key."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "example": "validation_error"
              },
              "message": {
                "type": "string"
              },
              "field": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ],
        "description": "Every error of the API has this shape."
      },
      "Me": {
        "type": "object",
        "properties": {
          "project": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "slug": {
                "type": "string"
              },
              "timezone": {
                "type": "string",
                "example": "Europe/Paris"
              },
              "billing": {
                "$ref": "#/components/schemas/BillingState"
              },
              "automation_blocked": {
                "type": "boolean",
                "description": "True while sends are paused by billing or a number change."
              },
              "created_at": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": [
              "id",
              "name",
              "slug",
              "timezone",
              "billing",
              "automation_blocked",
              "created_at"
            ]
          },
          "channel": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "state": {
                "$ref": "#/components/schemas/ChannelState"
              },
              "phone_masked": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "+33 •• •• •• 37"
              },
              "connected_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            },
            "required": [
              "state",
              "phone_masked",
              "connected_at"
            ],
            "description": "Null when no WhatsApp number has been linked yet."
          },
          "key": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "key_id": {
                "type": "string",
                "example": "AbC123defGhI"
              },
              "scopes": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Scope"
                }
              }
            },
            "required": [
              "id",
              "key_id",
              "scopes"
            ]
          },
          "limits": {
            "type": "object",
            "properties": {
              "read_per_minute": {
                "type": "integer"
              },
              "write_per_minute": {
                "type": "integer"
              },
              "broadcasts_per_day": {
                "type": "integer"
              },
              "adhoc_messages_per_day": {
                "type": "integer"
              },
              "media_per_day": {
                "type": "integer"
              }
            },
            "required": [
              "read_per_minute",
              "write_per_minute",
              "broadcasts_per_day",
              "adhoc_messages_per_day",
              "media_per_day"
            ]
          }
        },
        "required": [
          "project",
          "channel",
          "key",
          "limits"
        ]
      },
      "BillingState": {
        "type": "string",
        "enum": [
          "active",
          "trialing",
          "inactive"
        ],
        "description": "`active` or `trialing`: messages are sent. `inactive`: the subscription is not active (ended, unpaid or never started); nothing is sent until it is."
      },
      "ChannelState": {
        "type": "string",
        "enum": [
          "connected",
          "disconnected",
          "pending",
          "suspended"
        ],
        "description": "State of the WhatsApp number linked to this account. Only `connected` can send. `pending`: waiting for the QR code scan in the app. `suspended`: see the app."
      },
      "Scope": {
        "type": "string",
        "enum": [
          "read",
          "write",
          "send"
        ],
        "description": "`read`: list and read. `write`: create and change configuration (events, sequences, webhooks). `send`: anything that sends or cancels a WhatsApp message now (ad hoc messages, broadcasts, retries)."
      },
      "Health": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "version": {
            "type": "string",
            "enum": [
              "1"
            ]
          }
        },
        "required": [
          "ok",
          "version"
        ]
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string",
            "example": "webi-dimanche"
          },
          "type": {
            "$ref": "#/components/schemas/EventType"
          },
          "status": {
            "$ref": "#/components/schemas/EventStatus"
          },
          "timezone": {
            "type": "string",
            "example": "Europe/Paris"
          },
          "recurrence": {
            "$ref": "#/components/schemas/RecurrenceRule"
          },
          "sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21",
            "description": "The linked sequence, if any."
          },
          "smart_link": {
            "type": "string",
            "format": "uri",
            "example": "https://mywa.group/alice/webi-dimanche",
            "description": "The one link to put in your funnel: it always redirects to the next community."
          },
          "link_fallback_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "rotation_delay_hours": {
            "type": "integer",
            "description": "Hours after the live during which the smart link still points to that occurrence."
          },
          "community": {
            "type": "object",
            "properties": {
              "name_template": {
                "type": "string",
                "example": "{event_name} {date}"
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "days_before": {
                "type": "integer",
                "minimum": 1,
                "maximum": 90
              },
              "overflow_switch_at": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Members at which a new community is created and the link switched (default 940)."
              },
              "modify_groups_policy": {
                "$ref": "#/components/schemas/CommunityPolicy"
              },
              "member_add_mode": {
                "$ref": "#/components/schemas/CommunityPolicy"
              }
            },
            "required": [
              "name_template",
              "description",
              "days_before",
              "overflow_switch_at",
              "modify_groups_policy",
              "member_add_mode"
            ]
          },
          "member_webhook_configured": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "id",
          "name",
          "slug",
          "type",
          "status",
          "timezone",
          "recurrence",
          "sequence_id",
          "smart_link",
          "link_fallback_url",
          "rotation_delay_hours",
          "community",
          "member_webhook_configured",
          "created_at",
          "updated_at"
        ]
      },
      "EventType": {
        "type": "string",
        "enum": [
          "punctual",
          "recurring"
        ]
      },
      "EventStatus": {
        "type": "string",
        "enum": [
          "draft",
          "active",
          "paused",
          "archived"
        ],
        "description": "`active`: communities are created and messages sent. `paused`: nothing is sent and the smart link goes to the fallback URL (or an inactive page). `archived`: stopped for good. `draft`: not started."
      },
      "RecurrenceRule": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "days": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "sun",
                "mon",
                "tue",
                "wed",
                "thu",
                "fri",
                "sat"
              ]
            },
            "minItems": 1
          },
          "time": {
            "type": "string",
            "pattern": "^\\d{2}:\\d{2}$",
            "example": "20:00"
          },
          "timezone": {
            "type": "string",
            "example": "Europe/Paris"
          },
          "excluded_dates": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          }
        },
        "required": [
          "days",
          "time",
          "timezone"
        ],
        "description": "Weekly recurrence in the event's timezone."
      },
      "CommunityPolicy": {
        "type": "string",
        "enum": [
          "anyone",
          "admins"
        ]
      },
      "EventDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Event"
          },
          {
            "type": "object",
            "properties": {
              "smart_link_destination": {
                "$ref": "#/components/schemas/SmartLinkDestination"
              }
            },
            "required": [
              "smart_link_destination"
            ]
          }
        ]
      },
      "SmartLinkDestination": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "enum": [
              "group",
              "fallback",
              "unavailable",
              "stopped"
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Where the smart link redirects right now."
          },
          "occurrence_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "group_number": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "reason",
          "url",
          "occurrence_id",
          "group_number"
        ]
      },
      "EventList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "Occurrence": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "scheduled_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "status": {
            "type": "string",
            "enum": [
              "upcoming",
              "ready",
              "live",
              "completed",
              "canceled"
            ],
            "description": "`ready`: the community exists. `live`/`completed`: the live happened. `canceled`: removed by a recurrence change or a stop."
          },
          "state": {
            "type": "string",
            "description": "Display state computed by the app (same vocabulary as the Occurrences tab)."
          },
          "detail": {
            "type": [
              "string",
              "null"
            ]
          },
          "link_missing": {
            "type": "boolean"
          },
          "community_due_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "When the community is (or was) due to be created."
          },
          "groups": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer"
              },
              "members": {
                "type": "integer"
              },
              "invite_link": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The WhatsApp invite link the smart link currently redirects to."
              }
            },
            "required": [
              "count",
              "members",
              "invite_link"
            ]
          },
          "messages": {
            "type": "object",
            "properties": {
              "sent": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              }
            },
            "required": [
              "sent",
              "total"
            ]
          }
        },
        "required": [
          "id",
          "scheduled_at",
          "status",
          "state",
          "detail",
          "link_missing",
          "community_due_at",
          "groups",
          "messages"
        ]
      },
      "OccurrenceList": {
        "type": "object",
        "properties": {
          "filter": {
            "type": "string",
            "enum": [
              "upcoming",
              "past",
              "attention"
            ]
          },
          "page": {
            "type": "integer"
          },
          "page_size": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "counts": {
            "type": "object",
            "properties": {
              "upcoming": {
                "type": "integer"
              },
              "past": {
                "type": "integer"
              },
              "attention": {
                "type": "integer"
              }
            },
            "required": [
              "upcoming",
              "past",
              "attention"
            ]
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Occurrence"
            }
          }
        },
        "required": [
          "filter",
          "page",
          "page_size",
          "total",
          "counts",
          "items"
        ]
      },
      "OccurrenceDetail": {
        "type": "object",
        "properties": {
          "occurrence": {
            "$ref": "#/components/schemas/Occurrence"
          },
          "event_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OccurrenceGroup"
            }
          },
          "provisioning": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "status": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "due_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "example": "2026-11-09T19:00:00+01:00",
                "description": "ISO 8601 date-time with offset."
              },
              "needs_attention": {
                "type": "boolean"
              },
              "can_retry": {
                "type": "boolean"
              },
              "latest_attempt_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "example": "2026-11-09T19:00:00+01:00",
                "description": "ISO 8601 date-time with offset."
              },
              "latest_error": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "status",
              "due_at",
              "needs_attention",
              "can_retry",
              "latest_attempt_at",
              "latest_error"
            ]
          }
        },
        "required": [
          "occurrence",
          "event_id",
          "groups",
          "provisioning"
        ]
      },
      "OccurrenceGroup": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "number": {
            "type": "integer",
            "description": "1 for the first community, 2 for the overflow one, and so on."
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "member_count": {
            "type": "integer"
          },
          "is_full": {
            "type": "boolean"
          },
          "invite_link": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "number",
          "name",
          "status",
          "member_count",
          "is_full",
          "invite_link"
        ]
      },
      "CommunityListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21",
            "description": "Groupilot id (null for an external community never used in a broadcast)."
          },
          "whatsapp_id": {
            "type": "string",
            "description": "WhatsApp community id. Use it as a broadcast target."
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "member_count": {
            "type": "integer"
          },
          "source": {
            "$ref": "#/components/schemas/CommunitySource"
          },
          "occurrence_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "scheduled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "number": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "whatsapp_id",
          "name",
          "member_count",
          "source",
          "occurrence_id",
          "scheduled_at",
          "number"
        ]
      },
      "CommunitySource": {
        "type": "string",
        "enum": [
          "groupilot",
          "external"
        ],
        "description": "`groupilot`: created by Groupilot for an occurrence. `external`: a community of the connected number that Groupilot did not create (older events, manual groups)."
      },
      "CommunityList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CommunityListItem"
            }
          },
          "external_unreachable": {
            "type": "boolean",
            "description": "True when the connected number could not be queried: only communities known to Groupilot are listed."
          }
        },
        "required": [
          "items",
          "external_unreachable"
        ]
      },
      "Community": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "whatsapp_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "source": {
            "$ref": "#/components/schemas/CommunitySource"
          },
          "member_count": {
            "type": "integer"
          },
          "is_full": {
            "type": "boolean"
          },
          "invite_link": {
            "type": [
              "string",
              "null"
            ]
          },
          "number": {
            "type": "integer"
          },
          "occurrence_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "event_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "options": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string"
              },
              "applied_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "example": "2026-11-09T19:00:00+01:00",
                "description": "ISO 8601 date-time with offset."
              },
              "last_error": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "status",
              "applied_at",
              "last_error"
            ]
          },
          "event_defaults": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "modify_groups_policy": {
                "type": "string",
                "enum": [
                  "anyone",
                  "admins"
                ]
              },
              "member_add_mode": {
                "type": "string",
                "enum": [
                  "anyone",
                  "admins"
                ]
              }
            },
            "required": [
              "description",
              "modify_groups_policy",
              "member_add_mode"
            ]
          }
        },
        "required": [
          "id",
          "whatsapp_id",
          "name",
          "status",
          "source",
          "member_count",
          "is_full",
          "invite_link",
          "number",
          "occurrence_id",
          "event_id",
          "options",
          "event_defaults"
        ]
      },
      "SequenceMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Your own id, when the message was created through the API."
          },
          "order": {
            "type": "integer"
          },
          "timing": {
            "$ref": "#/components/schemas/Timing"
          },
          "type": {
            "$ref": "#/components/schemas/MessageType"
          },
          "text": {
            "type": "string",
            "description": "Supports the date variables `{J:jour}`, `{J:date}`, `{J+1:date}`, `{J:mois}`."
          },
          "media_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "poll": {
            "$ref": "#/components/schemas/Poll"
          },
          "ghost_mention": {
            "type": "boolean",
            "description": "Notify every member without showing @mentions (text messages only). Use sparingly."
          },
          "link_preview": {
            "type": "boolean",
            "description": "Text messages only: `false` sends the text without the preview card of its link (the link stays clickable). Always `true` on other types."
          },
          "community_update": {
            "$ref": "#/components/schemas/CommunityUpdateStep"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "id",
          "order",
          "timing",
          "type",
          "text",
          "media_url",
          "poll",
          "ghost_mention",
          "link_preview",
          "community_update",
          "created_at"
        ]
      },
      "Timing": {
        "type": [
          "string",
          "null"
        ],
        "pattern": "^(J[+-]?\\d{1,2} \\d{2}:\\d{2}|H[+-]\\d{1,3})$",
        "description": "When the message is sent, relative to the live. `J-1 10:00`: the day before at 10:00 (event timezone). `J0 18:30`: the day of the live. `J+1 09:00`: the day after. `H-1`: exactly one hour before the live; `H+2`: two hours after.",
        "example": "J-1 10:00"
      },
      "MessageType": {
        "type": "string",
        "enum": [
          "text",
          "image",
          "video",
          "voice",
          "document",
          "poll",
          "community_update"
        ],
        "description": "`text`, `image`, `video`, `voice`, `document`, `poll`: a message posted in the community. `community_update`: a step that changes the community's name and/or description at its time (nothing is posted; WhatsApp shows a system line)."
      },
      "Poll": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "question": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "options": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "minItems": 2,
            "maxItems": 12
          },
          "select_count": {
            "anyOf": [
              {
                "type": "number",
                "enum": [
                  0
                ]
              },
              {
                "type": "number",
                "enum": [
                  1
                ]
              }
            ],
            "description": "0: several answers allowed. 1: one answer."
          }
        },
        "required": [
          "question",
          "options",
          "select_count"
        ]
      },
      "CommunityUpdateStep": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "name_template": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200,
            "description": "New community name, or null to leave it. Variables: `{community_name}` (the community's normal name), `{community_description}`, `{event_name}`, `{project_name}`, `{date}`, `{time}`, and the date tokens `{J:date}`, `{J+4:date}`, `{J+4:mois}`, `{J-1:jour}` relative to the live. Rendered name is cut to 100 characters.",
            "example": "🔴 EN LIVE · {community_name}"
          },
          "description_template": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "description": "New description (same variables; empty string clears it), or null to leave it."
          },
          "restore_name": {
            "type": "boolean",
            "description": "Put the community's normal name back. Exclusive with `name_template`."
          },
          "restore_description": {
            "type": "boolean",
            "description": "Put the event's description back. Exclusive with `description_template`."
          }
        },
        "required": [
          "name_template",
          "description_template",
          "restore_name",
          "restore_description"
        ],
        "description": "Only on a `community_update` step; null otherwise."
      },
      "SequenceSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "message_count": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "id",
          "name",
          "message_count",
          "created_at"
        ]
      },
      "Sequence": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SequenceMessage"
            }
          },
          "linked_events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
                },
                "name": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "name",
                "status"
              ]
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "id",
          "name",
          "messages",
          "linked_events",
          "created_at"
        ]
      },
      "SequenceList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SequenceSummary"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "Job": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "occurrence_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "send_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "status": {
            "$ref": "#/components/schemas/JobStatus"
          },
          "source": {
            "type": "string",
            "enum": [
              "sequence",
              "ad_hoc"
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "description": "Your label for an ad hoc message."
          },
          "identity_label": {
            "type": "string"
          },
          "delivery": {
            "type": "object",
            "properties": {
              "sent": {
                "type": "integer"
              },
              "failed": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              },
              "certain_failed": {
                "type": "integer"
              },
              "uncertain": {
                "type": "integer"
              }
            },
            "required": [
              "sent",
              "failed",
              "total",
              "certain_failed",
              "uncertain"
            ]
          },
          "content": {
            "type": "object",
            "properties": {
              "source": {
                "type": "string",
                "enum": [
                  "snapshot",
                  "template"
                ],
                "description": "`snapshot`: frozen at first send. `template`: still follows the sequence message."
              },
              "type": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MessageType"
                  },
                  {
                    "type": "string",
                    "enum": [
                      ""
                    ]
                  }
                ]
              },
              "text": {
                "type": "string"
              },
              "media_url": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "poll": {
                "$ref": "#/components/schemas/Poll"
              },
              "community_update": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/CommunityUpdateStep"
                  },
                  {
                    "description": "For a `community_update` step: the payload that will be (or was) applied. Not editable per occurrence; cancel is possible."
                  }
                ]
              },
              "link_preview": {
                "type": "boolean",
                "description": "Text messages: `false` when the text is (or was) sent without its link preview card. Always `true` on other types."
              }
            },
            "required": [
              "source",
              "type",
              "text",
              "media_url",
              "poll",
              "community_update",
              "link_preview"
            ]
          },
          "sequence_message": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
              },
              "order": {
                "type": "integer"
              },
              "timing": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "order",
              "timing"
            ]
          },
          "editable": {
            "type": "boolean"
          },
          "cancelable": {
            "type": "boolean"
          },
          "retryable": {
            "type": "boolean"
          },
          "retrying": {
            "type": "boolean"
          },
          "retry": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer"
              },
              "max": {
                "type": "integer"
              },
              "next_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "example": "2026-11-09T19:00:00+01:00",
                "description": "ISO 8601 date-time with offset."
              },
              "last_error_category": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "count",
              "max",
              "next_at",
              "last_error_category"
            ]
          },
          "has_override": {
            "type": "boolean"
          },
          "first_attempt_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "sent_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "occurrence_id",
          "send_at",
          "status",
          "source",
          "label",
          "identity_label",
          "delivery",
          "content",
          "sequence_message",
          "editable",
          "cancelable",
          "retryable",
          "retrying",
          "retry",
          "has_override",
          "first_attempt_at",
          "sent_at",
          "error_message"
        ]
      },
      "JobStatus": {
        "type": "string",
        "enum": [
          "scheduled",
          "billing_paused",
          "overdue",
          "sent",
          "partial",
          "failed",
          "canceled"
        ],
        "description": "`scheduled`: waiting for its time. `billing_paused`: held while the subscription is not active. `overdue`: its time passed and it was not sent. `partial`: sent to some communities only. `canceled`: will not be sent."
      },
      "Delivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "community_whatsapp_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "community_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "number": {
            "type": [
              "integer",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "description": "Display state: sent, sending, not_sent, to_verify…"
          },
          "reason_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "sent_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ]
          },
          "reach": {
            "type": "object",
            "properties": {
              "members_at_send": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Recipients at send time (community members minus the sending number)."
              },
              "delivered_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "read_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "read_rate": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "read_count / members_at_send, in percent, one decimal."
              },
              "measurement_status": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "pending",
                  "partial",
                  "consolidated",
                  "unknown",
                  null
                ]
              },
              "measured_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "example": "2026-11-09T19:00:00+01:00",
                "description": "ISO 8601 date-time with offset."
              }
            },
            "required": [
              "members_at_send",
              "delivered_count",
              "read_count",
              "read_rate",
              "measurement_status",
              "measured_at"
            ],
            "description": "WhatsApp read receipts, measured hourly after the send; all null until the first measurement."
          }
        },
        "required": [
          "id",
          "community_whatsapp_id",
          "community_name",
          "number",
          "status",
          "state",
          "reason_code",
          "sent_at",
          "error_message",
          "reach"
        ]
      },
      "DeliveryList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Delivery"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "items",
          "next_cursor"
        ]
      },
      "Broadcast": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "status": {
            "$ref": "#/components/schemas/BroadcastStatus"
          },
          "type": {
            "$ref": "#/components/schemas/SendableMessageType"
          },
          "text": {
            "type": "string"
          },
          "media_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "poll": {
            "$ref": "#/components/schemas/Poll"
          },
          "community_count": {
            "type": "integer"
          },
          "counts": {
            "type": "object",
            "properties": {
              "success": {
                "type": "integer"
              },
              "failure": {
                "type": "integer"
              },
              "uncertain": {
                "type": "integer"
              }
            },
            "required": [
              "success",
              "failure",
              "uncertain"
            ]
          },
          "scheduled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "sent_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "canceled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "id",
          "status",
          "type",
          "text",
          "media_url",
          "poll",
          "community_count",
          "counts",
          "scheduled_at",
          "sent_at",
          "canceled_at",
          "created_at"
        ]
      },
      "BroadcastStatus": {
        "type": "string",
        "enum": [
          "pending",
          "sending",
          "completed",
          "failed",
          "canceled"
        ]
      },
      "SendableMessageType": {
        "type": "string",
        "enum": [
          "text",
          "image",
          "video",
          "voice",
          "document",
          "poll"
        ]
      },
      "BroadcastList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Broadcast"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "BroadcastRecipient": {
        "type": "object",
        "properties": {
          "community_whatsapp_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "sent, failed, skipped, pending, sending, requires_review…"
          },
          "attempt_count": {
            "type": "integer"
          },
          "settled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "community_whatsapp_id",
          "status",
          "attempt_count",
          "settled_at"
        ]
      },
      "BroadcastRecipientList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BroadcastRecipient"
            }
          },
          "total": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "page_size": {
            "type": "number",
            "enum": [
              50
            ]
          }
        },
        "required": [
          "items",
          "total",
          "page",
          "page_size"
        ]
      },
      "Notification": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "type": {
            "type": "string",
            "example": "send_failure"
          },
          "title": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "read": {
            "type": "boolean"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {}
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "id",
          "type",
          "title",
          "message",
          "read",
          "metadata",
          "created_at"
        ]
      },
      "NotificationList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Notification"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "EventCreate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "slug": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
            "description": "Lowercase letters, digits and dashes. Ends the smart link; cannot change later."
          },
          "type": {
            "$ref": "#/components/schemas/EventType"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "IANA zone. Defaults to the account's timezone. Cannot change later."
          },
          "recurrence": {
            "type": "object",
            "properties": {
              "days": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "sun",
                    "mon",
                    "tue",
                    "wed",
                    "thu",
                    "fri",
                    "sat"
                  ]
                },
                "minItems": 1
              },
              "time": {
                "type": "string",
                "pattern": "^\\d{2}:\\d{2}$",
                "example": "20:00"
              },
              "excluded_dates": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                }
              }
            },
            "required": [
              "days",
              "time"
            ],
            "description": "Required for a recurring event; the timezone is the event's."
          },
          "link_fallback_url": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "format": "uri"
          },
          "rotation_delay_hours": {
            "type": "integer",
            "minimum": 0,
            "maximum": 168
          },
          "community": {
            "type": "object",
            "properties": {
              "name_template": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 2000
              },
              "days_before": {
                "type": "integer",
                "minimum": 1,
                "maximum": 90
              },
              "overflow_switch_at": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 1,
                "maximum": 980
              },
              "modify_groups_policy": {
                "$ref": "#/components/schemas/CommunityPolicy"
              },
              "member_add_mode": {
                "$ref": "#/components/schemas/CommunityPolicy"
              }
            }
          }
        },
        "required": [
          "name",
          "slug",
          "type"
        ]
      },
      "EventUpdate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "description": "Display name. The slug (smart link) and the communities that already exist keep their names; the next communities use the new one."
          },
          "type": {
            "$ref": "#/components/schemas/EventType"
          },
          "link_fallback_url": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "format": "uri"
          },
          "rotation_delay_hours": {
            "type": "integer",
            "minimum": 0,
            "maximum": 168
          },
          "community": {
            "type": "object",
            "properties": {
              "name_template": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 2000
              },
              "days_before": {
                "type": "integer",
                "minimum": 1,
                "maximum": 90
              },
              "overflow_switch_at": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 1,
                "maximum": 980
              },
              "modify_groups_policy": {
                "$ref": "#/components/schemas/CommunityPolicy"
              },
              "member_add_mode": {
                "$ref": "#/components/schemas/CommunityPolicy"
              }
            }
          },
          "apply_to_existing_communities": {
            "type": "object",
            "properties": {
              "name": {
                "type": "boolean"
              },
              "description": {
                "type": "boolean"
              }
            },
            "description": "Also rename / re-describe the communities that already exist on WhatsApp."
          }
        },
        "additionalProperties": false
      },
      "EventUpdateResponse": {
        "type": "object",
        "properties": {
          "event": {
            "$ref": "#/components/schemas/Event"
          },
          "existing_communities": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "total": {
                "type": "integer"
              },
              "succeeded": {
                "type": "integer"
              },
              "failed": {
                "type": "integer"
              },
              "skipped": {
                "type": "integer"
              }
            },
            "required": [
              "total",
              "succeeded",
              "failed",
              "skipped"
            ]
          }
        },
        "required": [
          "event",
          "existing_communities"
        ]
      },
      "PauseResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused"
            ]
          },
          "changed": {
            "type": "boolean"
          },
          "canceled_elapsed_jobs": {
            "type": "integer"
          }
        },
        "required": [
          "status",
          "changed"
        ]
      },
      "SequenceLink": {
        "type": "object",
        "properties": {
          "sequence_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21",
            "description": "`null` unlinks. Pending sends of future occurrences are replaced."
          }
        },
        "required": [
          "sequence_id"
        ]
      },
      "SequenceLinkResponse": {
        "type": "object",
        "properties": {
          "event": {
            "$ref": "#/components/schemas/Event"
          },
          "created_jobs": {
            "type": "integer"
          }
        },
        "required": [
          "event",
          "created_jobs"
        ]
      },
      "RecurrenceUpdate": {
        "type": "object",
        "properties": {
          "recurrence": {
            "type": "object",
            "properties": {
              "days": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "sun",
                    "mon",
                    "tue",
                    "wed",
                    "thu",
                    "fri",
                    "sat"
                  ]
                },
                "minItems": 1
              },
              "time": {
                "type": "string",
                "pattern": "^\\d{2}:\\d{2}$",
                "example": "20:00"
              },
              "excluded_dates": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                }
              }
            },
            "required": [
              "days",
              "time"
            ]
          },
          "regenerate_window_weeks": {
            "type": "integer",
            "minimum": 1,
            "maximum": 52,
            "default": 4
          },
          "dry_run": {
            "type": "boolean",
            "default": false
          }
        },
        "required": [
          "recurrence"
        ]
      },
      "RecurrenceUpdateResponse": {
        "type": "object",
        "properties": {
          "dry_run": {
            "type": "boolean"
          },
          "idempotent": {
            "type": "boolean"
          },
          "added": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
                },
                "scheduled_at": {
                  "type": "string",
                  "format": "date-time",
                  "example": "2026-11-09T19:00:00+01:00",
                  "description": "ISO 8601 date-time with offset."
                }
              },
              "required": [
                "scheduled_at"
              ]
            }
          },
          "cancelled": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
                },
                "scheduled_at": {
                  "type": "string",
                  "format": "date-time",
                  "example": "2026-11-09T19:00:00+01:00",
                  "description": "ISO 8601 date-time with offset."
                }
              },
              "required": [
                "scheduled_at"
              ]
            }
          },
          "kept": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
                },
                "scheduled_at": {
                  "type": "string",
                  "format": "date-time",
                  "example": "2026-11-09T19:00:00+01:00",
                  "description": "ISO 8601 date-time with offset."
                }
              },
              "required": [
                "scheduled_at"
              ]
            }
          },
          "event": {
            "$ref": "#/components/schemas/Event"
          }
        },
        "required": [
          "dry_run",
          "idempotent",
          "added",
          "cancelled",
          "kept"
        ]
      },
      "OccurrenceCreate": {
        "type": "object",
        "properties": {
          "scheduled_at_local": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2})?$",
            "example": "2026-12-07T20:00",
            "description": "Local date-time in the event's timezone, no offset."
          }
        },
        "required": [
          "scheduled_at_local"
        ]
      },
      "RetryProvisioningResponse": {
        "type": "object",
        "properties": {
          "accepted": {
            "type": "boolean"
          },
          "mode": {
            "type": "string",
            "enum": [
              "create",
              "resume",
              "repair",
              "retry"
            ]
          },
          "provisioning_status": {
            "type": [
              "string",
              "null"
            ]
          },
          "retry_available_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "accepted",
          "mode",
          "provisioning_status",
          "retry_available_at"
        ]
      },
      "CommunityUpdate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000
          },
          "modify_groups_policy": {
            "$ref": "#/components/schemas/CommunityPolicy"
          },
          "member_add_mode": {
            "$ref": "#/components/schemas/CommunityPolicy"
          }
        },
        "additionalProperties": false
      },
      "CommunityUpdateResponse": {
        "type": "object",
        "properties": {
          "community": {
            "$ref": "#/components/schemas/Community"
          },
          "applied": {
            "type": "object",
            "additionalProperties": {
              "type": "boolean"
            }
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        },
        "required": [
          "community",
          "applied",
          "errors"
        ]
      },
      "MessageUpdate": {
        "type": "object",
        "properties": {
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "timing": {
            "$ref": "#/components/schemas/Timing"
          },
          "type": {
            "$ref": "#/components/schemas/MessageType"
          },
          "text": {
            "type": "string",
            "maxLength": 10000
          },
          "media_url": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "format": "uri"
          },
          "poll": {
            "$ref": "#/components/schemas/Poll"
          },
          "ghost_mention": {
            "type": "boolean"
          },
          "link_preview": {
            "type": "boolean",
            "description": "Text messages only, default `true`. `false` sends the text without the preview card of its link (the link stays clickable). Ignored (stored `true`) on other types."
          },
          "community_update": {
            "$ref": "#/components/schemas/CommunityUpdateStepInput"
          },
          "resync": {
            "type": "boolean",
            "default": true
          }
        },
        "additionalProperties": false
      },
      "CommunityUpdateStepInput": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "name_template": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200,
            "description": "New community name. Variables: `{community_name}` (the community's normal name), `{community_description}`, `{event_name}`, `{project_name}`, `{date}`, `{time}`, and the date tokens `{J:date}`, `{J+4:date}`, `{J+4:mois}`, `{J-1:jour}` relative to the live.",
            "example": "🔴 EN LIVE · {community_name}"
          },
          "description_template": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "description": "New description (same variables; `\"\"` clears it)."
          },
          "restore_name": {
            "type": "boolean",
            "description": "Put the normal name back (exclusive with `name_template`)."
          },
          "restore_description": {
            "type": "boolean",
            "description": "Put the event's description back (exclusive with `description_template`)."
          }
        },
        "additionalProperties": false,
        "description": "Payload of a `community_update` step; required when `type` is `community_update`, refused on any other type (such a step has no `text`, `media_url`, `poll` or `ghost_mention`). Give at least one change: a name (`name_template` or `restore_name`) and/or a description (`description_template` or `restore_description`)."
      },
      "MessageCreate": {
        "type": "object",
        "properties": {
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "timing": {
            "$ref": "#/components/schemas/Timing"
          },
          "type": {
            "$ref": "#/components/schemas/MessageType"
          },
          "text": {
            "type": "string",
            "maxLength": 10000
          },
          "media_url": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "format": "uri"
          },
          "poll": {
            "$ref": "#/components/schemas/Poll"
          },
          "ghost_mention": {
            "type": "boolean"
          },
          "link_preview": {
            "type": "boolean",
            "description": "Text messages only, default `true`. `false` sends the text without the preview card of its link (the link stays clickable). Ignored (stored `true`) on other types."
          },
          "community_update": {
            "$ref": "#/components/schemas/CommunityUpdateStepInput"
          },
          "resync": {
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "type"
        ],
        "additionalProperties": false
      },
      "SequenceCreate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        },
        "required": [
          "name"
        ]
      },
      "SequenceUpdate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 200
          }
        },
        "additionalProperties": false
      },
      "MessageOrder": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "minItems": 1,
            "maxItems": 200,
            "description": "Every message id of the sequence, in the new order (at most 200)."
          },
          "resync": {
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "ids"
        ]
      },
      "ResyncResult": {
        "type": "object",
        "properties": {
          "events_resynced": {
            "type": "integer"
          },
          "canceled_jobs": {
            "type": "integer"
          },
          "created_jobs": {
            "type": "integer"
          },
          "overrides_kept": {
            "type": "integer",
            "description": "Pending sends edited by hand in the app, left as they are."
          },
          "locked_skipped": {
            "type": "integer",
            "description": "Sends already sent, in progress or frozen, left as they are."
          }
        },
        "required": [
          "events_resynced",
          "canceled_jobs",
          "created_jobs",
          "overrides_kept",
          "locked_skipped"
        ]
      },
      "ResyncPreview": {
        "type": "object",
        "properties": {
          "linked_events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "event_id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
                },
                "name": {
                  "type": "string"
                },
                "eligible": {
                  "type": "boolean"
                },
                "reason": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "future_occurrences": {
                  "type": "integer"
                },
                "jobs_to_resync": {
                  "type": "integer"
                },
                "overrides_kept": {
                  "type": "integer"
                },
                "locked_skipped": {
                  "type": "integer"
                }
              },
              "required": [
                "event_id",
                "name",
                "eligible",
                "reason",
                "future_occurrences",
                "jobs_to_resync",
                "overrides_kept",
                "locked_skipped"
              ]
            }
          }
        },
        "required": [
          "linked_events"
        ]
      },
      "ResyncRequest": {
        "type": "object",
        "properties": {
          "event_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "minItems": 1,
            "maxItems": 50,
            "description": "Defaults to every event linked to the sequence."
          }
        }
      },
      "SequenceSync": {
        "type": "object",
        "properties": {
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "messages": {
            "type": "array",
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/MessageInput"
                },
                {
                  "type": "object",
                  "properties": {},
                  "required": [
                    "external_id"
                  ]
                }
              ],
              "description": "A sequence step. Messages (`text`, media, `poll`) are posted in the community; a `community_update` step renames / re-describes it instead."
            },
            "maxItems": 200,
            "description": "The full list of steps, at most 200. The texts, poll questions and options, and community update templates of one call add up to at most 3 MiB (3,145,728 bytes, counted in UTF-8); a larger payload is refused with `400 validation_error` (field `messages`) before anything is written: split the content across several sequences or shorten the texts. Send the JSON as UTF-8: a request body above 4 MiB is refused with HTTP `413` (escaping every non-ASCII character as `\\uXXXX` can double the size of texts written in non-Latin scripts)."
          },
          "apply_to_pending_jobs": {
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "external_id",
          "name",
          "messages"
        ]
      },
      "MessageInput": {
        "type": "object",
        "properties": {
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "timing": {
            "$ref": "#/components/schemas/Timing"
          },
          "type": {
            "$ref": "#/components/schemas/MessageType"
          },
          "text": {
            "type": "string",
            "maxLength": 10000
          },
          "media_url": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "format": "uri"
          },
          "poll": {
            "$ref": "#/components/schemas/Poll"
          },
          "ghost_mention": {
            "type": "boolean"
          },
          "link_preview": {
            "type": "boolean",
            "description": "Text messages only, default `true`. `false` sends the text without the preview card of its link (the link stays clickable). Ignored (stored `true`) on other types."
          },
          "community_update": {
            "$ref": "#/components/schemas/CommunityUpdateStepInput"
          }
        },
        "required": [
          "type"
        ],
        "description": "A sequence step. Messages (`text`, media, `poll`) are posted in the community; a `community_update` step renames / re-describes it instead."
      },
      "SequenceSyncResponse": {
        "type": "object",
        "properties": {
          "sequence": {
            "$ref": "#/components/schemas/Sequence"
          },
          "created": {
            "type": "boolean"
          },
          "messages": {
            "type": "object",
            "properties": {
              "created": {
                "type": "integer"
              },
              "updated": {
                "type": "integer"
              },
              "deleted": {
                "type": "integer"
              },
              "unchanged": {
                "type": "integer"
              }
            },
            "required": [
              "created",
              "updated",
              "deleted",
              "unchanged"
            ]
          },
          "resync": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ResyncResult"
              },
              {
                "type": [
                  "object",
                  "null"
                ]
              }
            ]
          }
        },
        "required": [
          "sequence",
          "created",
          "messages",
          "resync"
        ]
      },
      "MessageMutationResponse": {
        "type": "object",
        "properties": {
          "sequence": {
            "$ref": "#/components/schemas/Sequence"
          },
          "resync": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ResyncResult"
              },
              {
                "type": [
                  "object",
                  "null"
                ]
              }
            ]
          }
        },
        "required": [
          "sequence",
          "resync"
        ]
      },
      "MediaUploadCreate": {
        "type": "object",
        "properties": {
          "kind": {
            "$ref": "#/components/schemas/MediaKind"
          },
          "filename": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "example": "visuel.jpg"
          }
        },
        "required": [
          "kind",
          "filename"
        ]
      },
      "MediaKind": {
        "type": "string",
        "enum": [
          "image",
          "video",
          "voice",
          "document"
        ]
      },
      "MediaUpload": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "upload_url": {
            "type": "string",
            "format": "uri",
            "description": "PUT the file body here (header `Content-Type` set), then call `complete`."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "max_bytes": {
            "type": "integer"
          },
          "allowed_extensions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "upload_url",
          "expires_at",
          "max_bytes",
          "allowed_extensions"
        ]
      },
      "Media": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "kind": {
            "$ref": "#/components/schemas/MediaKind"
          },
          "media_url": {
            "type": "string",
            "format": "uri",
            "description": "Use it as `media_url` of a message."
          },
          "bytes": {
            "type": "integer"
          },
          "content_type": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "kind",
          "media_url",
          "bytes",
          "content_type"
        ]
      },
      "MediaImport": {
        "type": "object",
        "properties": {
          "kind": {
            "$ref": "#/components/schemas/MediaKind"
          },
          "url": {
            "type": "string",
            "maxLength": 2000,
            "format": "uri"
          },
          "filename": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        },
        "required": [
          "kind",
          "url"
        ]
      },
      "AdHocMessageCreate": {
        "type": "object",
        "properties": {
          "occurrence_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "send_at": {
            "type": "string",
            "format": "date-time",
            "description": "At least 60 seconds in the future."
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "image",
              "video",
              "voice",
              "poll"
            ]
          },
          "text": {
            "type": "string",
            "maxLength": 10000
          },
          "media_url": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "format": "uri"
          },
          "poll": {
            "$ref": "#/components/schemas/Poll"
          },
          "label": {
            "type": "string",
            "maxLength": 60,
            "description": "Shown in the app next to the message."
          }
        },
        "required": [
          "occurrence_id",
          "send_at",
          "type"
        ]
      },
      "JobOverride": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10000
          },
          "media_url": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "format": "uri"
          }
        },
        "additionalProperties": false
      },
      "JobRetry": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "failed",
              "partial",
              "overdue",
              "force_now"
            ],
            "description": "`failed`/`partial`/`overdue`: re-queue the communities that certainly failed before sending. `force_now`: skip the automatic backoff."
          }
        },
        "required": [
          "mode"
        ]
      },
      "JobRetryResponse": {
        "type": "object",
        "properties": {
          "job": {
            "$ref": "#/components/schemas/Job"
          },
          "deliveries_reset": {
            "type": "integer"
          }
        },
        "required": [
          "job",
          "deliveries_reset"
        ]
      },
      "BroadcastCreate": {
        "type": "object",
        "properties": {
          "community_whatsapp_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "minItems": 1,
            "maxItems": 200,
            "description": "From `GET /communities` (`whatsapp_id`)."
          },
          "type": {
            "$ref": "#/components/schemas/SendableMessageType"
          },
          "text": {
            "type": "string",
            "maxLength": 10000
          },
          "media_url": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "format": "uri"
          },
          "poll": {
            "$ref": "#/components/schemas/Poll"
          },
          "scheduled_at": {
            "type": "string",
            "format": "date-time",
            "description": "Omit to send now (with a random delay between communities)."
          },
          "scheduled_at_local": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2})?$",
            "description": "Local time in the account's timezone, instead of `scheduled_at`."
          }
        },
        "required": [
          "community_whatsapp_ids",
          "type"
        ]
      },
      "BroadcastCancelResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "canceled"
            ]
          },
          "changed": {
            "type": "boolean"
          }
        },
        "required": [
          "status",
          "changed"
        ]
      },
      "MemberWebhookConfig": {
        "type": "object",
        "properties": {
          "url": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "format": "uri",
            "description": "HTTPS URL, or null to disable."
          }
        },
        "required": [
          "url"
        ]
      },
      "MemberWebhook": {
        "type": "object",
        "properties": {
          "url": {
            "type": [
              "string",
              "null"
            ]
          },
          "secret_configured": {
            "type": "boolean"
          },
          "signing_secret": {
            "type": "string",
            "description": "Only in the response that created it. Never shown again."
          },
          "recent_deliveries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                },
                "attempt_count": {
                  "type": "integer"
                },
                "last_http_status": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "last_error_code": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time",
                  "example": "2026-11-09T19:00:00+01:00",
                  "description": "ISO 8601 date-time with offset."
                },
                "completed_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "example": "2026-11-09T19:00:00+01:00",
                  "description": "ISO 8601 date-time with offset."
                }
              },
              "required": [
                "id",
                "type",
                "status",
                "attempt_count",
                "last_http_status",
                "last_error_code",
                "created_at",
                "completed_at"
              ]
            }
          }
        },
        "required": [
          "url",
          "secret_configured",
          "recent_deliveries"
        ]
      },
      "MemberWebhookRotate": {
        "type": "object",
        "properties": {
          "signing_secret": {
            "type": "string"
          },
          "rotated_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "signing_secret",
          "rotated_at"
        ]
      },
      "MemberWebhookTest": {
        "type": "object",
        "properties": {
          "delivery_id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "http_status": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "delivery_id",
          "status",
          "http_status"
        ]
      },
      "BackupAdmin": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean",
            "description": "False while the feature is switched off server side."
          },
          "default": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "target": {
                "$ref": "#/components/schemas/MaskedPhone"
              },
              "revision": {
                "type": "integer"
              },
              "updated_at": {
                "type": "string",
                "format": "date-time",
                "example": "2026-11-09T19:00:00+01:00",
                "description": "ISO 8601 date-time with offset."
              }
            },
            "required": [
              "target",
              "revision",
              "updated_at"
            ]
          },
          "future_rule": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "target": {
                "$ref": "#/components/schemas/MaskedPhone"
              },
              "revision": {
                "type": "integer"
              },
              "start_occurrence_id": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid",
                "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
              },
              "starts_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "example": "2026-11-09T19:00:00+01:00",
                "description": "ISO 8601 date-time with offset."
              }
            },
            "required": [
              "enabled",
              "target",
              "revision",
              "start_occurrence_id",
              "starts_at"
            ]
          },
          "communities": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
                },
                "occurrence_id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
                },
                "scheduled_at": {
                  "type": "string",
                  "format": "date-time",
                  "example": "2026-11-09T19:00:00+01:00",
                  "description": "ISO 8601 date-time with offset."
                },
                "name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "number": {
                  "type": "integer"
                },
                "selectable": {
                  "type": "boolean"
                },
                "current": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "properties": {
                    "target": {
                      "$ref": "#/components/schemas/MaskedPhone"
                    },
                    "status": {
                      "type": "string"
                    },
                    "verified_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time",
                      "example": "2026-11-09T19:00:00+01:00",
                      "description": "ISO 8601 date-time with offset."
                    }
                  },
                  "required": [
                    "target",
                    "status",
                    "verified_at"
                  ]
                }
              },
              "required": [
                "id",
                "occurrence_id",
                "scheduled_at",
                "name",
                "number",
                "selectable",
                "current"
              ]
            }
          }
        },
        "required": [
          "available",
          "default",
          "future_rule",
          "communities"
        ]
      },
      "MaskedPhone": {
        "type": "object",
        "properties": {
          "phone_masked": {
            "type": "string"
          }
        },
        "required": [
          "phone_masked"
        ]
      },
      "BackupAdminDefault": {
        "type": "object",
        "properties": {
          "phone_e164": {
            "type": "string",
            "pattern": "^\\+[1-9][0-9]{7,14}$",
            "example": "+33612345678"
          },
          "expected_revision": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "default": null
          },
          "consent_confirmed": {
            "type": "boolean",
            "enum": [
              true
            ],
            "description": "You confirm the person agrees to be made administrator."
          },
          "contact_requirements_confirmed": {
            "type": "boolean",
            "enum": [
              true
            ],
            "description": "You confirm both numbers have each other saved as contacts."
          }
        },
        "required": [
          "phone_e164",
          "consent_confirmed",
          "contact_requirements_confirmed"
        ]
      },
      "BackupAdminPreview": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "apply",
              "retry",
              "stop",
              "enable_rule",
              "stop_rule"
            ]
          },
          "community_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "maxItems": 250,
            "description": "Required for apply, retry and stop. apply and retry take one community at a time until bulk protection opens (409 `bulk_apply_disabled`)."
          },
          "target": {
            "type": "object",
            "properties": {
              "source": {
                "type": "string",
                "enum": [
                  "manual_phone",
                  "event_default"
                ]
              },
              "phone_e164": {
                "type": "string",
                "pattern": "^\\+[1-9][0-9]{7,14}$",
                "example": "+33612345678"
              }
            },
            "required": [
              "source"
            ],
            "description": "Required for apply and enable_rule."
          },
          "start_occurrence_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21",
            "description": "For enable_rule: first occurrence covered."
          }
        },
        "required": [
          "action"
        ]
      },
      "BackupAdminPreviewResponse": {
        "type": "object",
        "properties": {
          "preview_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "action": {
            "type": "string"
          },
          "target": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MaskedPhone"
              },
              {
                "type": [
                  "object",
                  "null"
                ]
              }
            ]
          },
          "community_count": {
            "type": "integer"
          },
          "affected_count": {
            "type": "integer"
          },
          "communities": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
                },
                "occurrence_id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
                },
                "disposition": {
                  "type": "string"
                },
                "status": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "id",
                "occurrence_id",
                "disposition",
                "status"
              ]
            }
          }
        },
        "required": [
          "preview_id",
          "expires_at",
          "action",
          "target",
          "community_count",
          "affected_count",
          "communities"
        ]
      },
      "BackupAdminConfirm": {
        "type": "object",
        "properties": {
          "preview_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "consent_confirmed": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "contact_requirements_confirmed": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        },
        "required": [
          "preview_id",
          "consent_confirmed",
          "contact_requirements_confirmed"
        ]
      },
      "BackupAdminConfirmResponse": {
        "type": "object",
        "properties": {
          "accepted": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "action": {
            "type": "string"
          },
          "affected_count": {
            "type": "integer"
          }
        },
        "required": [
          "accepted",
          "action",
          "affected_count"
        ]
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "url": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          "enabled": {
            "type": "boolean"
          },
          "disabled_reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "user",
              "failures",
              null
            ],
            "description": "`failures`: paused automatically after 50 consecutive deliveries failed for good; fix the endpoint, then `enabled: true`."
          },
          "consecutive_failures": {
            "type": "integer",
            "description": "Deliveries that failed for good since the last success."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "disabled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "id",
          "url",
          "description",
          "events",
          "enabled",
          "disabled_reason",
          "consecutive_failures",
          "created_at",
          "updated_at",
          "disabled_at"
        ]
      },
      "WebhookEventType": {
        "type": "string",
        "enum": [
          "member.joined",
          "job.sent",
          "job.failed",
          "community.created",
          "community.full",
          "channel.disconnected",
          "event.paused",
          "broadcast.completed"
        ],
        "description": "`member.joined`: Someone joined a WhatsApp community of one of your events. `job.sent`: A scheduled message was sent (all or part of its communities). `job.failed`: A scheduled message failed for good (no more automatic retry). `community.created`: A WhatsApp community was created for an occurrence. `community.full`: A community reached its switch threshold; the next one takes over. `channel.disconnected`: The WhatsApp number went offline and needs a new QR scan. `event.paused`: An event was paused (through the API). `broadcast.completed`: A broadcast finished (completed, failed or requires review)."
      },
      "WebhookEndpointList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEndpoint"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "WebhookEndpointCreate": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "minLength": 12,
            "maxLength": 2048,
            "pattern": "^https:\\/\\/\\S+$",
            "example": "https://hooks.example.com/groupilot"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            },
            "minItems": 1,
            "maxItems": 8
          },
          "description": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "example": "Make scenario"
          }
        },
        "required": [
          "url",
          "events"
        ]
      },
      "WebhookEndpointUpdate": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "minLength": 12,
            "maxLength": 2048,
            "pattern": "^https:\\/\\/\\S+$",
            "example": "https://hooks.example.com/groupilot"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            },
            "minItems": 1,
            "maxItems": 8
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 120,
            "example": "Make scenario"
          },
          "enabled": {
            "type": "boolean"
          }
        }
      },
      "WebhookEndpointCreated": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEndpoint"
          },
          {
            "type": "object",
            "properties": {
              "signing_secret": {
                "type": "string",
                "description": "Shown once. HMAC-SHA256 key of the `X-Groupilot-Signature` header.",
                "example": "whsec_…"
              }
            },
            "required": [
              "signing_secret"
            ]
          }
        ]
      },
      "WebhookRotateResponse": {
        "type": "object",
        "properties": {
          "signing_secret": {
            "type": "string"
          },
          "rotated_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "signing_secret",
          "rotated_at"
        ]
      },
      "WebhookTestResponse": {
        "type": "object",
        "properties": {
          "delivery_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "status": {
            "type": "string",
            "enum": [
              "delivered",
              "failed",
              "pending"
            ]
          },
          "http_status": {
            "type": [
              "integer",
              "null"
            ]
          },
          "error_code": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "delivery_id",
          "status",
          "http_status",
          "error_code"
        ]
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "type": {
            "type": "string",
            "example": "job.sent"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "delivered",
              "failed",
              "skipped"
            ]
          },
          "attempt_count": {
            "type": "integer"
          },
          "max_attempts": {
            "type": "integer"
          },
          "last_http_status": {
            "type": [
              "integer",
              "null"
            ]
          },
          "last_error_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "last_attempt_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "next_attempt_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "id",
          "type",
          "status",
          "attempt_count",
          "max_attempts",
          "last_http_status",
          "last_error_code",
          "occurred_at",
          "created_at",
          "last_attempt_at",
          "next_attempt_at",
          "completed_at"
        ]
      },
      "WebhookDeliveryList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookDelivery"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "WebhookEnvelope": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21",
            "description": "Delivery id, also sent as `X-Groupilot-Event-Id`. Retries reuse it: deduplicate on it."
          },
          "type": {
            "$ref": "#/components/schemas/WebhookEventType"
          },
          "version": {
            "type": "string",
            "enum": [
              "1"
            ]
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "project_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "data": {
            "type": "object",
            "additionalProperties": {},
            "description": "Event-specific fields; ids are the public API ids."
          }
        },
        "required": [
          "id",
          "type",
          "version",
          "occurred_at",
          "project_id",
          "data"
        ],
        "description": "Body of every webhook POST. Headers: `X-Groupilot-Event-Id`, `X-Groupilot-Event-Type`, `X-Groupilot-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\" with the endpoint's signing secret>`. Answer 2xx within 5 seconds; anything else is retried 6 times over about 24 hours (1 min, 5 min, 30 min, 2 h, 6 h, 15 h)."
      },
      "PartnerConnection": {
        "type": "object",
        "properties": {
          "grant_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "client_id": {
            "type": "string",
            "example": "gpc_…"
          },
          "project_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "project_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "user_id": {
            "type": "string",
            "format": "uuid",
            "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "scopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Scope"
            }
          },
          "signup_via_partner": {
            "type": "boolean",
            "description": "The account was created through the partner's signup link (`/signup?partner=<slug>`)."
          },
          "connected_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "last_used_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          },
          "revoked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-11-09T19:00:00+01:00",
            "description": "ISO 8601 date-time with offset."
          }
        },
        "required": [
          "grant_id",
          "client_id",
          "project_id",
          "project_name",
          "user_id",
          "email",
          "name",
          "scopes",
          "signup_via_partner",
          "connected_at",
          "last_used_at",
          "revoked_at"
        ]
      },
      "PartnerConnectionList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PartnerConnection"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "JobList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Job"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "items",
          "next_cursor"
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/me": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "The account behind this key",
        "description": "Returns the project (one WhatsApp number = one project), its billing and number state, the key's scopes and the limits that apply. A good first call to check a key.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Account summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "Meta"
        ],
        "summary": "Liveness",
        "description": "No authentication. Returns 200 when the API is up.",
        "responses": {
          "200": {
            "description": "Up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/events": {
      "get": {
        "tags": [
          "Events"
        ],
        "summary": "List events",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/EventStatus"
                },
                {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EventStatus"
                  }
                }
              ],
              "description": "Filter by status (repeatable). Default: every status except `archived`."
            },
            "required": false,
            "description": "Filter by status (repeatable). Default: every status except `archived`.",
            "name": "status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Events of the account, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Events"
        ],
        "summary": "Create an event",
        "description": "Send an `Idempotency-Key` header to make retries safe (24 h).",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created. A recurring event gets its occurrences created by the scheduler within minutes; a punctual event needs `POST /events/{id}/occurrences`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventDetail"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}": {
      "get": {
        "tags": [
          "Events"
        ],
        "summary": "Read an event",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The event with its current smart link destination.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventDetail"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Events"
        ],
        "summary": "Change an event's settings",
        "description": "The slug (smart link) and the timezone cannot change; `name` can (the link and the existing communities keep their names, the next communities use the new one). Status changes go through `pause` / `resume`; the recurrence through `recurrence`; the sequence through `sequence`.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventUpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/occurrences": {
      "get": {
        "tags": [
          "Occurrences"
        ],
        "summary": "List the occurrences of an event",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "upcoming",
                "past",
                "attention"
              ],
              "default": "upcoming"
            },
            "required": false,
            "name": "filter",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "One page of 20 occurrences.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OccurrenceList"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Occurrences"
        ],
        "summary": "Add an occurrence",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OccurrenceCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created; its sends are scheduled if a sequence is linked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Occurrence"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/occurrences/{id}": {
      "get": {
        "tags": [
          "Occurrences"
        ],
        "summary": "Read an occurrence with its communities",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The occurrence, its communities and the creation state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OccurrenceDetail"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/communities": {
      "get": {
        "tags": [
          "Communities"
        ],
        "summary": "List every community of the connected number",
        "description": "Communities created by Groupilot plus the external ones the number administers. The list is the set of valid broadcast targets. The external part is cached for 5 minutes.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Communities, most recent live first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommunityList"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/communities/{id}": {
      "get": {
        "tags": [
          "Communities"
        ],
        "summary": "Read a community",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The community.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Community"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Communities"
        ],
        "summary": "Rename, describe or change the policies of a community",
        "description": "Applied on WhatsApp right away; the response reports each field.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommunityUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Applied (possibly partially).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommunityUpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after a few seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sequences": {
      "get": {
        "tags": [
          "Sequences"
        ],
        "summary": "List sequences",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Sequences of the account, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceList"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Sequences"
        ],
        "summary": "Create a sequence",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SequenceCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created, empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceSummary"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sequences/{id}": {
      "get": {
        "tags": [
          "Sequences"
        ],
        "summary": "Read a sequence with its messages",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The sequence, its messages in order and the events using it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sequence"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Sequences"
        ],
        "summary": "Rename a sequence",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SequenceUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceSummary"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Sequences"
        ],
        "summary": "Delete a sequence",
        "description": "Refused (409) while an active or paused event uses it, unless `force=true`: the events are then unlinked and their pending sends canceled.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                {
                  "type": "string",
                  "enum": [
                    "false"
                  ]
                }
              ],
              "default": "false"
            },
            "required": false,
            "name": "force",
            "in": "query"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/jobs": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "List the scheduled messages of an event",
        "description": "Every message instance (one per occurrence and sequence message, plus ad hoc messages), with its delivery state. Cursor pagination; the cursor is only valid with the same `order`.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/JobStatus"
                },
                {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/JobStatus"
                  }
                }
              ]
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": false,
            "name": "occurrence_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "description": "WhatsApp community id (see /communities)."
            },
            "required": false,
            "description": "WhatsApp community id (see /communities).",
            "name": "community_id",
            "in": "query"
          },
          {
            "schema": {
              "$ref": "#/components/schemas/MessageType"
            },
            "required": false,
            "description": "`text`, `image`, `video`, `voice`, `document`, `poll`: a message posted in the community. `community_update`: a step that changes the community's name and/or description at its time (nothing is posted; WhatsApp shows a system line).",
            "name": "content_type",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "required": false,
            "name": "from",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "required": false,
            "name": "to",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "asc"
            },
            "required": false,
            "name": "order",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "One page of messages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobList"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{id}": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "Read a scheduled message",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Messages"
        ],
        "summary": "Change the content of a pending message",
        "description": "Only while `editable` (not yet attempted, subscription active, not a poll, not a community update: 409 `community_update_not_editable`). The override wins over the sequence until the message is sent.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobOverride"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{id}/deliveries": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "List the deliveries of a message, one per community",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "One page of deliveries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryList"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts": {
      "get": {
        "tags": [
          "Broadcasts"
        ],
        "summary": "List broadcasts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Broadcasts of the account, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BroadcastList"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Broadcasts"
        ],
        "summary": "Send a message to several communities",
        "description": "Now or at a given time, with a random delay between communities. 8 per day per account, 200 communities per broadcast. `send` scope.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BroadcastCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Broadcast"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts/{id}": {
      "get": {
        "tags": [
          "Broadcasts"
        ],
        "summary": "Read a broadcast",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The broadcast.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Broadcast"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts/{id}/recipients": {
      "get": {
        "tags": [
          "Broadcasts"
        ],
        "summary": "List the recipients of a broadcast",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "maximum": 10000,
              "default": 0
            },
            "required": false,
            "name": "page",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Pages of 50 communities.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BroadcastRecipientList"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/notifications": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "List notifications",
        "description": "The account's notifications (send failures, disconnections, full communities…), newest first.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "maximum": 10000,
              "default": 0
            },
            "required": false,
            "name": "offset",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                {
                  "type": "string",
                  "enum": [
                    "false"
                  ]
                }
              ],
              "default": "false"
            },
            "required": false,
            "name": "unread_only",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Notifications.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationList"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/pause": {
      "post": {
        "tags": [
          "Events"
        ],
        "summary": "Pause an event",
        "description": "Nothing is sent and no scheduled community is created while paused (an overflow community can still open if a community fills up); the smart link goes to the fallback URL if set. Resume later; messages whose time passed during the pause are not sent.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Paused (or already paused).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PauseResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/resume": {
      "post": {
        "tags": [
          "Events"
        ],
        "summary": "Resume a paused event",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Active again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PauseResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/sequence": {
      "put": {
        "tags": [
          "Events"
        ],
        "summary": "Link or unlink a sequence",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SequenceLink"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Linked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceLinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/recurrence": {
      "put": {
        "tags": [
          "Events"
        ],
        "summary": "Change the recurrence",
        "description": "Occurrences that no longer match are canceled with their pending sends; new ones are created with their sends. Past occurrences are kept. Use `dry_run` to preview.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurrenceUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Diff (and the event when applied).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurrenceUpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/occurrences/{id}/retry-provisioning": {
      "post": {
        "tags": [
          "Occurrences"
        ],
        "summary": "Retry the community creation",
        "description": "Only when the occurrence needs attention (`can_retry`). The scheduler does retry by itself; this forces it on its next tick.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted (or not yet due).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RetryProvisioningResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sequences/{id}/messages": {
      "post": {
        "tags": [
          "Sequences"
        ],
        "summary": "Add a message",
        "description": "By default the pending sends of the linked events are resynchronised (`resync: false` to batch several changes, then `POST /sequences/{id}/resync`).",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Added.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sequences/{id}/messages/{message_id}": {
      "patch": {
        "tags": [
          "Sequences"
        ],
        "summary": "Change a message",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "message_id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Sequences"
        ],
        "summary": "Remove a message",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "message_id",
            "in": "path"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                {
                  "type": "string",
                  "enum": [
                    "false"
                  ]
                }
              ],
              "default": "true"
            },
            "required": false,
            "name": "resync",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Removed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageMutationResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sequences/{id}/messages/order": {
      "put": {
        "tags": [
          "Sequences"
        ],
        "summary": "Reorder the messages",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageOrder"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reordered.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageMutationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sequences/{id}/resync": {
      "get": {
        "tags": [
          "Sequences"
        ],
        "summary": "Preview a resynchronisation",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "What a resync would change, per linked event.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResyncPreview"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Sequences"
        ],
        "summary": "Resynchronise the pending sends with the sequence",
        "description": "Refused with `409 conflict`, before anything changes, when it would schedule more than 20,000 sends in one call: pass fewer `event_ids`.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResyncRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResyncResult"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sequences/sync": {
      "put": {
        "tags": [
          "Sequences"
        ],
        "summary": "Create or update a sequence by your own id",
        "description": "Idempotent: send the whole sequence each time your platform saves it. Messages are matched by `external_id`; missing ones are removed. With `apply_to_pending_jobs` (default) the pending sends of the linked events are resynchronised; sends already sent, in progress or edited by hand are left untouched. At most 2 calls per minute per sequence. Size: The texts, poll questions and options, and community update templates of one call add up to at most 3 MiB (3,145,728 bytes, counted in UTF-8); a larger payload is refused with `400 validation_error` (field `messages`) before anything is written: split the content across several sequences or shorten the texts. Send the JSON as UTF-8: a request body above 4 MiB is refused with HTTP `413` (escaping every non-ASCII character as `\\uXXXX` can double the size of texts written in non-Latin scripts). Work: when the resync would schedule more than 20,000 sends (upcoming occurrences of the linked events × messages), the call is refused with `409 conflict` before anything is written; link fewer events, or pass `apply_to_pending_jobs: false` and resync event by event (`POST /sequences/{id}/resync` with `event_ids`).",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SequenceSync"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Synchronised.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceSyncResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Request body larger than 4 MiB (`payload_too_large`). Split it into several calls.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Idempotency-Key reused with a different request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/media/uploads": {
      "post": {
        "tags": [
          "Media"
        ],
        "summary": "Start an upload",
        "description": "Returns a one-time URL to PUT the file to (10 minutes), then call `complete`. Limits: image 16 MB (jpg, png), video 40 MB (mp4, mov, 3gp), voice 16 MB (ogg, m4a, wav, mp3), document 100 MB.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MediaUploadCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload slot.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MediaUpload"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/media/uploads/{id}/complete": {
      "post": {
        "tags": [
          "Media"
        ],
        "summary": "Finish an upload",
        "description": "Checks the uploaded file's type and size; a file outside the limits is deleted and refused.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Ready to use.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Media"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/media/import": {
      "post": {
        "tags": [
          "Media"
        ],
        "summary": "Import a file from a public URL",
        "description": "Groupilot downloads the file (HTTPS, public host, 40 MB max) and stores it.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MediaImport"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Media"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/messages": {
      "post": {
        "tags": [
          "Messages"
        ],
        "summary": "Schedule a one-off message on an occurrence",
        "description": "Sent to the occurrence's communities at `send_at`. Content is frozen at creation. 30 per day per account. `send` scope.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdHocMessageCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Scheduled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{id}/cancel": {
      "post": {
        "tags": [
          "Messages"
        ],
        "summary": "Cancel a pending message",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Canceled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{id}/retry": {
      "post": {
        "tags": [
          "Messages"
        ],
        "summary": "Retry a failed message",
        "description": "Re-queues only the communities where the send certainly failed before leaving; a send WhatsApp did not confirm is never repeated. `send` scope.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobRetry"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Re-queued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRetryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts/{id}/cancel": {
      "post": {
        "tags": [
          "Broadcasts"
        ],
        "summary": "Cancel a scheduled broadcast",
        "description": "Only before the sending starts.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Canceled (idempotent).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BroadcastCancelResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/member-webhook": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Read the member-join webhook of an event",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Configuration and last deliveries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberWebhook"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Set the member-join webhook",
        "description": "Groupilot POSTs `member.joined` to this URL when someone joins a community of the event, signed with `X-Groupilot-Signature: t=…,v1=…` (HMAC-SHA256 of `<t>.<body>`). The signing secret is returned once.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberWebhookConfig"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberWebhook"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/member-webhook/rotate-secret": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Rotate the signing secret",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "New secret, shown once.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberWebhookRotate"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/member-webhook/test": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a test delivery",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Attempted right away.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberWebhookTest"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/backup-admin": {
      "get": {
        "tags": [
          "Events"
        ],
        "summary": "Read the backup administrator settings",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Default number, future rule, communities.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupAdmin"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Events"
        ],
        "summary": "Set the default backup administrator number",
        "description": "The number is checked on WhatsApp first, so this route is limited to 6 calls per minute per account, shared with the preview. Both numbers must have each other saved as contacts, or WhatsApp may flag the addition. Nothing is applied until a preview is confirmed.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BackupAdminDefault"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupAdmin"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Idempotency-Key reused with a different request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/backup-admin/preview": {
      "post": {
        "tags": [
          "Events"
        ],
        "summary": "Preview a backup administrator change",
        "description": "Returns what would change, with a `preview_id` valid 10 minutes. Confirm it with `confirm`. 6 calls per minute per account, shared with `PUT /events/{id}/backup-admin`.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BackupAdminPreview"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Preview.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupAdminPreviewResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Idempotency-Key reused with a different request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/backup-admin/confirm": {
      "post": {
        "tags": [
          "Events"
        ],
        "summary": "Confirm a backup administrator preview",
        "description": "Irreversible on WhatsApp for the communities concerned. Both acknowledgements are mandatory.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BackupAdminConfirm"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted; applied by the scheduler within minutes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupAdminConfirmResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook endpoints",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Endpoints of the account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointList"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Create a webhook endpoint",
        "description": "HTTPS, public host only (no private address, no credentials in the URL). At most 5 endpoints per account. The signing secret is returned once.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointCreated"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The resource is in a state that forbids this action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Get a webhook endpoint",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Change a webhook endpoint",
        "description": "`enabled: false` pauses deliveries (nothing is queued while paused); `enabled: true` resumes, including after an automatic pause (50 consecutive failures), and resets the failure count.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete a webhook endpoint",
        "description": "Its delivery history goes with it.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/rotate-secret": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Rotate the signing secret",
        "description": "The new secret applies to the next deliveries; update your verifier first, then rotate.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "New secret, shown once.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookRotateResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a test delivery",
        "description": "Posts a `webhook.test` envelope now and returns the outcome of the first attempt.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "First attempt outcome.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/deliveries": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List deliveries of an endpoint",
        "description": "Newest first, 30 days of history.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "6f1c2d2e-0c1a-4a7b-9d2e-1b7f3a9c5e21"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-11-09T19:00:00+01:00",
              "description": "Only deliveries created before this instant (pagination)."
            },
            "required": false,
            "description": "Only deliveries created before this instant (pagination).",
            "name": "before",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Deliveries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryList"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or malformed JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Scope missing, API not enabled for this account, or action not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (or not yours).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/partner/connections": {
      "get": {
        "tags": [
          "Partners"
        ],
        "summary": "List the accounts connected to the partner's apps",
        "description": "For integration partners only. Every Groupilot account that authorized one of the partner's OAuth apps, with the account's email (it consented to the connection), the connected WhatsApp account and whether it signed up through the partner. Revoked connections are included with `revoked_at` set.",
        "security": [
          {
            "partnerKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Connections, newest first (1000 max).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerConnectionList"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}
