Creates one idempotent, 30-second host/co-host microphone command for an admitted participant in this open meeting. This checks roster authorization, not live media presence. Mute is executed by the requesting host's connected TopoloChat meeting client using provider-enforced remote mute. The target must be present in that client's joined participant list. Keep that client connected; an API/CLI request alone does not claim provider success. The client reports applied only after provider acknowledgement. request_unmute asks the target's connected TopoloChat client for an explicit choice. Only that participant can enable their audio. No host or API caller can unmute another person.
Action app_topolo_chat.meetings.audio_control · POST /api/meetings/{meetingId}/audio-controls. Intended audience: public.
Catalog flags: readOnly=False, requiresConfirmation=True, destructive=False, agentAccess=confirm. HTTP method and empty permission fields do not override the actual effects or authority below.
Authority and prerequisites
- Declared authorization mode=runtime, requiredPermission=app_topolo_chat.meetings:write; actual source identity/resource checks below remain mandatory.
- Discover the actual identifier and current intended state within existing authority. Examples grant no access and are not executable probes.
Identifiers
- Obtain meetingId and participantId from the same authorized roster. Generate and retain one requestId for the confirmed target/operation. Discover actual connected media presence in the host client separately.
Input
meetingId: type="string"; minLength=1. Required.participantId: type="string"; minLength=1. Required.operation: type="string"; enum=["mute", "request_unmute"]. Required.requestId: type="string"; pattern="^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$". Required.
The exact native input/output schemas are retained in the hidden paired layer for this version. Top-level undeclared fields are rejected. Nested open records and semantic prerequisites still need source checks.
Effects and important boundaries
- Creates one idempotent, 30-second host/co-host microphone command for an admitted participant in this open meeting. This checks roster authorization, not live media presence.
- Mute is executed by the requesting host's connected TopoloChat meeting client using provider-enforced remote mute. The target must be present in that client's joined participant list. Keep that client connected; an API/CLI request alone does not claim provider success. The client reports applied only after provider acknowledgement.
- request_unmute asks the target's connected TopoloChat client for an explicit choice. Only that participant can enable their audio. No host or API caller can unmute another person.
- Member runtime authorization verifies Auth identity, canonical workspace access and this meeting roster; service principals are refused. The nominal meetings:read/write permission is not a substitute for that runtime check.
- Guest routes are catalog-public transports protected by a secret session token hash. The admission must have been consumed and belong to a joined guest in an open meeting; it confers no workspace access or host privilege. Keep the token secret.
- Open means live or scheduled. Joined participants, and invited non-guests, pass the audio roster predicate; waiting/removed guests or ended meetings do not. Roster admission is not provider media presence.
- Control reads return at most 100 newest commands issued by or addressed to this actor. Pending commands are presented as expired after 30 seconds without a read-side status write.
- No server action in this set enables a microphone or captures media. applied is an executing client acknowledgment, not an independently verified media receipt.
- Only the host/co-host may target another admitted participant. Self-moderation is refused. Keep the requesting host client connected for provider-enforced mute; the API alone creates a command.
- requestId is a UUID and is unique per meeting/requesting participant. Reusing it with the same target/operation returns the existing command; changing either is request_conflict. Request creation returns 202 even when an existing command is returned.
- request_unmute asks the target client for a choice. It never remotely enables another person’s microphone.
Refusals, failures and recovery
- 404
not_found: Use a participant from this meeting's published read. Never substitute an identifier from another workspace. - 409
participant_not_active: The caller and target must be admitted members or admitted guests in an open meeting. Waiting, removed and ended meetings are refused. Roster admission is not live media presence. - 403
moderation_forbidden: Only a host or co-host of this meeting may request remote microphone controls. - 403
result_forbidden: Mute results belong to the requesting host. Unmute decisions belong only to the targeted participant; hosts cannot consent for them. - 409
request_expired: Requests expire after 30 seconds. Read the current state before explicitly creating another request. - 409
request_conflict: Retry only the identical operation and target for a requestId. - 409
result_conflict: Read the already completed result. It cannot be overwritten. - 400
self_moderation: Use your own microphone control, not a host moderation request. - 503
database_unavailable: Retry after the meeting data service is available.
A mute never enables audio. The participant may choose to unmute themselves. Pending requests expire after 30 seconds; never turn on another person's microphone or silently retry an expired request.
Verification
- Call app_topolo_chat.meetings.audio_controls and match the command id and status. Pending is not a muted microphone or consent to unmute.
- Retain actual request/receipt identifiers securely, preserve UNKNOWN effects and reconcile before any retry.
Run a reviewed request
Discover the current action and its resource requirements before running it. Save the approved input as reviewed-input.json; replace synthetic examples with values obtained through the intended authorized workflow. If discovery requires a resource binding, provide its published type and resolved ID separately on both plan and call. Stop if validation fails or the plan is not executable.
topolo actions get app_topolo_chat.meetings.audio_control --json
topolo actions validate app_topolo_chat.meetings.audio_control --data @reviewed-input.json --json
topolo actions plan app_topolo_chat.meetings.audio_control --data @reviewed-input.json --confirm --json
topolo actions call app_topolo_chat.meetings.audio_control --data @reviewed-input.json --confirm --json
--confirm must represent approval of the actual request and its effects. The examples do not supply that approval.
Worked examples
All examples are synthetic and unrun. They cannot authorize access, create human consent, prove media/provider success or establish financial/customer state. Placeholder tokens are unusable. No contact, payment, notification, provisioning or business read was executed.
Command accepted, media not proved
SOURCE-AUTHORED SYNTHETIC, UNRUN. Output assessment: PASS_STRUCTURAL_ONLY_UNRUN.
Input:
{
"meetingId": "meeting_example",
"participantId": "participant_example",
"operation": "mute",
"requestId": "00000000-0000-4000-8000-000000000001"
}
Output illustration or error excerpt:
{
"id": "audio_example",
"meetingId": "meeting_example",
"participantId": "participant_example",
"requestedBy": "host_example",
"operation": "mute",
"status": "pending",
"createdAt": "2026-10-20T00:00:00.000Z",
"expiresAt": "2026-10-20T00:00:30.000Z"
}
202 pending command only. Keep media/provider outcome separate.
Refusal or failure
SOURCE-AUTHORED SYNTHETIC, UNRUN. Source-derived error-code excerpt only; messages/envelope can differ by layer or locale. Not a captured response. Output assessment: ERROR_EXCERPT_NOT_SUCCESS_SCHEMA.
Input:
{
"meetingId": "meeting_example",
"participantId": "participant_example",
"operation": "mute",
"requestId": "00000000-0000-4000-8000-000000000001"
}
Output illustration or error excerpt:
{
"error": "moderation_forbidden"
}
A regular participant cannot issue host moderation commands.
Invalid input: stop at schema validation
SOURCE-AUTHORED SYNTHETIC, UNRUN. null is a no-response sentinel, not returned JSON null. Output assessment: NOT_APPLICABLE_NO_REQUEST.
Input:
{
"participantId": "participant_example",
"operation": "mute",
"requestId": "00000000-0000-4000-8000-000000000001"
}
Output illustration or error excerpt:
null
Intentionally invalid input; no request was issued and no HTTP response/status is asserted.
Boundary: idempotency conflict
SOURCE-AUTHORED SYNTHETIC, UNRUN. Error-code excerpt only. Output assessment: ERROR_EXCERPT_NOT_SUCCESS_SCHEMA.
Input:
{
"meetingId": "meeting_example",
"participantId": "participant_example",
"operation": "mute",
"requestId": "00000000-0000-4000-8000-000000000001"
}
Output illustration or error excerpt:
{
"error": "request_conflict",
"code": "request_conflict"
}
409 if this requestId already names another target or operation. Preserve the original request.
Source and verification limits
Reviewed against b5577fe8b0441cd07630b44866cb8b059a8bf047 at apps/api/src/handlers/meeting-audio-routes.ts and the published action schema on 2026-10-20. Examples are synthetic and unrun. Source review and schema validation do not prove current deployed behavior, provider completion or business delivery. Response excerpts are labelled where incomplete.
Change log
- 2026-10-20: Prepared the action guide with paired agent schemas, permission and effect boundaries, worked examples, verification and recovery instructions. Independently checked the pinned source; publication and runtime verification remain separate.