Commercial Plans & Feature Entitlements
The Ternis Auth & SSO Platform provides a centralized plan and entitlement management system. Rather than having each distributed application (e.g. ternisdomains.de, thosted.de, analytics portals) build separate subscription tables, applications consume the user's active plan, feature toggles, and numerical quotas directly via standard OAuth tokens and REST API endpoints.
1. Platform Plan Matrix
Ternis Auth ships with 4 standard subscription tiers:
| Plan | Slug | Price | Domains Limit | API Rate Limit | Dedicated IP | 24/7 SLA | SSO SAML |
|---|---|---|---|---|---|---|---|
| Community Free | free |
Free | 2 | 1,000 / mo | No | No | No |
| Developer Starter | starter |
€9.00 / mo | 10 | 10,000 / mo | No | No | No |
| Developer Pro | pro |
€29.00 / mo | 50 | 50,000 / mo | Yes | Yes | No |
| Enterprise Cloud | enterprise |
€99.00 / mo | 500 | 500,000 / mo | Yes | Yes | Yes |
2. How Applications Read User Plans
Ternis ecosystem applications can inspect plan entitlements via two primary mechanisms:
Mechanism A: Standard OpenID Connect Claims
When requesting the standard OAuth scopes openid, profile, or ternis:customer, the /oauth/userinfo response automatically includes the active plan object and list of authorized entitlements:
{
"sub": "b2f6b897-4001-460d-8386-db93f1d8c1c4",
"name": "Elena Rostova",
"email": "member@ternis.org",
"plan": {
"id": "9dc721a0-128f-4318-912b-31ca78198f12",
"name": "Developer Pro",
"slug": "pro",
"tier": "pro",
"price_cents": 2900,
"currency": "EUR",
"features": {
"domains_limit": 50,
"api_rate_limit": 50000,
"custom_avatar_cdn": true,
"priority_support": true,
"dns_management": true,
"ssl_wildcards": true,
"dedicated_ip": true,
"balance_auto_topup": true,
"sso_saml": false
}
},
"entitlements": [
"domains_limit",
"api_rate_limit",
"custom_avatar_cdn",
"priority_support",
"dns_management",
"ssl_wildcards",
"dedicated_ip",
"balance_auto_topup"
]
}
Mechanism B: Dedicated Plan & Entitlement Endpoint
Ternis backend services can query the dedicated plan endpoint with an authorized Bearer token:
GET /api/v1/user/plan HTTP/1.1
Host: auth.ternis.net
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGci...
Response (200 OK):
{
"user_id": "b2f6b897-4001-460d-8386-db93f1d8c1c4",
"plan": {
"id": "9dc721a0-128f-4318-912b-31ca78198f12",
"name": "Developer Pro",
"slug": "pro",
"price_cents": 2900,
"formatted_price": "€29.00 / mo",
"currency": "EUR",
"billing_interval": "month"
},
"features": {
"domains_limit": 50,
"api_rate_limit": 50000,
"custom_avatar_cdn": true,
"priority_support": true,
"dns_management": true,
"ssl_wildcards": true,
"dedicated_ip": true,
"balance_auto_topup": true,
"sso_saml": false
},
"entitlements": [
"domains_limit",
"api_rate_limit",
"custom_avatar_cdn",
"priority_support",
"dns_management",
"ssl_wildcards",
"dedicated_ip",
"balance_auto_topup"
],
"status": "active"
}
3. Implementation Example in ternisdomains.de
Here is an example of how ternisdomains.de verifies a user's domain registration quota before creating a new DNS zone:
namespace App\Services;
use Illuminate\Support\Facades\Http;
class DomainEntitlementService
{
public function canRegisterDomain(string $accessToken, int $currentDomainCount): bool
{
$response = Http::withToken($accessToken)
->get('https://auth.ternis.net/api/v1/user/plan');
if (! $response->successful()) {
return false;
}
$features = $response->json('features', []);
$maxDomains = $features['domains_limit'] ?? 2;
return $currentDomainCount < $maxDomains;
}
}