AstrBot Plugin Market JSON Specification
Specification version: 2026-06-27
Market JSON schema version: 1
1. Scope
This document defines the JSON format for AstrBot plugin market sources.
2. Terms
PluginRecord: One plugin entry in a market source.MarketMetadata: Metadata for the market source itself.plugin_id: The global plugin package identifier.metadata.yaml: The plugin metadata file inside the installed plugin package.
The terms MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are normative.
3. Document Format
A plugin market source MUST be a UTF-8 JSON object.
The root object MUST contain the reserved $meta key.
All root keys other than $meta MUST be one of:
- a
plugin_idstring - a
namestring under the compatibility exception in Section 5
Each root key other than $meta MUST map to a PluginRecord object:
{
"$meta": {
"schema_version": 1,
"name": "AstrBot Official Plugin Market",
"version": "2026-06-27",
"homepage": "https://astrbot.app",
"repository": "https://github.com/AstrBotDevs/AstrBot_Plugins_Collection"
},
"owner/astrbot_plugin_foo": {
"author": "owner",
"name": "astrbot_plugin_foo",
"version": "1.0.0",
"repo": "https://github.com/owner/astrbot_plugin_foo",
"desc": "Plugin description"
},
"astrbot_plugin_bar": {
"author": "owner",
"version": "1.0.0",
"repo": "https://github.com/owner/astrbot_plugin_bar",
"desc": "Compatibility record using the root key as name"
}
}The root object MUST NOT contain top-level metadata fields outside $meta.
4. Market Metadata
$meta MUST NOT be interpreted as a PluginRecord.
$meta MUST be a MarketMetadata object.
MarketMetadata MUST contain:
| Field | Type | Requirement |
|---|---|---|
schema_version | integer | Market JSON schema version. MUST be 1 for this specification. |
MarketMetadata MAY contain:
| Field | Type | Requirement |
|---|---|---|
name | string | Human-readable market source name. |
version | string | Market source data version. MUST NOT be used as the schema version. |
homepage | string | HTTPS homepage URL. |
repository | string | HTTPS repository URL for the market source data. |
description | string | Market source description. |
updated_at | string | ISO 8601 timestamp. |
$meta MUST NOT be used for:
- plugin identity
- install source resolution
- update source resolution
- plugin security validation
5. Plugin Identity
plugin_id is defined as:
metadata.author + "/" + metadata.nameFor every PluginRecord:
- The root key SHOULD equal
${author}/${name}. - The root key MAY equal
nameunder the compatibility exception below. authorMUST equalmetadata.yaml.author.nameMUST equalmetadata.yaml.name.plugin_idMUST be globally unique across the AstrBot plugin ecosystem.- Two
plugin_idvalues that are equal after lowercase normalization MUST NOT both exist. repoMUST NOT be used as plugin identity.root_dir_name, local directory names, display names, and registry names MUST NOT be used as plugin identity.
author and name:
- MUST be non-empty strings.
- MUST be trimmed.
- MUST NOT contain
/. - MUST NOT contain ASCII control characters.
- SHOULD be stable package identity values, not display names.
5.1. Name Key Compatibility Exception
A root key MAY equal metadata.yaml.name instead of ${author}/${name}.
When this exception is used:
- The root key MUST NOT contain
/. authorMUST be present.nameMAY be omitted.- If
nameis present, it MUST equal the root key. - The root key MUST equal
metadata.yaml.name. - Consumers MUST construct
plugin_idas${author}/${root_key}.
6. Required Fields
Each PluginRecord MUST contain:
| Field | Type | Requirement |
|---|---|---|
author | string | Plugin author namespace. MUST match metadata.yaml.author. |
name | string | Plugin package name. MUST match metadata.yaml.name. MAY be omitted only when the root key equals metadata.yaml.name. |
version | string | Plugin version. MUST match metadata.yaml.version. |
repo | string | HTTPS GitHub repository URL used for source attribution and installation. |
desc | string | Default plugin description. |
7. Optional Fields
| Field | Type | Requirement |
|---|---|---|
display_name | string | Human-readable plugin name. |
short_desc | string | Short description for compact UI. |
download_url | string | HTTPS ZIP download URL. Installed package identity MUST still match author/name. |
logo | string | HTTPS image URL or relative static asset path. |
tags | string[] | Tag list. |
category | string | Market category key. |
support_platforms | string[] | Supported platform keys. |
astrbot_version | string | AstrBot version requirement expression. |
social_link | string | Author or project HTTPS URL. |
updated_at | string | ISO 8601 timestamp. |
i18n | object | Localized display fields. |
pinned | boolean | Market recommendation flag. |
stars | integer | Non-negative star count or ranking signal. |
download_count | integer | Non-negative download count. |
7.1. Repository URL
repo MUST be one of:
https://github.com/{owner}/{repository}
https://github.com/{owner}/{repository}.git
https://github.com/{owner}/{repository}/tree/{branch}owner, repository, and branch MUST match:
[A-Za-z0-9_-]+repo MUST NOT be:
- an HTTP URL
- an SSH URL
- a non-GitHub URL
- a GitHub Enterprise URL
- a GitHub file, release, pull request, issue, or subdirectory URL
download_url MAY point to any HTTPS ZIP URL.
7.2. Localized Fields
i18n keys SHOULD be BCP 47 locale tags.
Each locale object MAY contain:
{
"display_name": "Localized name",
"desc": "Localized description",
"short_desc": "Localized short description"
}8. Reserved Fields
Market sources MUST NOT use these fields inside PluginRecord objects:
| Field | Reason |
|---|---|
plugin_id | Derived from author/name. |
market_plugin_id | Runtime/client compatibility field, not market data. |
market_plugin_identifier | Deprecated runtime/client compatibility field. |
root_dir_name | Local installation field. |
local_plugin_name | Local installation field. |
install_method | Local installation field. |
registry_url | Local installation field. |
registry_name | Local installation field. |
installed_at | Local installation field. |
Consumers MUST NOT use reserved fields for plugin identity.
The root key $meta is reserved for MarketMetadata.
9. Deprecated Fields
These fields MAY be accepted by clients during migration, but new market sources MUST NOT emit them:
| Deprecated Field | Replacement |
|---|---|
support_platform | support_platforms |
platform | support_platforms |
10. Unknown Fields
Consumers MAY preserve unknown fields.
Consumers MUST NOT use unknown fields for:
- plugin identity
- install source resolution
- update source resolution
- security validation
11. Validation Rules
A market source is valid only if all rules pass:
- The root JSON value is an object.
$metais present.$metais an object.$meta.schema_versionis the integer1.- Every root key other than
$metais either aplugin_idor anamekey. - Every root value other than
$metais aPluginRecordobject. - Every record contains all required fields except
nameMAY be omitted when the root key is anamekey. - Every required string field is non-empty after trimming.
authorand presentnamevalues do not contain/.- The root key equals
${author}/${name}exactly, or the root key equalsnameexactly under the compatibility exception. - No two IDs are equal after lowercase normalization.
repois an HTTPS GitHub repository URL.- If present,
download_urlis an HTTPS URL. - If present,
tagsis an array of strings. - If present,
support_platformsis an array of strings. - If present,
starsis a non-negative integer. - If present,
download_countis a non-negative integer. - If present,
updated_atis an ISO 8601 timestamp. - If present,
$meta.homepageis an HTTPS URL. - If present,
$meta.repositoryis an HTTPS URL. - If present,
$meta.updated_atis an ISO 8601 timestamp. - The package resolved from
repoordownload_urlcontainsmetadata.yaml. metadata.yaml.authorequalsauthor.metadata.yaml.nameequalsname.metadata.yaml.versionequalsversion.
12. Installation Rules
For market installation:
- The client sends the selected
plugin_idand registry source to the backend. - The backend resolves the
PluginRecordfrom that registry source byplugin_id. - The backend installs using
download_urlwhen available; otherwise it installs usingrepo. - After installation, the backend reads the installed
metadata.yaml. - The installed
metadata.yaml.author/nameMUST equal the selectedplugin_id. - If identity validation fails, installation MUST fail.
- A successful market install MAY persist
repo,download_url, registry information, and install time in local state.
13. Update Rules
For market-installed plugins:
- Update checks MUST use the registry source recorded at installation time.
- Update checks MUST resolve the market record by
plugin_id. - Version comparison MUST use the installed metadata version and the market record
version. - Update execution MUST use the resolved market record
repo/download_url.
For non-market installs:
- URL installs, Git installs, and upload installs MUST NOT be treated as market installs.
- They MAY persist
plugin_idfrom installedmetadata.yaml. - They MUST NOT enable market update checks unless explicitly bound to a market source.
14. Source Binding Rules
When binding an installed non-market plugin to a market source:
- The installed plugin identity MUST be read from installed
metadata.yaml. - Candidate market records MUST have the same
plugin_id. - Candidate market records SHOULD have the same repository identity.
- Binding MUST persist the selected registry source and
plugin_id.
15. Compatibility
Consumers MAY read legacy market sources during migration.
For legacy sources:
- Consumers MAY accept sources without
$meta.schema_versionduring migration. - Consumers SHOULD construct
plugin_idfromauthor/name. - Consumers SHOULD reject entries without
authorornamefor market installation. - Consumers MAY use legacy root keys for display only.
- Consumers MUST NOT use legacy root keys as plugin identity unless the key equals
${author}/${name}.
New market sources MUST include $meta.schema_version.
