Skip to content

Manifest

manifest.json lives in the package root. The host validates it strictly: unknown top-level keys and unknown permissions are errors.

Field Description
schema always 1
id unique identifier, for example com.example.hello
name name; can be an object with translations by language
version semver, for example 1.0.0
compat compatibility, see below (compat.freshgram is required)
runtime how to run the code
files the package file list

description, author, license and permissions are optional but recommended. Unknown top-level keys are errors, except keys that start with x- (these are not accepted as language keys inside a localized name/description map, though). Every key is listed in the full manifest reference.

Key Meaning
description text for the install dialog; a string or a language map (up to 1000 characters)
author an object with name (up to 100), url (https) and contact (up to 200)
license licence name, up to 64 characters
homepage, repository, support https links, up to 500 characters each
icon path of a PNG in the package, at most 256 KiB; checked when the package is opened, not by the manifest parser
changelog path of a file in the package
categories up to 8 tokens (a-z, 0-9, -, up to 32 characters each)
keywords up to 16 tokens of the same kind
locales up to 64 language codes the plugin is translated to (ru, pt-BR)

icon and changelog must also be listed in files. Empty strings are rejected for every one of these keys (and for author.name, author.contact, updates.feed): omit a key instead of writing "". Length limits of the other strings are in the full reference.

"compat": { "freshgram": ">=7.0.0 <8.0.0", "api": 7 }
  • freshgram — range of client versions.
  • api — the API level the plugin requires: a single integer n (meaning “level n or higher”, must be 1–1000) or an object { "min": 3, "max": 7 } (both 1–1000, max not below min). The host currently declares level 7.
  • accounts — account restrictions (the compat.accounts field).
  • If the plugin requires Premium, set compat.accounts.premium. compat.requires lists host features and compat.testedWith the client version you tested with (a semantic version, up to 64 characters).
"runtime": { "kind": "python", "entry": "main.py" }
"runtime": {
"kind": "wasm",
"module": "plugin.wasm",
"language": "rust",
"abi": 1,
"limits": { "memoryMb": 64, "eventTimeoutMs": 500, "storageMb": 10 }
}
Key Value
kind python or wasm (up to 16 characters)
entry entry file (Python)
module path to the .wasm (Wasm)
language language hint, for example rust, c
pythonVersion optional, informational: a Python version hint (up to 32 characters). The host does not compare it with the interpreter, and ignores it for wasm plugins
abi Wasm ABI version, currently only 1
limits.memoryMb memory, 1–1024, default 64
limits.eventTimeoutMs event handling timeout, 10–60000, default 500
limits.storageMb storage quota, 0–1024, default 10
"permissions": {
"required": [
{ "id": "messages.read", "reason": "Counts the messages it sees." }
]
}

Each permission has an id and a reason (up to 500 characters; can be localized). The reason is shown to the user. Extra fields:

  • scope — only for messages.read: selected or all.
  • mode — for fs.folder: read or write.
  • ports — for net.local: port ranges on this computer.

The full list is in the permission reference.

What the plugin adds to the app:

Key Purpose
events events the plugin subscribes to (see Events)
commands /name commands with a description
menus menu items on surfaces (surface, id, title, icon, when)
icons the plugin’s own icons
outgoing / incoming message hooks
translator the plugin as a translation provider (name, languages, maxChars)
aiProvider the plugin as an AI provider (name, maxChars)
messages an object with a from array: { "from": ["com.example.other", "*"] } lists the plugins whose plugin.message is accepted ("*" — any); up to 64 entries; needs the plugins.message permission. The key is contributes.messages.from, not contributes.messages as a list
settingsPage the plugin has a settings page

Menu surfaces: message, chat, profile, composer, main_menu, tray, selection, shared_media. The when condition can limit an item with chat_type, out, has_media, has_text, media and forwarded. A menu item id may contain only a-z, 0-9 and -.

activation.on limits what can wake the plugin: startup, event, command, menu, settings, message, timer, translate, ai, toast. activation.background together with the background permission allows background work. dependencies and conflicts list other plugins by id with a version range. storage.export.prefixes and storage.export.exclude set which keys are exported on transfer, and storage.schema is the storage schema version. updates.feed is accepted by the parser but is not used by the app yet. signature is the manifest signature (the algorithm is set in signature.alg).