Hidden and frankly scummy licensing model
I found WebhookX after seeing it being hyped and initially thought it looked genuinely promising.
The lack of a UI was already a trade-off, but fine. If the project is otherwise usable as an open-source, self-hosted tool, I can live with a CLI-first and GitOps-oriented workflow.
I started planning an actual setup around it:
- configuration managed through GitHub;
- secrets injected through CI;
- separate workspaces for separate projects;
- automatic declarative synchronization;
- one central self-hosted webhook infrastructure.
Then I dug into the source code and found this:
|
var plans = map[string]Plan{ |
|
"free": { |
|
Name: "free", |
|
Plugins: FreePlugins, |
|
Features: []string{}, |
|
ForbiddenAPIs: map[string]*Condition{ |
|
"/workspaces": {Methods: []string{"POST"}}, |
|
"/workspaces/{id}": {Methods: []string{"DELETE"}}, |
|
"/workspaces/{workspace}/config/sync": {Methods: []string{"POST"}, ExcludeDefaultWorkspace: true}, |
|
"/workspaces/{workspace}/config/dump": {Methods: []string{"POST"}, ExcludeDefaultWorkspace: true}, |
|
"/workspaces/{workspace}/endpoints": {Methods: []string{"POST"}, ExcludeDefaultWorkspace: true}, |
|
"/workspaces/{workspace}/endpoints/{id}": {Methods: []string{"PUT", "DELETE"}, ExcludeDefaultWorkspace: true}, |
|
"/workspaces/{workspace}/sources": {Methods: []string{"POST"}, ExcludeDefaultWorkspace: true}, |
|
"/workspaces/{workspace}/sources/{id}": {Methods: []string{"PUT", "DELETE"}, ExcludeDefaultWorkspace: true}, |
|
"/workspaces/{workspace}/events": {Methods: []string{"POST"}, ExcludeDefaultWorkspace: true}, |
|
"/workspaces/{workspace}/events/{id}/retry": {Methods: []string{"POST"}, ExcludeDefaultWorkspace: true}, |
|
"/workspaces/{workspace}/plugins": {Methods: []string{"POST"}, ExcludeDefaultWorkspace: true}, |
|
"/workspaces/{workspace}/plugins/{id}": {Methods: []string{"PUT", "DELETE"}, ExcludeDefaultWorkspace: true}, |
|
}, |
|
Limits: map[string]int{}, |
|
}, |
|
"enterprise": { |
|
Name: "enterprise", |
|
Plugins: append(FreePlugins, EnterprisePlugins...), |
|
Features: []string{"secret"}, |
|
ForbiddenAPIs: map[string]*Condition{}, |
|
Limits: map[string]int{}, |
|
}, |
|
} |
Apparently, the official free version does not allow users to create additional workspaces.
It also blocks creating or modifying sources, endpoints, plugins, and declarative configuration in any workspace other than default.
So the advertised multi-tenancy model is effectively locked behind an Enterprise license.
That is already disappointing. What makes it significantly worse is that this limitation is not clearly disclosed anywhere users would reasonably look before deploying the product.
Your documentation explicitly advertises multi-tenancy
The WebhookX documentation lists the following under Key Features:
Multi-tenancy
Each workspace provides the isolation of entities, ensuring that traffic from one tenant does not interfere with another.
That wording presents workspaces and tenant isolation as a normal key capability of WebhookX.
It does not say:
Multiple workspaces require an Enterprise license.
It does not say:
The free version is limited to a single default workspace.
It does not say:
Multi-tenancy is only available to paying customers.
Instead, multi-tenancy is advertised alongside high performance, zero loss, plugins, rate limiting, observability, and scalability as a key feature of the product.
The public API documentation also presents workspace creation as available
The public Admin API documentation contains:
with the summary:
Create a workspace
The OpenAPI specification describes the request and a normal successful 201 response.
There is no licensing note, no Enterprise badge, no warning, and no mention that the official free image will reject this request with 403.
A developer reading the feature overview and API documentation has every reason to believe that multiple workspaces are part of the available self-hosted product.
Only after reading pkg/license/plan.go does the actual behavior become visible.
I wasted time designing around a feature that is silently disabled
I spent roughly an hour designing a deployment around WebhookX before discovering this.
My intended setup depended on workspaces for clean separation between unrelated projects:
WebhookX
├── Workspace: Project A
│ ├── Webhook source 1
│ └── Webhook source 2
├── Workspace: Project B
│ └── Webhook source 1
└── Workspace: Project C
This seemed like the obvious intended use of a product whose documentation advertises multi-tenancy and explicitly says that each workspace provides isolation between tenants.
Instead, the free version effectively forces everything into:
Workspace: default
├── Project A sources and endpoints
├── Project B sources and endpoints
├── Project C sources and endpoints
└── every configuration boundary mixed together
Naming conventions and path prefixes are not tenant isolation.
They do not provide separate configuration boundaries, separate administrative scopes, separate event views, or a limited blast radius when a declarative sync goes wrong.
This is not an Enterprise feature
I have no problem with an open-source company charging for actual Enterprise functionality.
Reasonable Enterprise features include:
- SSO, SAML, or OIDC;
- RBAC and granular permissions;
- centralized identity and user management;
- audit logs;
- compliance features;
- official secret-manager integrations;
- advanced high availability features;
- support contracts and SLAs;
- organization-wide governance and policy controls.
Those are genuine Enterprise requirements.
Basic isolation between unrelated projects is not.
This is not about a large company needing sophisticated multi-tenant administration. This is about a developer wanting to prevent the webhooks, secrets, endpoints, events, and configuration of Project A from being mixed with Project B.
That is basic operational hygiene.
WebhookX does not provide another project abstraction underneath a workspace. Sources, endpoints, plugins, events, and delivery attempts belong directly to a workspace.
The workspace is therefore not an optional organizational layer above projects.
The workspace is the project isolation boundary.
Restricting the free version to one writable workspace effectively restricts the product to one properly isolated project per installation.
The paid feature is not advanced Enterprise administration.
The paid feature is basic separation between projects.
That is what makes this licensing decision so frustrating. It takes a core architectural capability and artificially turns it into an Enterprise feature.
This is especially hard to justify for a self-hosted product
WebhookX is not paying for my infrastructure.
The user provides:
- the server;
- PostgreSQL;
- Redis;
- storage;
- bandwidth;
- monitoring;
- backups;
- updates;
- maintenance;
- incident response.
Allowing another workspace does not meaningfully increase WebhookX's hosting costs because WebhookX is not hosting anything.
Of course, maintainers need a sustainable business model.
But disabling basic project isolation in a self-hosted infrastructure product is a poor way to create one, especially when the restriction is not clearly disclosed before installation.
The workaround destroys the point of the product
The obvious workaround is to deploy one complete WebhookX stack per project:
Project A
└── WebhookX + PostgreSQL + Redis
Project B
└── WebhookX + PostgreSQL + Redis
Project C
└── WebhookX + PostgreSQL + Redis
That means:
- more containers;
- more databases;
- more queues;
- more backups;
- more updates;
- more monitoring;
- more failure points.
At that point, the supposedly central webhook infrastructure is no longer central.
Users are forced to duplicate the entire stack solely because the existing project-isolation mechanism is commercially disabled.
The other option is to put unrelated projects into the same default workspace and accept that they share a configuration boundary, administration boundary, and event namespace.
Neither option is reasonable.
Please disclose this honestly
At an absolute minimum, the feature documentation should say directly next to “Multi-tenancy”:
Multiple workspaces require an Enterprise license. The free edition is limited to the default workspace.
The workspace creation API documentation should also state:
This endpoint requires an Enterprise license.
The README and quickstart should link to a public and easy-to-find feature comparison covering:
- what the free version supports;
- which APIs are restricted;
- which plugins and features require Enterprise;
- how an Enterprise license is obtained;
- and what it costs.
Users should not have to inspect licensing middleware in the source code to discover that an advertised key feature is unavailable in the official free deployment.
The licensing decision itself is frustrating.
Advertising multi-tenancy as a key feature, documenting POST /workspaces as a normal available operation, and hiding the actual restriction exclusively in licensing code is what makes this feel dishonest and scummy.
Hidden and frankly scummy licensing model
I found WebhookX after seeing it being hyped and initially thought it looked genuinely promising.
The lack of a UI was already a trade-off, but fine. If the project is otherwise usable as an open-source, self-hosted tool, I can live with a CLI-first and GitOps-oriented workflow.
I started planning an actual setup around it:
Then I dug into the source code and found this:
webhookx/pkg/license/plan.go
Lines 44 to 72 in d30d51a
Apparently, the official free version does not allow users to create additional workspaces.
It also blocks creating or modifying sources, endpoints, plugins, and declarative configuration in any workspace other than
default.So the advertised multi-tenancy model is effectively locked behind an Enterprise license.
That is already disappointing. What makes it significantly worse is that this limitation is not clearly disclosed anywhere users would reasonably look before deploying the product.
Your documentation explicitly advertises multi-tenancy
The WebhookX documentation lists the following under Key Features:
That wording presents workspaces and tenant isolation as a normal key capability of WebhookX.
It does not say:
It does not say:
It does not say:
Instead, multi-tenancy is advertised alongside high performance, zero loss, plugins, rate limiting, observability, and scalability as a key feature of the product.
The public API documentation also presents workspace creation as available
The public Admin API documentation contains:
with the summary:
The OpenAPI specification describes the request and a normal successful
201response.There is no licensing note, no Enterprise badge, no warning, and no mention that the official free image will reject this request with
403.A developer reading the feature overview and API documentation has every reason to believe that multiple workspaces are part of the available self-hosted product.
Only after reading
pkg/license/plan.godoes the actual behavior become visible.I wasted time designing around a feature that is silently disabled
I spent roughly an hour designing a deployment around WebhookX before discovering this.
My intended setup depended on workspaces for clean separation between unrelated projects:
This seemed like the obvious intended use of a product whose documentation advertises multi-tenancy and explicitly says that each workspace provides isolation between tenants.
Instead, the free version effectively forces everything into:
Naming conventions and path prefixes are not tenant isolation.
They do not provide separate configuration boundaries, separate administrative scopes, separate event views, or a limited blast radius when a declarative sync goes wrong.
This is not an Enterprise feature
I have no problem with an open-source company charging for actual Enterprise functionality.
Reasonable Enterprise features include:
Those are genuine Enterprise requirements.
Basic isolation between unrelated projects is not.
This is not about a large company needing sophisticated multi-tenant administration. This is about a developer wanting to prevent the webhooks, secrets, endpoints, events, and configuration of Project A from being mixed with Project B.
That is basic operational hygiene.
WebhookX does not provide another project abstraction underneath a workspace. Sources, endpoints, plugins, events, and delivery attempts belong directly to a workspace.
The workspace is therefore not an optional organizational layer above projects.
The workspace is the project isolation boundary.
Restricting the free version to one writable workspace effectively restricts the product to one properly isolated project per installation.
The paid feature is not advanced Enterprise administration.
The paid feature is basic separation between projects.
That is what makes this licensing decision so frustrating. It takes a core architectural capability and artificially turns it into an Enterprise feature.
This is especially hard to justify for a self-hosted product
WebhookX is not paying for my infrastructure.
The user provides:
Allowing another workspace does not meaningfully increase WebhookX's hosting costs because WebhookX is not hosting anything.
Of course, maintainers need a sustainable business model.
But disabling basic project isolation in a self-hosted infrastructure product is a poor way to create one, especially when the restriction is not clearly disclosed before installation.
The workaround destroys the point of the product
The obvious workaround is to deploy one complete WebhookX stack per project:
That means:
At that point, the supposedly central webhook infrastructure is no longer central.
Users are forced to duplicate the entire stack solely because the existing project-isolation mechanism is commercially disabled.
The other option is to put unrelated projects into the same
defaultworkspace and accept that they share a configuration boundary, administration boundary, and event namespace.Neither option is reasonable.
Please disclose this honestly
At an absolute minimum, the feature documentation should say directly next to “Multi-tenancy”:
The workspace creation API documentation should also state:
The README and quickstart should link to a public and easy-to-find feature comparison covering:
Users should not have to inspect licensing middleware in the source code to discover that an advertised key feature is unavailable in the official free deployment.
The licensing decision itself is frustrating.
Advertising multi-tenancy as a key feature, documenting
POST /workspacesas a normal available operation, and hiding the actual restriction exclusively in licensing code is what makes this feel dishonest and scummy.