Build a plugin
A plugin is an HTTPS endpoint that receives signed events from RolChat, plus optional calls it makes back into RolChat. There is no code to upload and no runtime to host inside RolChat.
1. Register the plugin
Section titled “1. Register the plugin”In Settings → Plugins → Catalogue → Custom, or with the API:
POST /api/v1/pluginsAuthorization: Bearer rcp_…X-Account-Id: <account uuid>
{ "plugin_type": "custom", "name": "Acme back office", "api_key_external": "<key RolChat should use to call you, optional>", "webhook_url_outbound": "https://backoffice.acme.com/rolchat", "sync_config": { "enrich_contacts": true, "enrich_companies": true, "sync_agent_schedule": false, "create_contacts": false }}The response contains the plugin ID and the webhook secret, shown once. Store it; every event RolChat sends is signed with it, and every event you send to RolChat must be too.
2. Receive events from RolChat
Section titled “2. Receive events from RolChat”RolChat posts to webhook_url_outbound when things change:
| Event | When |
|---|---|
chats.conversation.created |
A conversation starts |
crm.contact.created |
A contact is created |
crm.contact.updated |
A contact changes |
tickets.ticket.created |
A ticket is created |
tickets.ticket.status_changed |
A ticket moves |
marketing.meeting.booked |
A meeting is booked |
marketing.meeting.cancelled |
A meeting is cancelled |
{ "event": "crm.contact.created", "account_id": "…", "plugin_id": "…", "timestamp": "2026-04-13T14:32:00Z", "data": { … }}Verify the signature, freshness and nonce exactly as described in Webhooks, answer 200 quickly, and deduplicate by event ID. The broader event families available to subscriptions are in the event catalogue.
3. Send events into RolChat
Section titled “3. Send events into RolChat”Post to your plugin’s inbound endpoint, signed with the same secret:
POST /api/v1/webhooks/plugin/{plugin_id}Content-Type: application/jsonX-RolChat-Timestamp: 1713615825X-RolChat-Signature: sha256=…X-RolChat-Nonce: nonce_01HK…
{ "event": "contact.data_updated", "timestamp": "2026-04-13T14:32:00Z", "data": { "external_id": "acme_user_123", "email": "user@company.com", "plugin_data": { "role": "Admin", "registered_at": "2024-03-15", "last_login": "2026-04-11" } }}Response: { "received": true, "matched_contact_id": "…" }.
| Inbound event | What RolChat does |
|---|---|
contact.data_updated |
Stores plugin_data on the matching contact |
company.data_updated |
Stores plugin_data on the matching company |
contact.created_external |
Creates or updates a contact |
agent.unavailable |
Runs the booking form’s unavailability strategy (cancel, reassign, offer a new slot) |
agent.available |
Notifies the agent about pending meetings |
Matching. RolChat looks the contact up by e-mail first, then by the external_id your plugin stored earlier. Not found: a lead is created if sync_config.create_contacts is on, otherwise the event is logged as unmatched.
4. Where plugin data shows up
Section titled “4. Where plugin data shows up”Contact and company cards show a section named after your plugin with the fields you sent, read-only, with the time of the last update. The same data is returned by the API:
GET /api/v1/contacts/{id}{ "data": { "id": "…", "plugin_data": { "{plugin_id}": { "plugin_name": "Acme back office", "updated_at": "…", "data": { … } } } }}Automation conditions can test plugin data, so a rule can route a conversation by the customer’s plan in your system.
5. Management API
Section titled “5. Management API”GET /api/v1/plugins connected pluginsGET /api/v1/plugins/catalog cataloguePOST /api/v1/plugins connectGET /api/v1/plugins/{id} detailsPATCH /api/v1/plugins/{id} settingsDELETE /api/v1/plugins/{id} removePOST /api/v1/plugins/{id}/activate activatePOST /api/v1/plugins/{id}/deactivate pausePOST /api/v1/plugins/{id}/test test the external keyPOST /api/v1/plugins/{id}/webhook-secret/rotate rotate with a 7-day overlapPOST /api/v1/plugins/{id}/webhook-secret/revoke revoke immediatelyGET /api/v1/plugins/{id}/events event log (direction, status, type, dates, cursor)GET /api/v1/plugins/{id}/sync-schedule schedule and last runPATCH /api/v1/plugins/{id}/sync-schedule { enabled, cron, timezone }POST /api/v1/plugins/{id}/sync-schedule/trigger run now (one per 5 minutes)6. Manifest
Section titled “6. Manifest”A published plugin declares itself in a manifest: name, category, the scopes it requests, the events it subscribes to, its settings form, optional allowed_source_ips, recommended_rotation_days, and its pricing if paid. The manifest drives the connect screen and the review before a community plugin is listed.
Limits and hygiene
Section titled “Limits and hygiene”- Inbound body up to 5 MB; outbound 1 MB by default.
- Plugin API keys are limited to 300 requests per minute; inbound webhooks to 120 per minute per plugin.
- Sustained delivery failures mark a plugin degraded; more than half failing for an hour pauses it and notifies the account admins.
- Never log or echo the webhook secret. Rotate it if you suspect exposure; the overlap window means nothing breaks.