License and Limits
Shoehorn ships with a free tier built in. No license key needed to run it. Higher editions raise the cluster and node limits and unlock paid support. All features are available on every edition. There’s no feature gating.
Editions
Section titled “Editions”| Edition | Key required | Clusters | Nodes | Pricing |
|---|---|---|---|---|
| Free | No | 1 | 5 | Free |
| Beta | Yes | 3 | Unlimited | 6 months free, then a 30-day read-only window before auto-disconnect |
| Standard | Yes | 3 + overage | Unlimited | €299/mo. Each extra cluster bills €99/mo |
| Airgapped | Yes | Per license | Per license | Custom. No phone-home. |
Entities, users, integrations, repositories, and addons are unlimited on every edition. Only clusters (and Free-tier nodes) are counted.
Free-tier node cap
Section titled “Free-tier node cap”Free is sized for one small cluster. The cap is 5 nodes with a soft buffer to 7. New nodes joining above the buffer are blocked at the agent. Existing nodes are never evicted.
| Node count | Behavior |
|---|---|
| 1–5 | Normal |
| 6–7 | Warning surfaced in the admin UI |
| Above 7 | Agent refuses new joins. Already-joined nodes keep running. |
The buffer exists so a node added during a deploy doesn’t immediately get blocked while the operator decides whether to upgrade.
Beta period and grace window
Section titled “Beta period and grace window”A Beta license runs free for 6 months from issue. After that:
- 30-day read-only window. The admin UI shows a banner. Mutating API calls return
423 BETA_ENDED_READ_ONLY. Catalog reads, dashboards, and agent traffic keep working, so existing data stays observable. License activation also keeps working, so a customer can switch to Standard without restoring write access first. - Auto-disconnect. When the 30 days expire, a daily background job keeps one cluster (smallest node count, oldest first) and revokes the agent tokens on the rest. Data stays in place. The disconnected agents can’t authenticate until they’re reactivated under a paid license.
Beta licenses issued before 2026-11-10 won’t expire before that date even if their natural 6-month end is earlier. This protects legacy Beta customers from a sudden read-only flip when per-cluster pricing took over.
Standard cluster overage
Section titled “Standard cluster overage”Standard includes 3 clusters in the base subscription. When an agent registers a cluster past your purchased capacity, the registration parks as pending instead of failing.
Admins approve or reject from Admin > Settings > License, or directly via the API:
# List pending registrationscurl https://shoehorn.example.com/api/v1/license/pending-clusters \ -H "Authorization: Bearer <admin-token>"
# Approve (bumps purchased_clusters by 1, bills +€99/mo)curl -X POST https://shoehorn.example.com/api/v1/license/pending-clusters/<cluster_id>/approve \ -H "Authorization: Bearer <admin-token>"
# Reject (clears the row; the agent will keep retrying until you fix the deploy)curl -X DELETE https://shoehorn.example.com/api/v1/license/pending-clusters/<cluster_id> \ -H "Authorization: Bearer <admin-token>"Approving increments your purchased cluster count by one. The agent comes online on its next heartbeat, around 30 seconds. Rejecting removes the row, but the agent will park itself again on its next register attempt. Fix the deployment to stop the loop.
License key format
Section titled “License key format”Keys are issued as SHP-<EDITION>-<PAYLOAD>.<SIGNATURE> where edition is one of:
BEfor BetaSTfor StandardAGfor Airgapped
The prefix is cosmetic. The actual tier comes from the signed payload.
View license status
Section titled “View license status”In the UI
Section titled “In the UI”Admin > Settings > License shows the active edition, licensee, expiration, cluster and node usage, pending registrations, and any warnings. Beta tenants past their end date also see the read-only countdown.
Via API
Section titled “Via API”curl https://shoehorn.example.com/api/v1/license \ -H "Authorization: Bearer <admin-token>"
curl https://shoehorn.example.com/api/v1/license/usage \ -H "Authorization: Bearer <admin-token>"The license-status response includes beta_ends_at, beta_grace_ends_at, and is_read_only. They’re set only when relevant; is_read_only is false for non-Beta editions.
Activate a license
Section titled “Activate a license”curl -X POST https://shoehorn.example.com/api/v1/license/activate \ -H "Authorization: Bearer <admin-token>" \ -H "Content-Type: application/json" \ -d '{"license_key":"SHP-ST-..."}'Successful activation updates the edition, limits, and expiration for the current tenant. If the tenant was in a Beta read-only window, activation lifts the write block on the next status read.
Deactivate a license
Section titled “Deactivate a license”curl -X POST https://shoehorn.example.com/api/v1/license/deactivate \ -H "Authorization: Bearer <admin-token>"The tenant falls back to Free limits (1 cluster, 5 nodes).
Expiration
Section titled “Expiration”Shoehorn warns when a license expires within 30 days. After expiry the license is marked invalid in the status response and the admin UI. Limits keep resolving from the stored edition until the license is changed or removed.
Beta licenses don’t expire the same way. The read-only window plus auto-disconnect handle that transition (see Beta period and grace window).
Operational notes
Section titled “Operational notes”- License checks are tenant-aware.
- Usage counts come from the live database, not cached estimates.
- API keys and automation clients see the same tenant limits as interactive users.
- The auto-disconnect job runs once a day on the worker service. With multiple worker replicas, only one runs it per cycle via a distributed lock.
- If license data is unreadable, Shoehorn falls back to Free limits.
See also
Section titled “See also”- API Overview: authentication and conventions
- Teams
- K8s Agent