Packages and usage
Every account has its own package for each of Dinio’s two services — a line:
| Line | Service | What its package limits |
|---|---|---|
auth |
DNS hosting | Zones, free-domain leases, health checks, how far back zone statistics go. |
filter |
DNS filtering | Client identities, sinkhole lists and rules, how far back client statistics go. |
The two are independent: you can have a package in one line, both, or neither. Without a
package in a line, nothing can be added in it — every create there is refused with
403 NO_SUBSCRIPTION. Choose one with Choose a package.
A limit only stops you from adding. Nothing you already have is ever removed, suspended or stops answering because of a package.
Limits
Section titled “Limits”Each limit has a key. A number is the limit; null means unlimited.
| Key | Line | Limit |
|---|---|---|
auth.zones.max |
auth |
Zones you own. Leases of free domains don’t count here. |
auth.free_subdomains.max |
auth |
Free-domain leases you own. |
auth.healthchecks.max |
auth |
Health checks in the zones you own. |
auth.healthchecks.min_interval_s |
auth |
Shortest health-check interval allowed, in seconds (at least 30). |
auth.logs.retention_days |
auth |
How many days back zone statistics reach; 0 = none. |
filter.clients.max |
filter |
Client identities you own. |
filter.sinkhole_lists.max |
filter |
Sinkhole lists you own. |
filter.sinkhole_rules.max |
filter |
Rules in all of your lists together. |
filter.sinkhole_rules_per_list.max |
filter |
Rules in any one of your lists. |
filter.logs.retention_hours |
filter |
How many hours back client statistics reach. |
filter.queries.monthly |
filter |
Lookups by your clients per month. |
A package may leave out the three filter.sinkhole_* keys; then that limit doesn’t apply.
New keys can appear — treat an unknown key as information to show, not an error.
Whose package counts: the owner’s, not the caller’s. Everything in a zone counts against the zone’s Owner — a health check an Administrator adds, too. Identities and lists count against the user who owns them.
Where the limits are checked:
| Request | Keys |
|---|---|
POST /zones |
auth.zones.max; for a lease auth.free_subdomains.max |
POST /health-checks |
auth.healthchecks.max, auth.healthchecks.min_interval_s |
PATCH /health-checks/:record_id with a new interval |
auth.healthchecks.min_interval_s |
| Zone import with health checks | auth.healthchecks.max, auth.healthchecks.min_interval_s |
POST /client-identities |
filter.clients.max |
POST /sinkhole-lists |
filter.sinkhole_lists.max |
POST /sinkhole-roles, list import and URL sources |
filter.sinkhole_rules.max, filter.sinkhole_rules_per_list.max |
/stats/zones/… |
auth.logs.retention_days |
/stats/clients/… |
filter.logs.retention_hours |
List packages
Section titled “List packages”/api/v1/plansThe price list: every listed package, in both lines. Needs no API key, so a pricing page can use it before sign-up. The response may be cached for five minutes.
curl https://api-dinio.bitelex.com/api/v1/plans{ "success": true, "data": [ { "id": "auth-pro@v1", "line": "auth", "code": "pro", "version": 1, "name": "Pro", "self_service": true, "prices": [ { "period": "monthly", "currency": "EUR", "amount_cents": 900, "tax_inclusive": false }, { "period": "yearly", "currency": "EUR", "amount_cents": 9000, "tax_inclusive": false } ], "entitlements": { "auth.zones.max": 20, "auth.free_subdomains.max": 3, "auth.healthchecks.max": 50, "auth.healthchecks.min_interval_s": 30, "auth.logs.retention_days": 30 } } ]}(The values are an example; read the real ones from the API.)
| Field | |
|---|---|
id |
The exact version: <line>-<code>@v<version>. |
code |
What you choose by, e.g. pro. |
self_service |
false: not for self-service — show “contact us” instead of a choose button. |
prices |
One per billing period, in cents, without VAT (tax_inclusive: false). Empty = free. |
entitlements |
The package’s limits; null = unlimited. |
Packages come in their display order, smallest first within a line.
Your packages
Section titled “Your packages”/api/v1/account/subscriptionsYour package per line — none, one or two items. Needs a personal key; a zone key has no
account and gets 403.
interface Subscription { uuid: string; user_id: string; line: 'auth' | 'filter'; plan_id: string; // the exact version, e.g. "auth-pro@v1" status: 'trial' | 'active' | 'past_due' | 'canceled'; period: 'monthly' | 'yearly' | null; // null for a free package trial_ends_at?: number; current_period_end?: number; created_at: number; updated_at: number;}You keep the version you chose: when a package gets a new version, your limits don’t change until you choose again.
Choose a package
Section titled “Choose a package”/api/v1/account/subscriptions/:linePuts you on a package in :line (auth or filter), in its current version. Returns the
new Subscription.
| Field | Type | |
|---|---|---|
code |
string | The package’s code from GET /plans. |
period |
string | monthly or yearly. Required for a paid package, refused for a free one. |
curl -X PUT -H "Authorization: Bearer $DINIO_API_KEY" -H "Content-Type: application/json" \ -d '{"code":"pro","period":"yearly"}' \ https://api-dinio.bitelex.com/api/v1/account/subscriptions/authA free package starts active, a paid one trial. Choosing the package you already have
with another period keeps your version.
409 PLAN_NOT_AVAILABLE— no such package, or it is not for self-service.409 PLAN_DOWNGRADE_BLOCKED— you use more than the package allows. Nothing changes;details.violationslists every limit you are over, so you can show what to remove first.
{ "success": false, "error": { "code": "PLAN_DOWNGRADE_BLOCKED", "message": "the package doesn't fit what is in use: auth.zones.max, auth.healthchecks.min_interval_s", "details": { "line": "auth", "violations": [ { "key": "auth.zones.max", "limit": 3, "used": 7 }, { "key": "auth.healthchecks.min_interval_s", "limit": 60, "used": 30, "count": 4 } ] } }}For a count, used is how many you have. For auth.healthchecks.min_interval_s, used is
your fastest interval and count how many checks run faster than limit. How far back
statistics reach never blocks a change.
Your usage
Section titled “Your usage”/api/v1/account/usagePer line: your package, its effective limits, and how much of each you use.
curl -H "Authorization: Bearer $DINIO_API_KEY" https://api-dinio.bitelex.com/api/v1/account/usage{ "success": true, "data": [ { "line": "auth", "subscription": { "plan_id": "auth-pro@v1", "status": "active", "period": "yearly", "…": "…" }, "plan": { "id": "auth-pro@v1", "code": "pro", "version": 1, "name": "Pro" }, "entitlements": { "auth.zones.max": { "limit": 20, "used": 17, "level": "warn" }, "auth.logs.retention_days": { "limit": 30 } } }, { "line": "filter", "subscription": null, "plan": null, "entitlements": null } ]}limit can differ from the price list when your account has an individual arrangement.
Counted limits also have used and level:
level |
|
|---|---|
ok |
Below 80 %. |
warn |
80 % or more. |
limit |
At the limit: the next add is refused. |
over |
Above it — possible after a package change by support. Everything keeps working; only adding is refused. |
A line without a package has plan and entitlements set to null.
Limit errors
Section titled “Limit errors”Over a limit, the request is refused with 403 PLAN_LIMIT and nothing is written. details
names the limit:
{ "success": false, "error": { "code": "PLAN_LIMIT", "message": "plan limit reached: auth.zones.max (20 of 20)", "details": { "key": "auth.zones.max", "limit": 20, "used": 20 } }}For a count, details has used; for a setting — a health-check interval, how far back
statistics reach — it has requested instead. To offer an upgrade, take the next package of
that line in GET /plans whose value for details.key is higher (or
null); for auth.healthchecks.min_interval_s, lower.
Without a package in the line, the error is 403 NO_SUBSCRIPTION with details.line
(auth or filter).
Warnings
Section titled “Warnings”A create that succeeds but brings a limit to 80 % or more carries warnings next to data:
{ "success": true, "data": { "uuid": "…", "name": "example.com", "…": "…" }, "warnings": [ { "code": "PLAN_USAGE", "message": "auth.zones.max: 17 of 20 used", "details": { "key": "auth.zones.max", "limit": 20, "used": 17, "level": "warn" } } ]}level is warn or limit. Show it to the user, with the offer of a bigger package.
Responses without warnings leave the field out.