API reference

Mirage Discord bridge

Linking Discord accounts, bridging a server with a Discord server, channel pairs and importing from Discord.

See Mirage. A server bridges with one Discord server where Caity's bot is: in each pair of channels, messages, edits, deletes and reactions cross the way you choose. Connecting and pairing check both sides, so you link your Discord account first (POST me/discord, then Discord sends you back to the Mirage app). Messages that came from Discord carry display (the name and avatar they were sent with, source: "discord" and their ids there); people who linked their account write as themselves. Files of messages sent to Discord are reachable by the token in their link, under /v1/hooks/messaging.

GET /v1/hooks/messaging/discord/files/:token/:filename

A file of a message sent to Discord: a redirect to it (cached 5 minutes). The link's token is the only credential; it goes when the message is deleted. No authentication.

Auth: none

Path parameterDescription
:tokenA 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>), 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.
:filenameThe file's name (for readers; the token finds the file).

Errors

StatusMessage
404File not found.

GET /v1/messaging/discord

Whether the Discord bridge is set up here (available, else reason), whether accounts can be linked (linking), the link that adds the bot to a Discord server (inviteUrl) and the bot's name.

Auth: user access token or platform agent key

Response 200

{
  available: boolean
  reason: null | string
  linking: boolean
  inviteUrl: null | string
  botName: "Caity"
  history: {
    max: number
    default: number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

GET /v1/messaging/me/discord

Your linked Discord account (account: id, username, name, when linked), or null, and whether linking is available.

Auth: user access token or platform agent key

Response 200

{
  available: boolean
  account: null | {
    discordUserId: string
    username: string
    name: string
    linkedAt: number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

POST /v1/messaging/me/discord

Starts linking your Discord account: url is Discord's consent page (OAuth2 identify with PKCE and a one-time state, good for 10 minutes). Discord sends you back to the Mirage app's /discord/callback.

Auth: user access token or platform agent key

Response 200

{
  url: string
}

Errors

StatusMessage
403Only the person signed in can do this.

POST /v1/messaging/me/discord/callback

Finishes linking with what Discord sent back (code, state), for the person who started. Discord's token is used once to read who you are, then revoked. A Discord account links to one person.

Auth: user access token or platform agent key

Response 200

{
  account: {
    discordUserId: string
    username: string
    name: string
    linkedAt: number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

DELETE /v1/messaging/me/discord

Unlinks your Discord account: your Discord messages show as from Discord again.

Auth: user access token or platform agent key

Response 204 with no body.

Errors

StatusMessage
403Only the person signed in can do this.

GET /v1/messaging/servers/:serverId/discord

The server's bridge: what's set up, your Discord account, the Discord server it's bridged with (or null), and its channel pairs with anything the bot still needs in each. MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 200

{
  account: null | {
    discordUserId: string
    username: string
    name: string
    linkedAt: number
  }
  bridge: null | {
    guildId: string
    guildName: string
    connectedBy: {
      userId: string
      name: string
    }
    connectedAt: number
    problem: null | string
  }
  pairs: {
    channelId: string
    channelName: null | string
    discordChannelId: string
    discordChannelName: string
    direction: "both" | "to_discord" | "to_mirage"
    problems: string[]
    createdAt: number
  }[]
  available: boolean
  reason: null | string
  linking: boolean
  inviteUrl: null | string
  botName: "Caity"
  history: {
    max: number
    default: number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

PUT /v1/messaging/servers/:serverId/discord

Bridges the server with a Discord server (guildId) the bot is in, where your linked Discord account has Manage Server. A Discord server bridges with one Mirage server. MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 200

{
  account: null | {
    discordUserId: string
    username: string
    name: string
    linkedAt: number
  }
  bridge: null | {
    guildId: string
    guildName: string
    connectedBy: {
      userId: string
      name: string
    }
    connectedAt: number
    problem: null | string
  }
  pairs: {
    channelId: string
    channelName: null | string
    discordChannelId: string
    discordChannelName: string
    direction: "both" | "to_discord" | "to_mirage"
    problems: string[]
    createdAt: number
  }[]
  available: boolean
  reason: null | string
  linking: boolean
  inviteUrl: null | string
  botName: "Caity"
  history: {
    max: number
    default: number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

DELETE /v1/messaging/servers/:serverId/discord

Ends the bridge: its pairs go, their webhooks leave Discord and a running import stops. Messages already across stay. MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 204 with no body.

Errors

StatusMessage
403Only the person signed in can do this.

GET /v1/messaging/servers/:serverId/discord/guilds

Discord servers you could bridge here: the bot is in them and your linked Discord account manages them (bridged: taken by another Mirage server). MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 200

{
  guilds: {
    guildId: string
    name: string
    bridged: boolean
  }[]
}

Errors

StatusMessage
403Only the person signed in can do this.

GET /v1/messaging/servers/:serverId/discord/channels

Both sides' channels, what each is paired with, what the bot can do in each Discord channel (read, webhooks, reactions) and what you can (read, post), and whether you can make channels on each side. MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 200

{
  discord: {
    id: string
    name: string
    type: string
    parentId: null | string
    position: number
    pairedWith: null | string
    bot: {
      read: boolean
      webhooks: boolean
      reactions: boolean
    }
    you: {
      read: boolean
      post: boolean
    }
  }[]
  mirage: {
    channelId: string
    name: string
    type: "text" | "category" | "voice" | "announcement" | "forum" | "stage"
    parentId: null | string
    position: number
    pairedWith: null | string
    you: {
      read: boolean
      post: boolean
    }
  }[]
  canCreateDiscord: boolean
  canCreateMirage: boolean
}

Errors

StatusMessage
403Only the person signed in can do this.

POST /v1/messaging/servers/:serverId/discord/channels

Pairs a Mirage channel (channelId, or newChannel: { name }) with a Discord channel (discordChannelId, or newDiscordChannel: { name }) and a direction: both, to_discord or to_mirage. You must read both channels and post where messages go; the bot needs Manage Webhooks there for messages going to Discord. MANAGE_SERVER (and MANAGE_CHANNELS here, or Manage Channels on Discord, for new channels).

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 201

{
  pair: {
    channelId: string
    channelName: null | string
    discordChannelId: string
    discordChannelName: string
    direction: "both" | "to_discord" | "to_mirage"
    problems: string[]
    createdAt: number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

PATCH /v1/messaging/servers/:serverId/discord/channels/:channelId

Changes which way a pair carries messages (direction); a webhook is made when Mirage's messages start going to Discord. MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).
:channelIdMirage channel id (chn_…).

Response 200

{
  pair: {
    channelId: string
    channelName: null | string
    discordChannelId: string
    discordChannelName: string
    direction: "both" | "to_discord" | "to_mirage"
    problems: string[]
    createdAt: number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

DELETE /v1/messaging/servers/:serverId/discord/channels/:channelId

Unpairs a channel; its webhook leaves Discord. MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).
:channelIdMirage channel id (chn_…).

Response 204 with no body.

Errors

StatusMessage
403Only the person signed in can do this.

GET /v1/messaging/servers/:serverId/discord/import

The latest import from Discord and how far it got (roles, channels, messages, files), or null. MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 200

{
  import: null | {
    importId: string
    status: "done" | "failed" | "cancelled" | "running"
    phase: "roles" | "done" | "channels" | "members" | "messages"
    options: {
      channels: number
      roles: boolean
      messages: number
      pair: boolean
    }
    pairing: null | {
      done: boolean
      paired: number
      oneWay: {
        name: string
        reason: string
      }[]
      failed: {
        name: string
        reason: string
      }[]
    }
    progress: {
      roles: number
      channels: number
      messages: number
      files: number
      channelsDone: number
      channelsTotal: number
    }
    startedBy: {
      userId: string
      name: string
    }
    createdAt: number
    finishedAt: null | number
    error: null | string
    stalled: boolean
    retryAt: null | number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

POST /v1/messaging/servers/:serverId/discord/import

Imports from the bridged Discord server in the background: chosen channels (channelIds) with their categories, roles (only permissions you have) and each text channel's newest messages (as many as the platform's limit allows, 5,000 by default; files copied; members' Discord roles follow for linked people). Channels you choose must be readable by your Discord account. MANAGE_SERVER, plus MANAGE_ROLES and MANAGE_CHANNELS for those.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 201

{
  import: {
    importId: string
    status: "done" | "failed" | "cancelled" | "running"
    phase: "roles" | "done" | "channels" | "members" | "messages"
    options: {
      channels: number
      roles: boolean
      messages: number
      pair: boolean
    }
    pairing: null | {
      done: boolean
      paired: number
      oneWay: {
        name: string
        reason: string
      }[]
      failed: {
        name: string
        reason: string
      }[]
    }
    progress: {
      roles: number
      channels: number
      messages: number
      files: number
      channelsDone: number
      channelsTotal: number
    }
    startedBy: {
      userId: string
      name: string
    }
    createdAt: number
    finishedAt: null | number
    error: null | string
    stalled: boolean
    retryAt: null | number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

DELETE /v1/messaging/servers/:serverId/discord/import

Stops the running import after its current step; what it made stays. MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 200

{
  import: {
    importId: string
    status: "done" | "failed" | "cancelled" | "running"
    phase: "roles" | "done" | "channels" | "members" | "messages"
    options: {
      channels: number
      roles: boolean
      messages: number
      pair: boolean
    }
    pairing: null | {
      done: boolean
      paired: number
      oneWay: {
        name: string
        reason: string
      }[]
      failed: {
        name: string
        reason: string
      }[]
    }
    progress: {
      roles: number
      channels: number
      messages: number
      files: number
      channelsDone: number
      channelsTotal: number
    }
    startedBy: {
      userId: string
      name: string
    }
    createdAt: number
    finishedAt: null | number
    error: null | string
    stalled: boolean
    retryAt: null | number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

POST /v1/messaging/servers/:serverId/discord/import/resume

Continues the latest import from where it stopped, when it stopped with a problem or stopped moving (stalled, or waiting to retry: retryAt). MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 200

{
  import: {
    importId: string
    status: "done" | "failed" | "cancelled" | "running"
    phase: "roles" | "done" | "channels" | "members" | "messages"
    options: {
      channels: number
      roles: boolean
      messages: number
      pair: boolean
    }
    pairing: null | {
      done: boolean
      paired: number
      oneWay: {
        name: string
        reason: string
      }[]
      failed: {
        name: string
        reason: string
      }[]
    }
    progress: {
      roles: number
      channels: number
      messages: number
      files: number
      channelsDone: number
      channelsTotal: number
    }
    startedBy: {
      userId: string
      name: string
    }
    createdAt: number
    finishedAt: null | number
    error: null | string
    stalled: boolean
    retryAt: null | number
  }
}

Errors

StatusMessage
403Only the person signed in can do this.

POST /v1/messaging/servers/:serverId/discord/import/pairs

After an import finished: pairs each imported text, announcement and forum channel with the Discord channel it came from (direction, default both; discordChannelIds for some only). Returns each channel's result. MANAGE_SERVER.

Auth: user access token or platform agent key

Path parameterDescription
:serverIdMirage server id (gld_…).

Response 200

{
  results: {
    discordChannelId: string
    channelId: string
    name: string
    paired: boolean
    already: boolean
    direction: null | "both" | "to_discord" | "to_mirage"
    error: null | string
  }[]
}

Errors

StatusMessage
403Only the person signed in can do this.