connector.json

The one file that says what a connector is, what it can do, how it talks and how the marketplace presents it — where it lives, how it is read, and a complete example.

connector.json sits at the root of the package and is the only place a connector describes itself. Nothing about a connector's identity, capabilities, limits or listing lives in PHP: the Connector class only binds ports, and the registry checks that what the class binds agrees with what the file declares.

The SDK reads the file when the application boots. It collects every problem before it stops, so an author fixing three mistakes sees all three, each named by its dotted path (listing.tagline, install.fields[1].type). Unknown keys are refused at every level, which is what turns a typo into a boot failure instead of a silently missing option.

The schema

The JSON Schema (draft 2020-12) is published at https://docs.subscriby.net/connectors/connector.schema.json. Point your editor at it with the $schema key and validation happens as you type:

{
    "$schema": "https://docs.subscriby.net/connectors/connector.schema.json",
    "key": "example"
}

The SDK validates the structural rules in PHP with no extra dependency (required keys, types, enumerations, patterns, unknown keys, the field and link rules), so a package that fails in an editor fails at boot with the same path named. A few limits only the schema states, such as the eighty-character tagline, so keep the editor validation on. The typed result is Subscriby\Connector\Data\ConnectorManifest, the object the registry hands to every surface.

The blocks

BlockRequiredWhat it declares
Identitykey, name, version, sdk, vendor.
installHow a creator connects: mode, scopes, the install and settings forms as fields.
resource_kindsEach kind of place the connector can gate and how access to it is granted.
capabilitiesWhat the connector can do; each one binds a port.
messagingThe platform's message limits.
pacingHow fast the platform lets an installation send.
management_commandsWhich of the core's admin commands the connector renders in-chat.
relay_modesThe support relay modes the connector offers.
recoveryWhich Disaster Recovery facets the connector performs.
listingWhat the marketplace shows, the words the marketing site borrows, the portal's button.

A complete example

{
    "$schema": "https://docs.subscriby.net/connectors/connector.schema.json",
    "key": "example",
    "name": "Example",
    "version": "1.0.0",
    "sdk": "^1.0",
    "vendor": "Acme",
    "install": {
        "mode": "paste_credential",
        "scopes": ["project"],
        "fields": [
            {
                "name": "intro",
                "type": "instructions",
                "label": "Create a bot and paste its token.",
                "steps": [
                    "Open the Example developer console.",
                    "Create a bot for your community.",
                    "Copy its token and paste it below, then click \":button\" in :app."
                ],
                "links": { "Example developer console": "https://developers.example.com" }
            },
            {
                "name": "token",
                "type": "secret",
                "label": "Bot token",
                "help": "Keep it secret: anyone who has it controls the bot.",
                "required": true,
                "rules": ["string", "min:20"]
            }
        ],
        "settings_fields": [
            { "name": "welcome", "type": "text", "label": "Welcome message" }
        ]
    },
    "resource_kinds": [
        {
            "kind": "room",
            "label": "Room",
            "portal_label": "Private room",
            "icon": "home",
            "grant_mode": "membership",
            "supports_early_admission_hold": false,
            "mirrorable": false
        }
    ],
    "capabilities": ["messaging", "access_control", "management_surface", "recovery_probes"],
    "messaging": {
        "max_length": 2000,
        "buttons_per_row": 3,
        "max_buttons": 9,
        "callback_data_bytes": 64,
        "supports_underline": true,
        "supports_spoiler": false,
        "supports_files": true
    },
    "pacing": {
        "min_interval_microseconds": 50000,
        "burst": 20,
        "per_recipient_interval_microseconds": 1000000
    },
    "management_commands": ["project_settings", "plan_manage", "broadcast"],
    "relay_modes": [],
    "recovery": { "probes": true },
    "listing": {
        "category": "community",
        "tagline": "Sell access to Example rooms, granted and removed automatically.",
        "overview": "Connect a bot and Subscriby runs your membership on Example…",
        "screenshots": [],
        "links": {
            "documentation": "https://docs.acme.test/subscriby",
            "support": "mailto:[email protected]",
            "privacy": "https://example.com/privacy",
            "terms": "https://example.com/terms",
            "homepage": "https://example.com"
        },
        "added_at": "2026-10-01",
        "changelog_url": "https://acme.test/changelog",
        "sign_in_required": false,
        "portal_cta": { "label": "Open the Example bot" },
        "marketing": {
            "audience": "Example communities",
            "place": "room",
            "places": "rooms and halls",
            "installation": "bot",
            "identity": "Example account"
        }
    }
}

Two real manifests to read beside it: the SDK's own fake connector, which declares as few capabilities as a connector can while still passing the kit, and the Telegram connector's, which declares every capability the SDK has and is quoted block by block through the pages that follow.

How the file is read

  1. The SDK's service provider locates the package root (the grandparent of the provider's src/ directory) and loads connector.json from it. A missing file, invalid JSON or a top-level value that is not an object fails at once with the path.
  2. Every block is read through a typed reader that records a problem and carries on: a missing required key, a wrong type, a value outside its enum, an unknown key, a string that fails its pattern, a field whose select has no options. The reader names the full path of each.
  3. When any problem was recorded the provider throws Subscriby\Connector\Exceptions\InvalidManifest listing them all, and the connector is not registered.
  4. The typed ConnectorManifest is handed to the registry with the Connector instance. The registry then checks the two against each other (a declared capability without its port, a bound port without its capability, a money-path capability on a package that is not official) and refuses the package on any mismatch. Capabilities lists those checks.

The file is the source

The conformance kit's manifest.file_is_the_source rule loads connector.json from disk and compares the key, name, version, SDK constraint, capability count and field counts with what the registry holds. A package that builds its manifest in PHP, or edits it after registration, fails that rule.

Translating what the file says

Every human-readable string in the file is written in English and doubles as a translation key: field labels, help texts, steps and select option labels are translated through the package's lang/<locale>.json files when the dashboard, the REST API or the apps render the form (the SDK's ManifestSettingsSchema does the lookup); resource-kind labels, the portal button label and the listing's tagline and overview go through the same files where a surface renders them. A connector that ships no translation for a string shows the English.

How is this guide?

On this page

Subscriby is a product designed by you — for you.

No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request