API reference

Mirage apps and bots

Applications, bot users and tokens, installing into servers, slash commands, interactions and events.
GET/v1/hooks/messaging/apps/:appId/icon

An app's image icon (a redirect), when it has one. No authentication.

Auth
None.

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 404No icon.
curl 'https://api.cactive.com.au/v1/hooks/messaging/apps/{appId}/icon'
Send it from this page with your session or a key.
POST/v1/hooks/messaging/webhooks/:appId/:token

A follow-up message from the app's bot (content), as a reply to the original response. The interaction's token (15 minutes) is the only credential.

Auth
None.

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

  • token

    A secret from a link: an issue automation rule's incoming-webhook token (shown once when issued), a map's share link, a notification recipient's confirm and unsubscribe link, a Drive public link (/l/<token>), a Vehicles drive's share link, or a Mirage interaction's token (itk_…, sent with the interaction, good for 15 minutes), or the token in the link to a file of a message Mirage sent to Discord, or a Marketing link's sealed token (a tracked click, the open pixel, unsubscribe and the preference centre, a double opt-in confirmation); or a Food recipe's public link (/r/<token>) or a household's calendar feed.

curl -X POST 'https://api.cactive.com.au/v1/hooks/messaging/webhooks/{appId}/{token}'
Send it from this page with your session or a key.

Response 201

{
  message: {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot: "server"
      avatarUrl: null
    } | {
      avatarUrl: null | string
      external?: "discord" | "webhook"
      bot?: "platform" | "server" | "bot"
      userId: string
      name: string
    }
    type: "default" | "join" | "system" | "reply" | "pin" | "follow"
    content: string
    replyTo: null | {
      author: {
        avatarUrl: null | string
        external?: "discord" | "webhook"
        bot?: "platform" | "server" | "bot"
        userId: string
        name: string
      }
      content: string
      messageId: string
    } | {
      deleted: boolean
      messageId: string
    }
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: {
      url: string
      durationSecs?: null | number
      waveform?: string
      attachmentId: string
      name: string
      mime: string
      size: number
      width: null | number
      height: null | number
    }[]
    reactions: {
      emoji: string
      count: number
      me: boolean
    }[]
    pinned: boolean
    thread: null | {
      threadId: string
      name: string
      messageCount: number
      lastActivityAt: number
      archived: boolean
    }
    poll: null | {
      question: string
      answers: {
        answerId: string
        text: string
        emoji: null | string
        count: number
      }[]
      multiple: boolean
      expiresAt: number
      closed: boolean
      total: number
      mine: string[]
    }
    embeds: {
      url: string
      type: "link" | "video" | "image" | "gifv" | "rich"
      title: null | string
      description: null | string
      siteName: null | string
      author: null | string
      color: null | string
      thumbnail: boolean
      image: null | {
        url: string
        width: null | number
        height: null | number
      }
      video: null | {
        url: string
        width: null | number
        height: null | number
      }
      gif: null | {
        url: string
        width: null | number
        height: null | number
      }
      provider: null | string
      authorUrl: null | string
      authorIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      thumb: null | {
        url: string
        width: null | number
        height: null | number
      }
      fields: {
        name: string
        value: string
        inline: boolean
      }[]
      footer: null | string
      footerIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      timestamp: null | number
      source: null | string
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null | string
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null | {
      content: string
      attachments: {
        attachmentId: string
        name: string
        mime: string
        size: number
        width: null | number
        height: null | number
        url: string
      }[]
      embeds: {
        url: string
        type: "link" | "video" | "image" | "gifv" | "rich"
        title: null | string
        description: null | string
        siteName: null | string
        author: null | string
        color: null | string
        thumbnail: boolean
        image: null | {
          url: string
          width: null | number
          height: null | number
        }
        video: null | {
          url: string
          width: null | number
          height: null | number
        }
        gif: null | {
          url: string
          width: null | number
          height: null | number
        }
        provider: null | string
        authorUrl: null | string
        authorIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        thumb: null | {
          url: string
          width: null | number
          height: null | number
        }
        fields: {
          name: string
          value: string
          inline: boolean
        }[]
        footer: null | string
        footerIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        timestamp: null | number
        source: null | string
      }[]
      origin: {
        serverId: string
        channelId: string
        messageId: string
        createdAt: number
      }
    }
    published: boolean
    crosspost: null | {
      serverId: string
      channelId: string
      messageId: string
      serverName: string
      channelName: string
      serverIcon: null | string
    }
    display: null | {
      source: "discord" | "webhook"
      name: null | string
      avatarUrl: null | string
      linked: boolean
      externalId: null | string
      externalAuthorId: null | string
    }
    stickers: {
      stickerId: string
      name: string
      format: "gif" | "png" | "webp" | "apng" | "lottie"
    }[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
  } | {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot?: "platform" | "server" | "bot"
      avatarUrl: null | string
    }
    type: "default"
    content: string
    replyTo: null
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: unknown[]
    reactions: unknown[]
    pinned: boolean
    thread: null
    poll: null
    embeds: unknown[]
    stickers: unknown[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null
    published: boolean
    crosspost: null
    display: null
    ephemeral: boolean
    thinking: boolean
  }
}
PATCH/v1/hooks/messaging/webhooks/:appId/:token/messages/@original

Edits the original response to an interaction, or posts it after a deferred answer (content).

Auth
None.

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

  • token

    A secret from a link: an issue automation rule's incoming-webhook token (shown once when issued), a map's share link, a notification recipient's confirm and unsubscribe link, a Drive public link (/l/<token>), a Vehicles drive's share link, or a Mirage interaction's token (itk_…, sent with the interaction, good for 15 minutes), or the token in the link to a file of a message Mirage sent to Discord, or a Marketing link's sealed token (a tracked click, the open pixel, unsubscribe and the preference centre, a double opt-in confirmation); or a Food recipe's public link (/r/<token>) or a household's calendar feed.

curl -X PATCH 'https://api.cactive.com.au/v1/hooks/messaging/webhooks/{appId}/{token}/messages/@original'
Send it from this page with your session or a key.

Response 200

{
  message: {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot: "server"
      avatarUrl: null
    } | {
      avatarUrl: null | string
      external?: "discord" | "webhook"
      bot?: "platform" | "server" | "bot"
      userId: string
      name: string
    }
    type: "default" | "join" | "system" | "reply" | "pin" | "follow"
    content: string
    replyTo: null | {
      author: {
        avatarUrl: null | string
        external?: "discord" | "webhook"
        bot?: "platform" | "server" | "bot"
        userId: string
        name: string
      }
      content: string
      messageId: string
    } | {
      deleted: boolean
      messageId: string
    }
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: {
      url: string
      durationSecs?: null | number
      waveform?: string
      attachmentId: string
      name: string
      mime: string
      size: number
      width: null | number
      height: null | number
    }[]
    reactions: {
      emoji: string
      count: number
      me: boolean
    }[]
    pinned: boolean
    thread: null | {
      threadId: string
      name: string
      messageCount: number
      lastActivityAt: number
      archived: boolean
    }
    poll: null | {
      question: string
      answers: {
        answerId: string
        text: string
        emoji: null | string
        count: number
      }[]
      multiple: boolean
      expiresAt: number
      closed: boolean
      total: number
      mine: string[]
    }
    embeds: {
      url: string
      type: "link" | "video" | "image" | "gifv" | "rich"
      title: null | string
      description: null | string
      siteName: null | string
      author: null | string
      color: null | string
      thumbnail: boolean
      image: null | {
        url: string
        width: null | number
        height: null | number
      }
      video: null | {
        url: string
        width: null | number
        height: null | number
      }
      gif: null | {
        url: string
        width: null | number
        height: null | number
      }
      provider: null | string
      authorUrl: null | string
      authorIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      thumb: null | {
        url: string
        width: null | number
        height: null | number
      }
      fields: {
        name: string
        value: string
        inline: boolean
      }[]
      footer: null | string
      footerIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      timestamp: null | number
      source: null | string
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null | string
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null | {
      content: string
      attachments: {
        attachmentId: string
        name: string
        mime: string
        size: number
        width: null | number
        height: null | number
        url: string
      }[]
      embeds: {
        url: string
        type: "link" | "video" | "image" | "gifv" | "rich"
        title: null | string
        description: null | string
        siteName: null | string
        author: null | string
        color: null | string
        thumbnail: boolean
        image: null | {
          url: string
          width: null | number
          height: null | number
        }
        video: null | {
          url: string
          width: null | number
          height: null | number
        }
        gif: null | {
          url: string
          width: null | number
          height: null | number
        }
        provider: null | string
        authorUrl: null | string
        authorIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        thumb: null | {
          url: string
          width: null | number
          height: null | number
        }
        fields: {
          name: string
          value: string
          inline: boolean
        }[]
        footer: null | string
        footerIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        timestamp: null | number
        source: null | string
      }[]
      origin: {
        serverId: string
        channelId: string
        messageId: string
        createdAt: number
      }
    }
    published: boolean
    crosspost: null | {
      serverId: string
      channelId: string
      messageId: string
      serverName: string
      channelName: string
      serverIcon: null | string
    }
    display: null | {
      source: "discord" | "webhook"
      name: null | string
      avatarUrl: null | string
      linked: boolean
      externalId: null | string
      externalAuthorId: null | string
    }
    stickers: {
      stickerId: string
      name: string
      format: "gif" | "png" | "webp" | "apng" | "lottie"
    }[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
  } | {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot?: "platform" | "server" | "bot"
      avatarUrl: null | string
    }
    type: "default"
    content: string
    replyTo: null
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: unknown[]
    reactions: unknown[]
    pinned: boolean
    thread: null
    poll: null
    embeds: unknown[]
    stickers: unknown[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null
    published: boolean
    crosspost: null
    display: null
    ephemeral: boolean
    thinking: boolean
  }
}
DELETE/v1/hooks/messaging/webhooks/:appId/:token/messages/@original

Deletes the original response to an interaction.

Auth
None.

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

  • token

    A secret from a link: an issue automation rule's incoming-webhook token (shown once when issued), a map's share link, a notification recipient's confirm and unsubscribe link, a Drive public link (/l/<token>), a Vehicles drive's share link, or a Mirage interaction's token (itk_…, sent with the interaction, good for 15 minutes), or the token in the link to a file of a message Mirage sent to Discord, or a Marketing link's sealed token (a tracked click, the open pixel, unsubscribe and the preference centre, a double opt-in confirmation); or a Food recipe's public link (/r/<token>) or a household's calendar feed.

curl -X DELETE 'https://api.cactive.com.au/v1/hooks/messaging/webhooks/{appId}/{token}/messages/@original'
Send it from this page with your session or a key.

Response 204 with no body

GET/v1/messaging/applications

Your applications (the developer portal's Mirage Bots), oldest first: each with its bot, public key, interactions endpoint, events and install settings.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/applications' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  applications: {
    ownerId: string
    publicKey: string
    interactionsUrl: null | string
    interactionsVerifiedAt: null | number
    events: string[]
    tokenHint: string
    createdAt: number
    updatedAt: number
    appId: string
    botId: string
    name: string
    description: null | string
    icon: null | string
    iconUrl: null | string
    public: boolean
    platform: boolean
    permissions: string
    installs: number
    installTypes: ("user" | "guild")[]
  }[]
}
POST/v1/messaging/applications

Makes an application (name 2 to 32 characters, description, icon emoji; an image icon is uploaded after) with its bot user (bot_…), an Ed25519 key pair that signs what Mirage sends it, and a bot token (si_bot_…) returned this once.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/applications' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 201

{
  app: {
    ownerId: string
    publicKey: string
    interactionsUrl: null | string
    interactionsVerifiedAt: null | number
    events: string[]
    tokenHint: string
    createdAt: number
    updatedAt: number
    appId: string
    botId: string
    name: string
    description: null | string
    icon: null | string
    iconUrl: null | string
    public: boolean
    platform: boolean
    permissions: string
    installs: number
    installTypes: ("user" | "guild")[]
  }
  token: string
}
GET/v1/messaging/applications/:appId

One of your applications; with a bot token, @me is the bot's own.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/applications/{appId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  application: {
    ownerId: string
    publicKey: string
    interactionsUrl: null | string
    interactionsVerifiedAt: null | number
    events: string[]
    tokenHint: string
    createdAt: number
    updatedAt: number
    appId: string
    botId: string
    name: string
    description: null | string
    icon: null | string
    iconUrl: null | string
    public: boolean
    platform: boolean
    permissions: string
    installs: number
    installTypes: ("user" | "guild")[]
  }
}
PATCH/v1/messaging/applications/:appId

Changes an application: name, description, icon (an emoji, an uploaded image:<version>, or null); installTypes (guild for servers, user for people's own accounts); interactionsUrl (HTTPS, saved only once it answers a signed PING with {"type": 1} and refuses a badly signed one with 401; null removes it); events (message_mention, member_join); public (listed in the App Directory, and anyone who manages a server may add it); permissions its install link asks for.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X PATCH 'https://api.cactive.com.au/v1/messaging/applications/{appId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  application: {
    ownerId: string
    publicKey: string
    interactionsUrl: null | string
    interactionsVerifiedAt: null | number
    events: string[]
    tokenHint: string
    createdAt: number
    updatedAt: number
    appId: string
    botId: string
    name: string
    description: null | string
    icon: null | string
    iconUrl: null | string
    public: boolean
    platform: boolean
    permissions: string
    installs: number
    installTypes: ("user" | "guild")[]
  }
}
DELETE/v1/messaging/applications/:appId

Deletes an application: its bot leaves every server and its roles go, with its commands and token.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X DELETE 'https://api.cactive.com.au/v1/messaging/applications/{appId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 204 with no body

POST/v1/messaging/applications/:appId/token

Resets the bot token: the old one stops working at once; the new one is returned this once.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/applications/{appId}/token' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  app: {
    ownerId: string
    publicKey: string
    interactionsUrl: null | string
    interactionsVerifiedAt: null | number
    events: string[]
    tokenHint: string
    createdAt: number
    updatedAt: number
    appId: string
    botId: string
    name: string
    description: null | string
    icon: null | string
    iconUrl: null | string
    public: boolean
    platform: boolean
    permissions: string
    installs: number
    installTypes: ("user" | "guild")[]
  }
  token: string
}
POST/v1/messaging/applications/:appId/icon/uploads

Where to PUT an image icon (mime: PNG, JPEG, WebP or GIF; size up to 1 MB); then set the answer's icon (image:<version>) with a PATCH. Its owner.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/applications/{appId}/icon/uploads' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  icon: string
  url: string
  headers: {
    "content-type": "image/png" | "image/jpeg" | "image/webp" | "image/gif"
  }
}
GET/v1/messaging/applications/:appId/deliveries

What Mirage sent the app's interactions endpoint lately (kept for days, as platform data sets): kind (command, component, modal, autocomplete, event:<type>, ping), a summary, the status, time taken and any error, newest first. kind filters, before pages. Its owner.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Query parameters

  • beforestring
  • kindstring

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/applications/{appId}/deliveries' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  deliveries: {
    deliveryId: string
    kind: string
    summary: null | string
    status: number
    ms: number
    error: null | string
    at: number
  }[]
  hasMore: boolean
}
GET/v1/messaging/me/applications

Apps you added to your account (user installs): their commands work in every server you're in.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/me/applications' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  applications: {
    addedAt: number
    appId: string
    botId: string
    name: string
    description: null | string
    icon: null | string
    iconUrl: null | string
    public: boolean
    platform: boolean
    permissions: string
    installs: number
    installTypes: ("user" | "guild")[]
  }[]
}
PUT/v1/messaging/me/applications/:appId

Adds an app that allows user installs to your account (up to a limit set as platform data). Where a server doesn't give outside apps USE_EXTERNAL_APPS, only you see its answers.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X PUT 'https://api.cactive.com.au/v1/messaging/me/applications/{appId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  application: {
    appId: string
    botId: string
    name: string
    description: null | string
    icon: null | string
    iconUrl: null | string
    public: boolean
    platform: boolean
    permissions: string
    installs: number
    installTypes: ("user" | "guild")[]
  }
}
DELETE/v1/messaging/me/applications/:appId

Removes an app from your account.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X DELETE 'https://api.cactive.com.au/v1/messaging/me/applications/{appId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 204 with no body

GET/v1/messaging/applications/:appId/commands

The app's global slash commands. Its owner, or its bot with its token.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/applications/{appId}/commands' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  commands: {
    appId: string
    scope: string
    name: string
    description: string
    options: {
      name: string
      description: string
      type: "string" | "number" | "boolean" | "user" | "role" | "channel" | "integer"
      required?: boolean
      choices?: {
        name: string
        value: string | number
      }[]
      autocomplete?: boolean
    }[]
  }[]
}
PUT/v1/messaging/applications/:appId/commands

Replaces the app's global commands with these (up to 100): name, description, and options (string, integer, number, boolean, user, channel or role; required ones first; choices, or autocomplete for the app to suggest values as they're typed). Its owner, or its bot.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X PUT 'https://api.cactive.com.au/v1/messaging/applications/{appId}/commands' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  commands: {
    appId: string
    scope: string
    name: string
    description: string
    options: {
      name: string
      description: string
      type: "string" | "number" | "boolean" | "user" | "role" | "channel" | "integer"
      required?: boolean
      choices?: {
        name: string
        value: string | number
      }[]
      autocomplete?: boolean
    }[]
  }[]
}
POST/v1/messaging/applications/:appId/commands

Adds or replaces one global command (by name).

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/applications/{appId}/commands' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 201

{
  command: {
    appId: string
    scope: string
    name: string
    description: string
    options: {
      name: string
      description: string
      type: "string" | "number" | "boolean" | "user" | "role" | "channel" | "integer"
      required?: boolean
      choices?: {
        name: string
        value: string | number
      }[]
      autocomplete?: boolean
    }[]
  }
}
DELETE/v1/messaging/applications/:appId/commands/:command

Deletes a global command.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

  • command

    A slash command's name (1 to 32 lowercase letters, digits, - or _).

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X DELETE 'https://api.cactive.com.au/v1/messaging/applications/{appId}/commands/{command}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 204 with no body

GET/v1/messaging/applications/:appId/servers/:serverId/commands

The app's commands for one server its bot is in.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

  • serverId

    Mirage server id (gld_…).

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/applications/{appId}/servers/{serverId}/commands' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  commands: {
    appId: string
    scope: string
    name: string
    description: string
    options: {
      name: string
      description: string
      type: "string" | "number" | "boolean" | "user" | "role" | "channel" | "integer"
      required?: boolean
      choices?: {
        name: string
        value: string | number
      }[]
      autocomplete?: boolean
    }[]
  }[]
}
PUT/v1/messaging/applications/:appId/servers/:serverId/commands

Replaces the app's commands for one server its bot is in; there they take the place of global commands of the same name.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

  • serverId

    Mirage server id (gld_…).

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X PUT 'https://api.cactive.com.au/v1/messaging/applications/{appId}/servers/{serverId}/commands' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  commands: {
    appId: string
    scope: string
    name: string
    description: string
    options: {
      name: string
      description: string
      type: "string" | "number" | "boolean" | "user" | "role" | "channel" | "integer"
      required?: boolean
      choices?: {
        name: string
        value: string | number
      }[]
      autocomplete?: boolean
    }[]
  }[]
}
POST/v1/messaging/applications/:appId/servers/:serverId/commands

Adds or replaces one of the app's commands for a server.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

  • serverId

    Mirage server id (gld_…).

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/applications/{appId}/servers/{serverId}/commands' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 201

{
  command: {
    appId: string
    scope: string
    name: string
    description: string
    options: {
      name: string
      description: string
      type: "string" | "number" | "boolean" | "user" | "role" | "channel" | "integer"
      required?: boolean
      choices?: {
        name: string
        value: string | number
      }[]
      autocomplete?: boolean
    }[]
  }
}
DELETE/v1/messaging/applications/:appId/servers/:serverId/commands/:command

Deletes one of the app's commands for a server.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

  • serverId

    Mirage server id (gld_…).

  • command

    A slash command's name (1 to 32 lowercase letters, digits, - or _).

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X DELETE 'https://api.cactive.com.au/v1/messaging/applications/{appId}/servers/{serverId}/commands/{command}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 204 with no body

GET/v1/messaging/applications/:appId/authorize

What an install link shows (permissions from the link, else the app's): the app, the permissions it asks for, and the servers you manage (installed where its bot already is). A private app shows only to its owner.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Query parameters

  • permissionsstring

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/applications/{appId}/authorize' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  app: {
    appId: string
    botId: string
    name: string
    description: null | string
    icon: null | string
    iconUrl: null | string
    public: boolean
    platform: boolean
    permissions: string
    installs: number
    installTypes: ("user" | "guild")[]
  }
  permissions: string
  permissionNames: ("CREATE_INVITE" | "KICK_MEMBERS" | "BAN_MEMBERS" | "ADMINISTRATOR" | "MANAGE_CHANNELS" | "MANAGE_SERVER" | "ADD_REACTIONS" | "VIEW_AUDIT_LOG" | "PRIORITY_SPEAKER" | "STREAM" | "VIEW_CHANNEL" | "SEND_MESSAGES" | "MANAGE_MESSAGES" | "EMBED_LINKS" | "ATTACH_FILES" | "READ_MESSAGE_HISTORY" | "MENTION_EVERYONE" | "USE_EXTERNAL_EMOJI" | "CONNECT" | "SPEAK" | "MUTE_MEMBERS" | "DEAFEN_MEMBERS" | "MOVE_MEMBERS" | "CHANGE_NICKNAME" | "MANAGE_NICKNAMES" | "MANAGE_ROLES" | "MANAGE_WEBHOOKS" | "MANAGE_EMOJIS" | "REQUEST_TO_SPEAK" | "MANAGE_EVENTS" | "MANAGE_THREADS" | "CREATE_THREADS" | "USE_EXTERNAL_STICKERS" | "SEND_IN_THREADS" | "MODERATE_MEMBERS" | "USE_SOUNDBOARD" | "USE_EXTERNAL_SOUNDS" | "SEND_POLLS" | "USE_EXTERNAL_APPS")[]
  servers: {
    serverId: string
    name: string
    icon: null | string
    permissions: string
    installed: boolean
  }[]
  onAccount: boolean
}
POST/v1/messaging/applications/:appId/install

Adds the app's bot to a server you manage (serverId; permissions, only ones you have). It joins with a role named after it holding them, which can't be deleted, given or taken by hand; removing the bot removes the role. MANAGE_SERVER.

Auth
A person's token or an API key, as Authorization: Bearer.
Make a Mirage bot

Path parameters

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/applications/{appId}/install' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 201

{
  integration: {
    app: {
      appId: string
      botId: string
      name: string
      description: null | string
      icon: null | string
      iconUrl: null | string
      public: boolean
      platform: boolean
      permissions: string
      installs: number
      installTypes: ("user" | "guild")[]
    }
    botId: string
    roleId: null | string
    permissions: string
    permissionNames: string[]
    installedBy: null | {
      userId: string
      name: string
    }
    installedAt: null | number
    commands: {
      name: string
      description: string
    }[]
    removable: boolean
  }
}
GET/v1/messaging/servers/:serverId/integrations

The server's apps: Caity (built in) and the bots people added, with who added them, what they were given and their commands. MANAGE_SERVER.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Path parameters

  • serverId

    Mirage server id (gld_…).

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/servers/{serverId}/integrations' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  integrations: {
    app: {
      appId: string
      botId: string
      name: string
      description: null | string
      icon: null | string
      iconUrl: null | string
      public: boolean
      platform: boolean
      permissions: string
      installs: number
      installTypes: ("user" | "guild")[]
    }
    botId: string
    roleId: null | string
    permissions: string
    permissionNames: string[]
    installedBy: null | {
      userId: string
      name: string
    }
    installedAt: null | number
    commands: {
      name: string
      description: string
    }[]
    removable: boolean
  }[]
}
DELETE/v1/messaging/servers/:serverId/integrations/:appId

Removes an app's bot and its role from the server. Caity can't be removed: keep it out of channels with channel permissions. MANAGE_SERVER.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Path parameters

  • serverId

    Mirage server id (gld_…).

  • appId

    Mirage application id (bap_…); @me with a bot token for the bot's own.

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X DELETE 'https://api.cactive.com.au/v1/messaging/servers/{serverId}/integrations/{appId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 204 with no body

GET/v1/messaging/directory

The App Directory: Caity, then public apps by how many servers use them; with serverId, which are already there.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Query parameters

  • serverIdstring

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/directory' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  applications: {
    installed: boolean
    appId: string
    botId: string
    name: string
    description: null | string
    icon: null | string
    iconUrl: null | string
    public: boolean
    platform: boolean
    permissions: string
    installs: number
    installTypes: ("user" | "guild")[]
  }[]
}
GET/v1/messaging/servers/:serverId/commands

Every slash command you can use in a server (the composer's "/" list): Caity's, then each app's.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Path parameters

  • serverId

    Mirage server id (gld_…).

Errors

  • 403Only the person signed in can do this; bots can't.
curl 'https://api.cactive.com.au/v1/messaging/servers/{serverId}/commands' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  commands: {
    appId: string
    scope: string
    name: string
    description: string
    options: {
      name: string
      description: string
      type: "string" | "number" | "boolean" | "user" | "role" | "channel" | "integer"
      required?: boolean
      choices?: {
        name: string
        value: string | number
      }[]
      autocomplete?: boolean
    }[]
    botId: string
    installed: "user" | "server"
    app: {
      name: string
      icon: null | string
      iconUrl: null | string
      platform: boolean
    }
  }[]
}
POST/v1/messaging/channels/:channelId/interactions

Uses a slash command (appId, name, options as { name, value }) in a channel or thread where you can send messages; the app's bot must be able to post there too. The app's endpoint gets a signed interaction (type 2, with a token) and answers within 3 seconds with a message ({"type": 4, "data": {"content": …, "components": …}}; flags: 64 shows it only to you), a modal (type 9) or deferred ({"type": 5}), then follows up with the token. Apps on your account answer where their bot isn't a member (only to you without USE_EXTERNAL_APPS). Caity answers /caity from its worker (deferred).

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Path parameters

  • channelId

    Mirage channel id (chn_…).

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/channels/{channelId}/interactions' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  interactionId: string
  deferred: boolean
  message: null
} | {
  interactionId: string
  deferred: boolean
  message: {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot: "server"
      avatarUrl: null
    } | {
      avatarUrl: null | string
      external?: "discord" | "webhook"
      bot?: "platform" | "server" | "bot"
      userId: string
      name: string
    }
    type: "default" | "join" | "system" | "reply" | "pin" | "follow"
    content: string
    replyTo: null | {
      author: {
        avatarUrl: null | string
        external?: "discord" | "webhook"
        bot?: "platform" | "server" | "bot"
        userId: string
        name: string
      }
      content: string
      messageId: string
    } | {
      deleted: boolean
      messageId: string
    }
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: {
      url: string
      durationSecs?: null | number
      waveform?: string
      attachmentId: string
      name: string
      mime: string
      size: number
      width: null | number
      height: null | number
    }[]
    reactions: {
      emoji: string
      count: number
      me: boolean
    }[]
    pinned: boolean
    thread: null | {
      threadId: string
      name: string
      messageCount: number
      lastActivityAt: number
      archived: boolean
    }
    poll: null | {
      question: string
      answers: {
        answerId: string
        text: string
        emoji: null | string
        count: number
      }[]
      multiple: boolean
      expiresAt: number
      closed: boolean
      total: number
      mine: string[]
    }
    embeds: {
      url: string
      type: "link" | "video" | "image" | "gifv" | "rich"
      title: null | string
      description: null | string
      siteName: null | string
      author: null | string
      color: null | string
      thumbnail: boolean
      image: null | {
        url: string
        width: null | number
        height: null | number
      }
      video: null | {
        url: string
        width: null | number
        height: null | number
      }
      gif: null | {
        url: string
        width: null | number
        height: null | number
      }
      provider: null | string
      authorUrl: null | string
      authorIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      thumb: null | {
        url: string
        width: null | number
        height: null | number
      }
      fields: {
        name: string
        value: string
        inline: boolean
      }[]
      footer: null | string
      footerIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      timestamp: null | number
      source: null | string
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null | string
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null | {
      content: string
      attachments: {
        attachmentId: string
        name: string
        mime: string
        size: number
        width: null | number
        height: null | number
        url: string
      }[]
      embeds: {
        url: string
        type: "link" | "video" | "image" | "gifv" | "rich"
        title: null | string
        description: null | string
        siteName: null | string
        author: null | string
        color: null | string
        thumbnail: boolean
        image: null | {
          url: string
          width: null | number
          height: null | number
        }
        video: null | {
          url: string
          width: null | number
          height: null | number
        }
        gif: null | {
          url: string
          width: null | number
          height: null | number
        }
        provider: null | string
        authorUrl: null | string
        authorIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        thumb: null | {
          url: string
          width: null | number
          height: null | number
        }
        fields: {
          name: string
          value: string
          inline: boolean
        }[]
        footer: null | string
        footerIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        timestamp: null | number
        source: null | string
      }[]
      origin: {
        serverId: string
        channelId: string
        messageId: string
        createdAt: number
      }
    }
    published: boolean
    crosspost: null | {
      serverId: string
      channelId: string
      messageId: string
      serverName: string
      channelName: string
      serverIcon: null | string
    }
    display: null | {
      source: "discord" | "webhook"
      name: null | string
      avatarUrl: null | string
      linked: boolean
      externalId: null | string
      externalAuthorId: null | string
    }
    stickers: {
      stickerId: string
      name: string
      format: "gif" | "png" | "webp" | "apng" | "lottie"
    }[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
  } | {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot?: "platform" | "server" | "bot"
      avatarUrl: null | string
    }
    type: "default"
    content: string
    replyTo: null
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: unknown[]
    reactions: unknown[]
    pinned: boolean
    thread: null
    poll: null
    embeds: unknown[]
    stickers: unknown[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null
    published: boolean
    crosspost: null
    display: null
    ephemeral: boolean
    thinking: boolean
  }
  updated?: undefined
  modal?: undefined
} | {
  interactionId: string
  deferred: boolean
  message: {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot: "server"
      avatarUrl: null
    } | {
      avatarUrl: null | string
      external?: "discord" | "webhook"
      bot?: "platform" | "server" | "bot"
      userId: string
      name: string
    }
    type: "default" | "join" | "system" | "reply" | "pin" | "follow"
    content: string
    replyTo: null | {
      author: {
        avatarUrl: null | string
        external?: "discord" | "webhook"
        bot?: "platform" | "server" | "bot"
        userId: string
        name: string
      }
      content: string
      messageId: string
    } | {
      deleted: boolean
      messageId: string
    }
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: {
      url: string
      durationSecs?: null | number
      waveform?: string
      attachmentId: string
      name: string
      mime: string
      size: number
      width: null | number
      height: null | number
    }[]
    reactions: {
      emoji: string
      count: number
      me: boolean
    }[]
    pinned: boolean
    thread: null | {
      threadId: string
      name: string
      messageCount: number
      lastActivityAt: number
      archived: boolean
    }
    poll: null | {
      question: string
      answers: {
        answerId: string
        text: string
        emoji: null | string
        count: number
      }[]
      multiple: boolean
      expiresAt: number
      closed: boolean
      total: number
      mine: string[]
    }
    embeds: {
      url: string
      type: "link" | "video" | "image" | "gifv" | "rich"
      title: null | string
      description: null | string
      siteName: null | string
      author: null | string
      color: null | string
      thumbnail: boolean
      image: null | {
        url: string
        width: null | number
        height: null | number
      }
      video: null | {
        url: string
        width: null | number
        height: null | number
      }
      gif: null | {
        url: string
        width: null | number
        height: null | number
      }
      provider: null | string
      authorUrl: null | string
      authorIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      thumb: null | {
        url: string
        width: null | number
        height: null | number
      }
      fields: {
        name: string
        value: string
        inline: boolean
      }[]
      footer: null | string
      footerIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      timestamp: null | number
      source: null | string
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null | string
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null | {
      content: string
      attachments: {
        attachmentId: string
        name: string
        mime: string
        size: number
        width: null | number
        height: null | number
        url: string
      }[]
      embeds: {
        url: string
        type: "link" | "video" | "image" | "gifv" | "rich"
        title: null | string
        description: null | string
        siteName: null | string
        author: null | string
        color: null | string
        thumbnail: boolean
        image: null | {
          url: string
          width: null | number
          height: null | number
        }
        video: null | {
          url: string
          width: null | number
          height: null | number
        }
        gif: null | {
          url: string
          width: null | number
          height: null | number
        }
        provider: null | string
        authorUrl: null | string
        authorIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        thumb: null | {
          url: string
          width: null | number
          height: null | number
        }
        fields: {
          name: string
          value: string
          inline: boolean
        }[]
        footer: null | string
        footerIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        timestamp: null | number
        source: null | string
      }[]
      origin: {
        serverId: string
        channelId: string
        messageId: string
        createdAt: number
      }
    }
    published: boolean
    crosspost: null | {
      serverId: string
      channelId: string
      messageId: string
      serverName: string
      channelName: string
      serverIcon: null | string
    }
    display: null | {
      source: "discord" | "webhook"
      name: null | string
      avatarUrl: null | string
      linked: boolean
      externalId: null | string
      externalAuthorId: null | string
    }
    stickers: {
      stickerId: string
      name: string
      format: "gif" | "png" | "webp" | "apng" | "lottie"
    }[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
  } | {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot?: "platform" | "server" | "bot"
      avatarUrl: null | string
    }
    type: "default"
    content: string
    replyTo: null
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: unknown[]
    reactions: unknown[]
    pinned: boolean
    thread: null
    poll: null
    embeds: unknown[]
    stickers: unknown[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null
    published: boolean
    crosspost: null
    display: null
    ephemeral: boolean
    thinking: boolean
  }
  updated: boolean
  modal?: undefined
}
POST/v1/messaging/channels/:channelId/interactions/autocomplete

What an option with autocomplete suggests while it's typed (appId, name, options with the one being typed focused): the app gets a signed interaction (type 4) and answers with up to 25 choices.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Path parameters

  • channelId

    Mirage channel id (chn_…).

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/channels/{channelId}/interactions/autocomplete' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  choices: {
    name: string
    value: string | number
  }[]
}
POST/v1/messaging/channels/:channelId/messages/:messageId/components

Presses a button or chooses in a select menu on an app's message (customId, values for a menu): the app gets a signed interaction (type 3) and answers with a message (type 4, flags: 64 for only you), deferred (5 or 6), a change to the message (7) or a modal (9). Returns message, updated or modal.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Path parameters

  • channelId

    Mirage channel id (chn_…).

  • messageId

    Message id (msg_…; Mirage messages are mmg_…).

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/channels/{channelId}/messages/{messageId}/components' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  interactionId: string
  deferred: boolean
  message: {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot: "server"
      avatarUrl: null
    } | {
      avatarUrl: null | string
      external?: "discord" | "webhook"
      bot?: "platform" | "server" | "bot"
      userId: string
      name: string
    }
    type: "default" | "join" | "system" | "reply" | "pin" | "follow"
    content: string
    replyTo: null | {
      author: {
        avatarUrl: null | string
        external?: "discord" | "webhook"
        bot?: "platform" | "server" | "bot"
        userId: string
        name: string
      }
      content: string
      messageId: string
    } | {
      deleted: boolean
      messageId: string
    }
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: {
      url: string
      durationSecs?: null | number
      waveform?: string
      attachmentId: string
      name: string
      mime: string
      size: number
      width: null | number
      height: null | number
    }[]
    reactions: {
      emoji: string
      count: number
      me: boolean
    }[]
    pinned: boolean
    thread: null | {
      threadId: string
      name: string
      messageCount: number
      lastActivityAt: number
      archived: boolean
    }
    poll: null | {
      question: string
      answers: {
        answerId: string
        text: string
        emoji: null | string
        count: number
      }[]
      multiple: boolean
      expiresAt: number
      closed: boolean
      total: number
      mine: string[]
    }
    embeds: {
      url: string
      type: "link" | "video" | "image" | "gifv" | "rich"
      title: null | string
      description: null | string
      siteName: null | string
      author: null | string
      color: null | string
      thumbnail: boolean
      image: null | {
        url: string
        width: null | number
        height: null | number
      }
      video: null | {
        url: string
        width: null | number
        height: null | number
      }
      gif: null | {
        url: string
        width: null | number
        height: null | number
      }
      provider: null | string
      authorUrl: null | string
      authorIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      thumb: null | {
        url: string
        width: null | number
        height: null | number
      }
      fields: {
        name: string
        value: string
        inline: boolean
      }[]
      footer: null | string
      footerIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      timestamp: null | number
      source: null | string
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null | string
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null | {
      content: string
      attachments: {
        attachmentId: string
        name: string
        mime: string
        size: number
        width: null | number
        height: null | number
        url: string
      }[]
      embeds: {
        url: string
        type: "link" | "video" | "image" | "gifv" | "rich"
        title: null | string
        description: null | string
        siteName: null | string
        author: null | string
        color: null | string
        thumbnail: boolean
        image: null | {
          url: string
          width: null | number
          height: null | number
        }
        video: null | {
          url: string
          width: null | number
          height: null | number
        }
        gif: null | {
          url: string
          width: null | number
          height: null | number
        }
        provider: null | string
        authorUrl: null | string
        authorIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        thumb: null | {
          url: string
          width: null | number
          height: null | number
        }
        fields: {
          name: string
          value: string
          inline: boolean
        }[]
        footer: null | string
        footerIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        timestamp: null | number
        source: null | string
      }[]
      origin: {
        serverId: string
        channelId: string
        messageId: string
        createdAt: number
      }
    }
    published: boolean
    crosspost: null | {
      serverId: string
      channelId: string
      messageId: string
      serverName: string
      channelName: string
      serverIcon: null | string
    }
    display: null | {
      source: "discord" | "webhook"
      name: null | string
      avatarUrl: null | string
      linked: boolean
      externalId: null | string
      externalAuthorId: null | string
    }
    stickers: {
      stickerId: string
      name: string
      format: "gif" | "png" | "webp" | "apng" | "lottie"
    }[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
  } | {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot?: "platform" | "server" | "bot"
      avatarUrl: null | string
    }
    type: "default"
    content: string
    replyTo: null
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: unknown[]
    reactions: unknown[]
    pinned: boolean
    thread: null
    poll: null
    embeds: unknown[]
    stickers: unknown[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null
    published: boolean
    crosspost: null
    display: null
    ephemeral: boolean
    thinking: boolean
  }
  updated?: undefined
  modal?: undefined
} | {
  interactionId: string
  deferred: boolean
  message: null
  updated?: undefined
  modal?: undefined
} | {
  interactionId: string
  deferred: boolean
  message: {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot: "server"
      avatarUrl: null
    } | {
      avatarUrl: null | string
      external?: "discord" | "webhook"
      bot?: "platform" | "server" | "bot"
      userId: string
      name: string
    }
    type: "default" | "join" | "system" | "reply" | "pin" | "follow"
    content: string
    replyTo: null | {
      author: {
        avatarUrl: null | string
        external?: "discord" | "webhook"
        bot?: "platform" | "server" | "bot"
        userId: string
        name: string
      }
      content: string
      messageId: string
    } | {
      deleted: boolean
      messageId: string
    }
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: {
      url: string
      durationSecs?: null | number
      waveform?: string
      attachmentId: string
      name: string
      mime: string
      size: number
      width: null | number
      height: null | number
    }[]
    reactions: {
      emoji: string
      count: number
      me: boolean
    }[]
    pinned: boolean
    thread: null | {
      threadId: string
      name: string
      messageCount: number
      lastActivityAt: number
      archived: boolean
    }
    poll: null | {
      question: string
      answers: {
        answerId: string
        text: string
        emoji: null | string
        count: number
      }[]
      multiple: boolean
      expiresAt: number
      closed: boolean
      total: number
      mine: string[]
    }
    embeds: {
      url: string
      type: "link" | "video" | "image" | "gifv" | "rich"
      title: null | string
      description: null | string
      siteName: null | string
      author: null | string
      color: null | string
      thumbnail: boolean
      image: null | {
        url: string
        width: null | number
        height: null | number
      }
      video: null | {
        url: string
        width: null | number
        height: null | number
      }
      gif: null | {
        url: string
        width: null | number
        height: null | number
      }
      provider: null | string
      authorUrl: null | string
      authorIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      thumb: null | {
        url: string
        width: null | number
        height: null | number
      }
      fields: {
        name: string
        value: string
        inline: boolean
      }[]
      footer: null | string
      footerIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      timestamp: null | number
      source: null | string
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null | string
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null | {
      content: string
      attachments: {
        attachmentId: string
        name: string
        mime: string
        size: number
        width: null | number
        height: null | number
        url: string
      }[]
      embeds: {
        url: string
        type: "link" | "video" | "image" | "gifv" | "rich"
        title: null | string
        description: null | string
        siteName: null | string
        author: null | string
        color: null | string
        thumbnail: boolean
        image: null | {
          url: string
          width: null | number
          height: null | number
        }
        video: null | {
          url: string
          width: null | number
          height: null | number
        }
        gif: null | {
          url: string
          width: null | number
          height: null | number
        }
        provider: null | string
        authorUrl: null | string
        authorIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        thumb: null | {
          url: string
          width: null | number
          height: null | number
        }
        fields: {
          name: string
          value: string
          inline: boolean
        }[]
        footer: null | string
        footerIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        timestamp: null | number
        source: null | string
      }[]
      origin: {
        serverId: string
        channelId: string
        messageId: string
        createdAt: number
      }
    }
    published: boolean
    crosspost: null | {
      serverId: string
      channelId: string
      messageId: string
      serverName: string
      channelName: string
      serverIcon: null | string
    }
    display: null | {
      source: "discord" | "webhook"
      name: null | string
      avatarUrl: null | string
      linked: boolean
      externalId: null | string
      externalAuthorId: null | string
    }
    stickers: {
      stickerId: string
      name: string
      format: "gif" | "png" | "webp" | "apng" | "lottie"
    }[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
  } | {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot?: "platform" | "server" | "bot"
      avatarUrl: null | string
    }
    type: "default"
    content: string
    replyTo: null
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: unknown[]
    reactions: unknown[]
    pinned: boolean
    thread: null
    poll: null
    embeds: unknown[]
    stickers: unknown[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null
    published: boolean
    crosspost: null
    display: null
    ephemeral: boolean
    thinking: boolean
  }
  updated: boolean
  modal?: undefined
} | {
  interactionId: string
  deferred: boolean
  message: null
  modal: {
    customId: string
    title: string
    components: {
      type: 1
      components: {
        type: 4
        customId: string
        style: 2 | 1
        label: string
        minLength?: number
        maxLength?: number
        required?: boolean
        value?: string
        placeholder?: string
      }[]
    }[]
    modalId: string
    appName: string
  }
  updated?: undefined
}
POST/v1/messaging/modals/:modalId

Submits a modal an app showed you (components as { customId, value }): the app gets a signed interaction (type 5) and answers as for a component.

Auth
A person's token or an API key, as Authorization: Bearer.
Get an API key

Path parameters

  • modalId

    The id a modal came with (mdl_…).

Errors

  • 403Only the person signed in can do this; bots can't.
curl -X POST 'https://api.cactive.com.au/v1/messaging/modals/{modalId}' \
  -H "Authorization: Bearer $CACTIVE_TOKEN"
Send it from this page with your session or a key.

Response 200

{
  interactionId: string
  deferred: boolean
  message: {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot: "server"
      avatarUrl: null
    } | {
      avatarUrl: null | string
      external?: "discord" | "webhook"
      bot?: "platform" | "server" | "bot"
      userId: string
      name: string
    }
    type: "default" | "join" | "system" | "reply" | "pin" | "follow"
    content: string
    replyTo: null | {
      author: {
        avatarUrl: null | string
        external?: "discord" | "webhook"
        bot?: "platform" | "server" | "bot"
        userId: string
        name: string
      }
      content: string
      messageId: string
    } | {
      deleted: boolean
      messageId: string
    }
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: {
      url: string
      durationSecs?: null | number
      waveform?: string
      attachmentId: string
      name: string
      mime: string
      size: number
      width: null | number
      height: null | number
    }[]
    reactions: {
      emoji: string
      count: number
      me: boolean
    }[]
    pinned: boolean
    thread: null | {
      threadId: string
      name: string
      messageCount: number
      lastActivityAt: number
      archived: boolean
    }
    poll: null | {
      question: string
      answers: {
        answerId: string
        text: string
        emoji: null | string
        count: number
      }[]
      multiple: boolean
      expiresAt: number
      closed: boolean
      total: number
      mine: string[]
    }
    embeds: {
      url: string
      type: "link" | "video" | "image" | "gifv" | "rich"
      title: null | string
      description: null | string
      siteName: null | string
      author: null | string
      color: null | string
      thumbnail: boolean
      image: null | {
        url: string
        width: null | number
        height: null | number
      }
      video: null | {
        url: string
        width: null | number
        height: null | number
      }
      gif: null | {
        url: string
        width: null | number
        height: null | number
      }
      provider: null | string
      authorUrl: null | string
      authorIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      thumb: null | {
        url: string
        width: null | number
        height: null | number
      }
      fields: {
        name: string
        value: string
        inline: boolean
      }[]
      footer: null | string
      footerIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      timestamp: null | number
      source: null | string
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null | string
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null | {
      content: string
      attachments: {
        attachmentId: string
        name: string
        mime: string
        size: number
        width: null | number
        height: null | number
        url: string
      }[]
      embeds: {
        url: string
        type: "link" | "video" | "image" | "gifv" | "rich"
        title: null | string
        description: null | string
        siteName: null | string
        author: null | string
        color: null | string
        thumbnail: boolean
        image: null | {
          url: string
          width: null | number
          height: null | number
        }
        video: null | {
          url: string
          width: null | number
          height: null | number
        }
        gif: null | {
          url: string
          width: null | number
          height: null | number
        }
        provider: null | string
        authorUrl: null | string
        authorIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        thumb: null | {
          url: string
          width: null | number
          height: null | number
        }
        fields: {
          name: string
          value: string
          inline: boolean
        }[]
        footer: null | string
        footerIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        timestamp: null | number
        source: null | string
      }[]
      origin: {
        serverId: string
        channelId: string
        messageId: string
        createdAt: number
      }
    }
    published: boolean
    crosspost: null | {
      serverId: string
      channelId: string
      messageId: string
      serverName: string
      channelName: string
      serverIcon: null | string
    }
    display: null | {
      source: "discord" | "webhook"
      name: null | string
      avatarUrl: null | string
      linked: boolean
      externalId: null | string
      externalAuthorId: null | string
    }
    stickers: {
      stickerId: string
      name: string
      format: "gif" | "png" | "webp" | "apng" | "lottie"
    }[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
  } | {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot?: "platform" | "server" | "bot"
      avatarUrl: null | string
    }
    type: "default"
    content: string
    replyTo: null
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: unknown[]
    reactions: unknown[]
    pinned: boolean
    thread: null
    poll: null
    embeds: unknown[]
    stickers: unknown[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null
    published: boolean
    crosspost: null
    display: null
    ephemeral: boolean
    thinking: boolean
  }
  updated?: undefined
  modal?: undefined
} | {
  interactionId: string
  deferred: boolean
  message: null
  updated?: undefined
  modal?: undefined
} | {
  interactionId: string
  deferred: boolean
  message: {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot: "server"
      avatarUrl: null
    } | {
      avatarUrl: null | string
      external?: "discord" | "webhook"
      bot?: "platform" | "server" | "bot"
      userId: string
      name: string
    }
    type: "default" | "join" | "system" | "reply" | "pin" | "follow"
    content: string
    replyTo: null | {
      author: {
        avatarUrl: null | string
        external?: "discord" | "webhook"
        bot?: "platform" | "server" | "bot"
        userId: string
        name: string
      }
      content: string
      messageId: string
    } | {
      deleted: boolean
      messageId: string
    }
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: {
      url: string
      durationSecs?: null | number
      waveform?: string
      attachmentId: string
      name: string
      mime: string
      size: number
      width: null | number
      height: null | number
    }[]
    reactions: {
      emoji: string
      count: number
      me: boolean
    }[]
    pinned: boolean
    thread: null | {
      threadId: string
      name: string
      messageCount: number
      lastActivityAt: number
      archived: boolean
    }
    poll: null | {
      question: string
      answers: {
        answerId: string
        text: string
        emoji: null | string
        count: number
      }[]
      multiple: boolean
      expiresAt: number
      closed: boolean
      total: number
      mine: string[]
    }
    embeds: {
      url: string
      type: "link" | "video" | "image" | "gifv" | "rich"
      title: null | string
      description: null | string
      siteName: null | string
      author: null | string
      color: null | string
      thumbnail: boolean
      image: null | {
        url: string
        width: null | number
        height: null | number
      }
      video: null | {
        url: string
        width: null | number
        height: null | number
      }
      gif: null | {
        url: string
        width: null | number
        height: null | number
      }
      provider: null | string
      authorUrl: null | string
      authorIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      thumb: null | {
        url: string
        width: null | number
        height: null | number
      }
      fields: {
        name: string
        value: string
        inline: boolean
      }[]
      footer: null | string
      footerIcon: null | {
        url: string
        width: null | number
        height: null | number
      }
      timestamp: null | number
      source: null | string
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null | string
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null | {
      content: string
      attachments: {
        attachmentId: string
        name: string
        mime: string
        size: number
        width: null | number
        height: null | number
        url: string
      }[]
      embeds: {
        url: string
        type: "link" | "video" | "image" | "gifv" | "rich"
        title: null | string
        description: null | string
        siteName: null | string
        author: null | string
        color: null | string
        thumbnail: boolean
        image: null | {
          url: string
          width: null | number
          height: null | number
        }
        video: null | {
          url: string
          width: null | number
          height: null | number
        }
        gif: null | {
          url: string
          width: null | number
          height: null | number
        }
        provider: null | string
        authorUrl: null | string
        authorIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        thumb: null | {
          url: string
          width: null | number
          height: null | number
        }
        fields: {
          name: string
          value: string
          inline: boolean
        }[]
        footer: null | string
        footerIcon: null | {
          url: string
          width: null | number
          height: null | number
        }
        timestamp: null | number
        source: null | string
      }[]
      origin: {
        serverId: string
        channelId: string
        messageId: string
        createdAt: number
      }
    }
    published: boolean
    crosspost: null | {
      serverId: string
      channelId: string
      messageId: string
      serverName: string
      channelName: string
      serverIcon: null | string
    }
    display: null | {
      source: "discord" | "webhook"
      name: null | string
      avatarUrl: null | string
      linked: boolean
      externalId: null | string
      externalAuthorId: null | string
    }
    stickers: {
      stickerId: string
      name: string
      format: "gif" | "png" | "webp" | "apng" | "lottie"
    }[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
  } | {
    messageId: string
    channelId: string
    serverId: string
    author: {
      userId: string
      name: string
      bot?: "platform" | "server" | "bot"
      avatarUrl: null | string
    }
    type: "default"
    content: string
    replyTo: null
    mentions: string[]
    mentionRoles: string[]
    mentionEveryone: boolean
    attachments: unknown[]
    reactions: unknown[]
    pinned: boolean
    thread: null
    poll: null
    embeds: unknown[]
    stickers: unknown[]
    components: {
      type: 1
      components: {
        type: 2
        style: 2 | 1 | 3 | 4 | 5
        label?: string
        emoji?: {
          name: string
          id?: string
          animated?: boolean
        }
        customId?: string
        url?: string
        disabled?: boolean
      } | {
        type: 3
        customId: string
        options: object[]
        placeholder?: string
        minValues?: number
        maxValues?: number
        disabled?: boolean
      }[]
    }[]
    editedAt: null | number
    createdAt: number
    nonce: null
    interaction: null | {
      interactionId: string
      name: string
      userId: string
      userName: string
      options?: {
        name: string
        value: boolean | string | number
      }[]
      kind?: "command" | "component" | "modal"
      label?: string
    }
    forwarded: null
    published: boolean
    crosspost: null
    display: null
    ephemeral: boolean
    thinking: boolean
  }
  updated: boolean
  modal?: undefined
} | {
  interactionId: string
  deferred: boolean
  message: null
  modal: {
    customId: string
    title: string
    components: {
      type: 1
      components: {
        type: 4
        customId: string
        style: 2 | 1
        label: string
        minLength?: number
        maxLength?: number
        required?: boolean
        value?: string
        placeholder?: string
      }[]
    }[]
    modalId: string
    appName: string
  }
  updated?: undefined
}