Managed-Mode Resources
A namespace in managed resource-authority mode authors its subscriber resources — lines, devices, trunks, ring groups, voicemail boxes, and namespace linkages — through per-entity REST endpoints instead of the YAML document. It exists for the shapes where a config document stops scaling: tens of thousands of lines, or a provisioning system that churns individual subscribers all day and wants one API call per change, not a version-and-apply cycle around each.
Most managed-mode users drive these endpoints from their own integration
code, so this page sketches the model and the basic flows rather than
walking every field — the request bodies mirror the YAML resource schemas
one-to-one (see the Namespace Resources
reference for field meanings), and the API appendix has the full
per-endpoint detail. Conventions as usual: $VSS, $TOKEN, $NSID;
vsscli commands live under vsscli resource … (aliases res,
resources).
The model
Section titled “The model”Authority mode is chosen at namespace creation and never changes
(POST /v1/ns?authority=managed — see
namespace administration).
In a managed namespace the split is:
Authored via /resources API |
Still authored in YAML (config versions + apply) |
|---|---|
| Lines, devices, trunks, ring groups, voicemail boxes, ns-linkages | Everything those resources reference: line/trunk profiles, translation / voicemail / caller-ID / screening contexts, routes, recordings, feature codes, configuration: keys |
A managed namespace’s YAML rejects the resource sections outright — the two authorities never overlap. The config document keeps its whole lifecycle (versions, validate, apply); it just carries policy, not subscribers.
The write semantics are deliberately different from document mode:
- Effective immediately. A resource write hits call processing as soon as it lands — no version, no apply, and therefore no rollback and no staged/latest state. Your integration’s audit trail is the change history.
- Validated per entity, not per document. Each write is checked against the running config body (does the profile/context exist?) and the current resource rows (does the referenced device/box exist?), and refused with a 400 naming the missing reference. What is not checked is the reverse direction: deletes don’t cascade and don’t look for dangling references — removing a device still listed by a line simply leaves the line pointing at nothing. Write ordering is your integration’s job: create referenced things first, delete referencing things first.
- Runtime surfaces are unchanged. Voicemail state, line features, and
device credentials work exactly as the rest of this section describes —
rt vm,rt line, andpeer passworddon’t care which authority mode defined the resource.
Permissions
Section titled “Permissions”The /resources tree has its own action pair so definition authoring can
be delegated separately from config authoring:
| Action | Held by |
|---|---|
resource:read |
partition-admin, namespace-admin, operator, editor, provisioner, viewer, system-auditor |
resource:write |
Same, minus viewer / system-auditor |
provisioner is the intended role for subscriber-churn integrations:
resource definitions, device credentials, and voicemail admin, with no
config authoring or namespace lifecycle.
Endpoint shape
Section titled “Endpoint shape”Every resource family follows the same pattern under
/v1/ns/{nsid}/resources/:
| Family | List | Get one | Create/replace | Merge-patch | Delete | Bulk |
|---|---|---|---|---|---|---|
lines/{line} |
✓ | ✓ | PUT | PATCH | ✓ | ✓ |
devices/{device} |
✓ | ✓ | PUT | — | ✓ | ✓ |
trunks/{trunk} |
✓ | ✓ | PUT | — | ✓ | — |
ring-groups/{group} |
✓ | ✓ | PUT | — | ✓ | — |
vm-boxes/{context}/{box} |
✓ | ✓ | PUT | — | ✓ | ✓ |
linkages/{peer} |
✓ | ✓ | PUT | PATCH | ✓ | ✓ |
PUT is create-or-replace with the full body; PATCH (lines, linkages) is a
tri-state merge-patch — absent key untouched, present key applied, blank
clears. Bulk (POST …/bulk with a JSON array) is best-effort: each
item is validated and written independently, and the response carries a
per-item success/error list in order — one bad row doesn’t abort the rest.
Bulk exists for the families that churn at subscriber scale (lines,
devices, voicemail boxes, linkages).
Calling any of these on a document-mode namespace answers 409 — the same request body belongs in the YAML there.
The basic flow: one subscriber, end to end
Section titled “The basic flow: one subscriber, end to end”Assume the running config body already defines a standard line profile
and voicemail context (that part is YAML, applied once). Provisioning a
subscriber is then four calls, ordered so every reference exists before
something names it:
# 1. Mailbox definitioncurl -s -X PUT "$VSS/v1/ns/$NSID/resources/vm-boxes/standard/1001" \ -H "Authorization: Bearer $TOKEN" -d '{}'
# 2. Device (creates its SIP peer — auth before routing)curl -s -X PUT "$VSS/v1/ns/$NSID/resources/devices/alice-desk" \ -H "Authorization: Bearer $TOKEN" -d '{"line":"1001"}'
# 3. The line, tying it togethercurl -s -X PUT "$VSS/v1/ns/$NSID/resources/lines/1001" \ -H "Authorization: Bearer $TOKEN" -d '{ "line_profile": "standard", "voicemail": "1001", "caller_id": "+13055551234", "devices": ["alice-desk"] }'
# 4. Mint the device credential (see Device Credentials)curl -s -X POST "$VSS/v1/peer/alice-desk@pbx.acme.example/setpass" \ -H "Authorization: Bearer $TOKEN"echo '{}' | vsscli resource vm-boxes put standard 1001 --stdinecho '{"line":"1001"}' | vsscli resource devices put alice-desk --stdin
vsscli resource lines put 1001 --stdin <<'EOF'line_profile: standardvoicemail: "1001"caller_id: "+13055551234"devices: [alice-desk]EOF
vsscli peer password generate alice-desk@pbx.acme.example --showWrite commands take their body from -f FILE or --stdin, as JSON or
YAML interchangeably.
The subscriber is live the moment step 3 returns — the phone registers as soon as step 4’s credential is configured on it. Inspect and adjust the same way:
curl -s "$VSS/v1/ns/$NSID/resources/lines" -H "Authorization: Bearer $TOKEN"curl -s "$VSS/v1/ns/$NSID/resources/lines/1001" -H "Authorization: Bearer $TOKEN"
# Merge-patch: change one field, everything else untouchedcurl -s -X PATCH "$VSS/v1/ns/$NSID/resources/lines/1001" \ -H "Authorization: Bearer $TOKEN" -d '{"caller_id":"+13055559999"}'vsscli resource lines listvsscli resource lines show 1001echo '{"caller_id":"+13055559999"}' | vsscli resource lines patch 1001 --stdinOffboarding — reverse order
Section titled “Offboarding — reverse order”Deletion is the mirror of provisioning: detach references before deleting what they point at. Each delete cleans up its own runtime state — a line delete purges the line’s feature rows (DND, forwards, speed dials, same as when a line leaves a document-mode config), a device delete drops its SIP auth before its routing, and a vm-box delete purges messages and greetings. What deletes never do is cascade across resources: removing a line does not remove its devices or mailbox.
# The line (stops calls, purges feature state), then its devices# (drops SIP auth first, then routing), then the mailboxcurl -s -X DELETE "$VSS/v1/ns/$NSID/resources/lines/1001" -H "Authorization: Bearer $TOKEN"curl -s -X DELETE "$VSS/v1/ns/$NSID/resources/devices/alice-desk" -H "Authorization: Bearer $TOKEN"curl -s -X DELETE "$VSS/v1/ns/$NSID/resources/vm-boxes/standard/1001" -H "Authorization: Bearer $TOKEN"vsscli resource lines delete 1001vsscli resource devices delete alice-deskvsscli resource vm-boxes delete standard 1001Conversely, a vm-box definition PUT never touches runtime state — you can re-PUT a box (or rebind a distribution list’s members) without clobbering its PIN, messages, or recorded greetings.
Trunks, ring groups, linkages
Section titled “Trunks, ring groups, linkages”Same verbs, same semantics; the bodies mirror their YAML counterparts (trunks, ring groups, linkages). Two trunk-specific conflict rules are enforced at write time, both 409s: a source IP claimed by another namespace on the same edge proxy, and a source IP claimed by another trunk in the same namespace (inbound classification is by exact source IP, so an IP must have exactly one owner).
A linkage’s inheritance block is part of the managed body like any other field — the profile, granted aliases, concurrency cap, and the permitted edge-IP / SIP-realm envelope a managed parent imposes on a child are all writable via PUT and merge-patchable via PATCH, and constrain the child’s config from its next apply.
Troubleshooting
Section titled “Troubleshooting”| Response | Meaning | Do |
|---|---|---|
409 “resources are document-authored” |
The namespace is in document mode | Author this in the YAML instead; authority is immutable |
400 naming a missing reference |
The profile/context/box/device you referenced doesn’t exist | Create it first (YAML apply for config-body refs, a /resources PUT for row refs) |
409 device peer conflict |
The device name (at this realm) is claimed by another namespace | Pick another device name |
409 trunk IP conflict |
Source IP owned by another namespace on this edge proxy, or by another trunk here | Resolve ownership; one IP, one owner |
404 on GET/PATCH/DELETE |
No such resource row — the problem type names the family (line-not-found, device-not-found, …) |
Managed resources exist only once PUT — there is no “in config but not applied” state |
| Bulk returns mixed results | Best-effort semantics | Inspect the per-item results array; retry the failures |