curl "https://api.telzino.com/v1/features" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
curl "https://api.telzino.com/v1/features?organization_id=ORG_UUID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
curl "https://api.telzino.com/v1/features?reseller_id=RESELLER_UUID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
const response = await fetch(
`https://api.telzino.com/v1/features?organization_id=${orgId}`,
{ headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN' } }
);
const { data } = await response.json();
// Hide anything this organization may not use.
const available = new Set(
data.filter(f => f.state === 'available').map(f => f.key)
);
if (available.has('knowledge_base')) showKnowledgeBaseTab();
import requests
response = requests.get(
'https://api.telzino.com/v1/features',
params={'organization_id': org_id},
headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
)
features = response.json()['data']
available = {f['key'] for f in features if f['state'] == 'available'}
{
"feature_administration_enabled": true,
"scope": {
"level": "organization",
"id": "3f2b1c9e-8a4d-4c17-9b3e-1d5a7c8e2f04"
},
"data": [
{
"key": "chat",
"name": "Chat",
"description": "Chat functionality for the organization.",
"category": "CAPABILITY",
"state": "available",
"locked_scope": null,
"decided_by": "feature_administration"
},
{
"key": "custom_voices",
"name": "Custom Voices",
"description": "Allow the organization to clone and assign custom (cloned) voices for its agents.",
"category": "CAPABILITY",
"state": "locked",
"locked_scope": "here",
"decided_by": "feature_administration"
},
{
"key": "integration.slack",
"name": "Slack",
"description": "Availability of the slack integration.",
"category": "INTEGRATION",
"state": "locked",
"locked_scope": "inherited",
"decided_by": "legacy_column"
},
{
"key": "knowledge_base",
"name": "Knowledge Base (RAG)",
"description": "Retrieval-augmented knowledge base.",
"category": "CAPABILITY",
"state": "locked",
"locked_scope": "inherited",
"decided_by": "feature_administration"
},
{
"key": "template.outbound",
"name": "Outbound Calling Agent",
"description": "Allow new agents that PLACE calls to be created.",
"category": "TEMPLATE",
"state": "available",
"locked_scope": null,
"decided_by": "feature_administration"
}
]
}
{
"error": "invalid_request",
"error_description": "Provide at most one of organization_id or reseller_id."
}
{
"error": "unauthorized",
"error_description": "User payload not found"
}
{
"error": "not_found",
"error_description": "Resource not found or access denied"
}
{
"error": "service_unavailable",
"error_description": "Could not resolve feature availability for this scope. Please retry."
}
Features
List Feature Availability
Returns every platform feature with whether it is available or locked for an account, reseller or organization
GET
/
v1
/
features
curl "https://api.telzino.com/v1/features" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
curl "https://api.telzino.com/v1/features?organization_id=ORG_UUID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
curl "https://api.telzino.com/v1/features?reseller_id=RESELLER_UUID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
const response = await fetch(
`https://api.telzino.com/v1/features?organization_id=${orgId}`,
{ headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN' } }
);
const { data } = await response.json();
// Hide anything this organization may not use.
const available = new Set(
data.filter(f => f.state === 'available').map(f => f.key)
);
if (available.has('knowledge_base')) showKnowledgeBaseTab();
import requests
response = requests.get(
'https://api.telzino.com/v1/features',
params={'organization_id': org_id},
headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
)
features = response.json()['data']
available = {f['key'] for f in features if f['state'] == 'available'}
{
"feature_administration_enabled": true,
"scope": {
"level": "organization",
"id": "3f2b1c9e-8a4d-4c17-9b3e-1d5a7c8e2f04"
},
"data": [
{
"key": "chat",
"name": "Chat",
"description": "Chat functionality for the organization.",
"category": "CAPABILITY",
"state": "available",
"locked_scope": null,
"decided_by": "feature_administration"
},
{
"key": "custom_voices",
"name": "Custom Voices",
"description": "Allow the organization to clone and assign custom (cloned) voices for its agents.",
"category": "CAPABILITY",
"state": "locked",
"locked_scope": "here",
"decided_by": "feature_administration"
},
{
"key": "integration.slack",
"name": "Slack",
"description": "Availability of the slack integration.",
"category": "INTEGRATION",
"state": "locked",
"locked_scope": "inherited",
"decided_by": "legacy_column"
},
{
"key": "knowledge_base",
"name": "Knowledge Base (RAG)",
"description": "Retrieval-augmented knowledge base.",
"category": "CAPABILITY",
"state": "locked",
"locked_scope": "inherited",
"decided_by": "feature_administration"
},
{
"key": "template.outbound",
"name": "Outbound Calling Agent",
"description": "Allow new agents that PLACE calls to be created.",
"category": "TEMPLATE",
"state": "available",
"locked_scope": null,
"decided_by": "feature_administration"
}
]
}
{
"error": "invalid_request",
"error_description": "Provide at most one of organization_id or reseller_id."
}
{
"error": "unauthorized",
"error_description": "User payload not found"
}
{
"error": "not_found",
"error_description": "Resource not found or access denied"
}
{
"error": "service_unavailable",
"error_description": "Could not resolve feature availability for this scope. Please retry."
}
Use this endpoint to find out which capabilities an account, reseller or organization may
actually use, so your integration can hide a feature instead of letting a user reach a
write that fails with
Use
Each entry in
Integration features are the exception to the regime split: the account’s integration
allow-list still applies even while Feature Administration is on, so an
403 forbidden.
Availability is governed by Feature Administration,
where a Partner or Reseller locks a feature for the levels beneath it. A lock is inherited:
one placed on an account applies to every reseller and organization under it, and one
placed on a reseller applies to all of its organizations.
Choosing a scope
Pass at most one scope parameter. Supplying both, or supplying one with an empty value, is rejected with400.
| Parameter | Reports availability for | Locks reflected |
|---|---|---|
| (none) | The authenticated account | Locks placed on the account itself |
reseller_id | That reseller | The reseller’s own locks, plus the account’s |
organization_id | That organization | The organization’s own locks, plus its reseller’s and its account’s |
organization_id when deciding what to show for a specific customer — it is the only
scope that reflects the full inheritance chain. The account-level view is deliberately
coarser: it reports only the locks that reach everything beneath, because an access token
identifies an account rather than one organization.
Query Parameters
string
Optional. Report availability for this organization, applying its account, reseller and
organization-level locks. The organization must belong to the authenticated account, or
the request is rejected with
404. Mutually exclusive with reseller_id.string
Optional. Report availability for this reseller, applying its own locks and those it
inherits from the account. The reseller must belong to the authenticated account, or the
request is rejected with
404. Mutually exclusive with organization_id.curl "https://api.telzino.com/v1/features" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
curl "https://api.telzino.com/v1/features?organization_id=ORG_UUID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
curl "https://api.telzino.com/v1/features?reseller_id=RESELLER_UUID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
const response = await fetch(
`https://api.telzino.com/v1/features?organization_id=${orgId}`,
{ headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN' } }
);
const { data } = await response.json();
// Hide anything this organization may not use.
const available = new Set(
data.filter(f => f.state === 'available').map(f => f.key)
);
if (available.has('knowledge_base')) showKnowledgeBaseTab();
import requests
response = requests.get(
'https://api.telzino.com/v1/features',
params={'organization_id': org_id},
headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
)
features = response.json()['data']
available = {f['key'] for f in features if f['state'] == 'available'}
{
"feature_administration_enabled": true,
"scope": {
"level": "organization",
"id": "3f2b1c9e-8a4d-4c17-9b3e-1d5a7c8e2f04"
},
"data": [
{
"key": "chat",
"name": "Chat",
"description": "Chat functionality for the organization.",
"category": "CAPABILITY",
"state": "available",
"locked_scope": null,
"decided_by": "feature_administration"
},
{
"key": "custom_voices",
"name": "Custom Voices",
"description": "Allow the organization to clone and assign custom (cloned) voices for its agents.",
"category": "CAPABILITY",
"state": "locked",
"locked_scope": "here",
"decided_by": "feature_administration"
},
{
"key": "integration.slack",
"name": "Slack",
"description": "Availability of the slack integration.",
"category": "INTEGRATION",
"state": "locked",
"locked_scope": "inherited",
"decided_by": "legacy_column"
},
{
"key": "knowledge_base",
"name": "Knowledge Base (RAG)",
"description": "Retrieval-augmented knowledge base.",
"category": "CAPABILITY",
"state": "locked",
"locked_scope": "inherited",
"decided_by": "feature_administration"
},
{
"key": "template.outbound",
"name": "Outbound Calling Agent",
"description": "Allow new agents that PLACE calls to be created.",
"category": "TEMPLATE",
"state": "available",
"locked_scope": null,
"decided_by": "feature_administration"
}
]
}
{
"error": "invalid_request",
"error_description": "Provide at most one of organization_id or reseller_id."
}
{
"error": "unauthorized",
"error_description": "User payload not found"
}
{
"error": "not_found",
"error_description": "Resource not found or access denied"
}
{
"error": "service_unavailable",
"error_description": "Could not resolve feature availability for this scope. Please retry."
}
Response Fields
| Field | Type | Description |
|---|---|---|
feature_administration_enabled | boolean | Whether the feature matrix governs availability platform-wide. See Governing regime below |
scope.level | string | The level answered for: account, reseller or organization |
scope.id | string | Identifier of the entity answered for |
data | array | One entry per feature in the registry, sorted by key |
data:
| Field | Type | Description |
|---|---|---|
key | string | Stable feature identifier, e.g. knowledge_base or integration.slack. Build your checks on this, not on name |
name | string | Display name |
description | string | What the feature does, and what locking it changes |
category | string | CAPABILITY, TEMPLATE, LLM_MODEL, TTS, INTEGRATION, OPERATIONAL or COMMERCIAL. Grouping only — it never affects access |
state | string | available or locked |
locked_scope | string | null | here when the lock sits on the entity you asked about, inherited when it was placed further up the chain. null when the feature is available |
decided_by | string | What established the answer — see below |
decided_by
| Value | Meaning |
|---|---|
feature_administration | The feature matrix decided, applying locks down the account → reseller → organization chain |
legacy_column | A per-account or per-organization setting decided, which is what governs while Feature Administration is switched off |
default_available | Nothing withholds this feature at this scope |
integration.*
entry can report legacy_column in either regime — as the example response above shows
for integration.slack.
Governing regime
feature_administration_enabled reports which of two regimes is in force platform-wide:
the Feature Administration matrix, or the older per-account and per-organization settings
that preceded it. The same feature can be governed differently under each, so the field is
included for callers that compare responses over time or raise a support ticket about one.
It does not change how you use the response: state is always the answer that applies
right now, under whichever regime is active.
Two things to build around
LLM models. An
llm.* feature reported as available means the model may be assigned
to the organization’s agents; locked means a Partner or Reseller has withheld it. The
always-available floor model (gpt-4.1) has no llm.* row because it can never be locked.
The same answer, shaped for building a picker, is available from
GET /v1/llm-models.Opt-in features report permission, not state. For
secure_access, phi_redaction and
use_reseller_smtp, available means the organization is permitted to switch the feature
on — not that it currently is. Locking these prevents a new opt-in; it never turns the
feature off for an organization already using it.Errors
| Status | Meaning |
|---|---|
400 | Both organization_id and reseller_id were supplied, or a scope parameter was supplied with an empty value |
401 | Missing or invalid access token |
404 | The organization_id or reseller_id does not exist, or does not belong to the authenticated account |
503 | Availability could not be resolved. This is transient — retry. Availability is never returned partially resolved, so a 503 is returned rather than a response that under-reports locks |
