Skip to article
Guides / Custom emoji

Custom emoji

Upload your own emoji, import them from Slack or Discord, and search them next to Unicode.

  • Plans Solo, Pro and Scale
On this page

Custom emoji are your own images, such as a team logo, a mascot or the party parrot. Emojisense hosts them and searches them next to Unicode emoji. People find each one by its shortcode or by any alias you give it.

Plans

PlanCustom emojiSlack and Discord import
Solo500—
Pro2kYes
Scale10kYes

The Free plan has no custom emoji. At the limit, uploads stop. Search keeps working.

Add emoji

Upload images in the dashboard, under your app. Each emoji has a shortcode and a list of aliases that search uses.

  • Formats: PNG, GIF, WebP or SVG, at most 256 KB each. SVG files are checked and rejected if they contain scripts, event handlers, javascript: links or external references.
  • Import from Slack (Pro and Scale): paste a Slack user token. Emojisense reads the workspace’s emoji list, downloads the images and never stores the token.
  • Import from Discord (Pro and Scale): give a bot token and a server (guild) id. The token is not stored either.

One import call stores at most 50 new emoji and reports imported, skipped and remaining. The dashboard calls again until nothing remains. Imports skip Slack aliases of other emoji, shortcodes you already have, images that fail the upload checks and anything over your plan’s limit. The full contract is in the HTTP API reference.

Each emoji has this shape in the dashboard API:

TypeScript
type CustomEmoji = {
  id: string;
  shortcode: string;
  aliases: string[];
  imageUrl: string; // https://api.emojisense.com/v1/custom/<appId>/<emojiId>
  tenantId: string | null; // null = app-wide
  tenantExternalId?: string | null; // tenants API and webhooks only
  source: "upload" | "slack" | "discord" | "api";
  bytes: number;
  createdAt: number; // epoch ms
};

Search them

Custom emoji are merged into search results with "source": "custom", before Unicode matches. A custom result carries its shortcode and an imageUrl:

TypeScript
// A custom match in /v1/search, /v1/suggest-reactions or on the device:
{
  emoji: ":partyparrot:",
  id: "C-<emojiId>",
  score: …,
  source: "custom",
  shortcode: "partyparrot",
  imageUrl: "https://api.emojisense.com/v1/custom/<appId>/<emojiId>",
}
  • On the API, /v1/search and /v1/suggest-reactions include the custom emoji of the key’s app.
  • On the device, the SDK gets a loadCustomPack({ endpoint, key }) function. It fetches the app’s emoji from GET /v1/custom-pack as a normal pack, so custom emoji are searched on every keystroke too.
  • Images are served from GET /v1/custom/:appId/:emojiId with a one-year immutable cache.

Render them

The ready pickers show imageUrl as an image when it is present. In your own UI, do the same:

TSX
function EmojiCell({ result }: { result: SearchResult }) {
  return result.imageUrl ? (
    <img
      src={result.imageUrl}
      alt={result.shortcode ?? result.emoji}
      width={24}
      height={24}
    />
  ) : (
    <span>{result.emoji}</span>
  );
}

One set per customer

If your product has many customers and each one needs its own emoji, use Tenants on the Scale plan.