From Zero to a Forum Connector
Build a complete Subscriby connector for an imaginary forum with private boards, chapter by chapter — package, manifest, installation, webhooks, messages, boards, portal sign-in, slots, tests, and shipping.
This tutorial builds a connector from an empty directory to a package that passes the kit, for a platform that does not exist: Agora, a self-hosted forum. Every creator runs their own Agora at their own domain, and Agora has private boards only members can read. A connector lets a creator sell access to those boards through Subscriby: a member pays on the portal, Agora adds them to the board, and Subscriby removes them when their access ends.
Agora is imaginary so the tutorial can show every kind of decision a real platform forces without teaching you a real platform's API. Its API is small and typical:
| Agora gives us | We will use it for |
|---|---|
| An API key per forum, created by the forum's administrator | Installing: the creator pastes it. |
GET /api/me | Verifying the key and learning the bot user's name. |
POST /api/webhooks with a secret, DELETE /api/webhooks/{id} | Receiving events; disconnecting. |
Webhooks signed X-Agora-Signature: sha256=… over the raw body | Authenticating inbound calls. |
GET /api/boards/{id}, POST/DELETE /api/boards/{id}/members/{user} | Describing a board, adding and removing members. |
GET /api/boards/{id}/members/{user} | A member's standing in a board. |
POST /api/messages (private messages, BBCode) | Every message the core sends a member. |
GET /api/users/{id} | What the forum knows about an account. |
| 60 requests a minute per API key | Pacing. |
Two properties of Agora shape the connector: a board membership is the grant (Agora can add a user to a board directly, so there are no invite links), and private messages have no buttons (so the core's message actions have to become something a forum can show).
What we build
subscriby-connector-agora/
├── connector.json
├── composer.json
├── config/connector-agora.php
├── database/migrations/2026_10_01_000000_create_agora_forums_table.php
├── lang/{english,spanish,…}.json
├── resources/views/slots/install.blade.php
├── resources/views/slots/install-placeholder.blade.php
├── routes/inbound.php
├── routes/web.php
├── src/
│ ├── AgoraConnectorServiceProvider.php
│ ├── AgoraConnector.php
│ ├── Agora.php the HTTP client
│ ├── Http/WebhookController.php
│ ├── Http/BoardPickerController.php
│ ├── Models/Forum.php
│ └── Ports/
│ ├── AgoraInstallationLifecycle.php
│ ├── AgoraIdentityResolver.php
│ ├── AgoraInboundGateway.php
│ ├── AgoraFailureClassifier.php
│ ├── AgoraTextRenderer.php
│ ├── AgoraUiSlots.php
│ ├── AgoraMessenger.php
│ ├── AgoraAccessController.php
│ ├── AgoraSpaceCatalog.php
│ ├── AgoraPortalLoginMethod.php
│ └── AgoraRecoverySupport.php
└── tests/The manifest declares four capabilities: messaging, access_control, portal_login and recovery_probes. No broadcasts (sixty requests a minute is no rate for a broadcast), no management_surface (a forum has no admin conversation to render), no support_relay, no native payments.
What you need
- PHP 8.4 and Composer.
- The SDK alone for the conformance kit and the port fakes (its
TestRegistrystands in for the application's registry); a checkout of Subscriby only to test the core's side against your connector (Testing a connector shows both). - The manifest reference, the ports reference and the Core API reference open in another tab. The tutorial explains each decision once and links the reference for the rest.
How is this guide?
Beyond the kit
What Subscriby's own suite checks that the kit cannot from outside a package — isolation in both directions, translation parity, skeleton parity — and what review reads for.
1. The package
Start the Agora connector — composer.json, the service provider, a Connector class that binds nothing yet, configuration, and the HTTP client every port will share.