Publishing guide
How to package a plugin, what the marketplace checks, how review works, and how pricing works.
Package your plugin
A plugin is a zip with infinibot.plugin.json at the root (or inside one top-level folder). The marketplace accepts manifest version 2 only. Leave out node_modules, tests and build caches.
my-plugin-1.0.0.zip
infinibot.plugin.json
index.ts
src/…
assets/icon.png
assets/cover.png
assets/shot-1.webp
The manifest needs an id (2 to 40 characters: a-z, 0-9, dashes), a name, a semver version, engines, a configSchema and the permissions it wants. The optional listing block pre-fills your marketplace page.
{
"manifestVersion": 2,
"id": "acme-notes",
"name": "Acme Notes",
"version": "1.0.0",
"engines": { "infinibot-plugin-api": "^2.0.0" },
"configSchema": { "type": "object", "properties": {} },
"permissions": {
"network": ["https://api.acme.dev"],
"exec": false
},
"listing": {
"tagline": "Shared notes your agents can read and write",
"description": "Long **markdown** description",
"category": "productivity",
"tags": ["notes", "memory"],
"icon": "assets/icon.png",
"cover": "assets/cover.png",
"screenshots": [{ "src": "assets/shot-1.webp", "caption": "The notebook" }]
}
}
Validation on upload
An upload is refused, with the reason, when any of these is true. Nothing is stored in that case.
- The file is not a zip, is larger than 20 MB, or expands suspiciously (zip bomb).
- An entry has an absolute path, a
..segment or a backslash (zip-slip), or is a symbolic link or special file. - The manifest is missing, is not valid JSON, is not version 2, or fails the same parser InfiniBot uses to load plugins.
- The plugin id belongs to another publisher or is reserved.
- The version is not higher than your last published version.
- A listing image named in the manifest is not in the zip.
The server computes the sha256 of the zip. InfiniBot checks that hash again before it installs anything.
The automated scan
The scan never blocks a submission by itself. It produces a list that you see right after the upload and that the reviewer works through.
| Finding | Level | What triggers it |
|---|---|---|
| Gated permissions | High | permissions.gated entries. They stay off until the workspace owner grants them. |
| Process execution | High | permissions.exec, or code that spawns processes without declaring it. |
| Native binaries | High | ELF, Mach-O or PE files, and .node, .so, .dll, .dylib, .exe. |
| Install scripts | High | preinstall, install, postinstall or prepare in a package.json. |
| Obfuscated or minified-only code | High | Code a reviewer cannot read. Ship the readable source. |
| Undeclared hosts | Warn | A URL in the code whose host is not in permissions.network. |
| Dynamic code | Warn | eval or new Function. |
Review
Every plugin and every new version is reviewed. A submission moves through these states:
draft -> submitted -> in review -> approved -> published
in review -> changes requested -> (you edit and resubmit)
in review -> rejected
published -> unlisted | suspended
- Changes requested: the reviewer's notes appear in the publisher portal. Fix the listing or upload a corrected zip into the same submission, then resubmit.
- Rejected: that version is closed. Submit a new version when the problem is fixed.
- Unlisted: hidden from the marketplace, direct links still work. Suspended: taken down, downloads stop.
- While a new version is in review, the previous version stays live.
Pricing and distribution
A plugin is Free or Paid.
- Free: we host the zip and InfiniBot installs it in one click.
- Paid: you set the price and give an https purchase / download page (Whop, Gumroad, a Stripe link). The listing shows the price and its Buy button opens your page in a new tab. You take the payment and deliver the zip; the buyer installs it with Plugins → Import plugin. Nothing is downloaded from the marketplace, and there are no license keys. The link must be https, and the marketplace blocks some domains.
- External distribution (free): only the listing lives here and it links to your site.
Upload the zip with a paid submission as well: reviewers read the code before the listing goes live, even though buyers get the plugin from you. If your plugin checks a purchase at run time, do that in your own code and declare the host it contacts under permissions.network.
The InfiniBot team can adjust catalogue settings such as featuring, ordering and visibility. InfiniBot's own paid plugins are sold on this site.
Registry API
InfiniBot reads the marketplace through three public endpoints.
| Endpoint | Returns |
|---|---|
GET /api/marketplace/index.json | Every published plugin, with its latest version, price, sha256 and download URL. |
GET /api/marketplace/plugins/<id> | One plugin plus its version history. |
GET /api/marketplace/plugins/<id>/download?version=latest | A redirect to the zip of a free plugin. A plugin sold by its publisher answers 404 with its purchase page: there is nothing to download here. |
Open the publisher portal to submit your first plugin, or go back to the marketplace.