session.permissions tells you which permissions your miniapp declared in its miniapp.json. has(type) is a synchronous boolean, getAll() returns the full record, and onUpdate / onPermissionError let you react to changes and to typed permission errors.
src/background/index.ts
has() and getAll() report what you declared in the manifest, not whether the user granted the OS prompt. has("microphone") === true only means your manifest lists MICROPHONE. If the user denied the OS permission, that subscription stays silent and receives nothing. The way to know a permission was actually granted is whether events arrive (and onPermissionError for the typed declaration error). See the manifest for how to declare permissions.

Methods

onUpdate does not fire with the current value when you subscribe. Call getAll() yourself if you want the starting state. The record changes on the connect handshake (CONNECT_ACK), or when the phone pushes an update (for example a dev miniapp re-scanned with an updated manifest). The handler receives the full record, not a list.

Permission types

has() and the keys of PermissionRecord use these canonical names. Each maps from the UPPER_CASE manifest type values. location is true if you declared either LOCATION or BACKGROUND_LOCATION, and notifications is true if you declared either notification permission. PermissionRecord is Record<PermissionType, boolean>, so getAll() always returns all five keys with a boolean each.

Permission errors

If you call a capability whose permission you never declared, the phone runtime rejects with PERMISSION_NOT_DECLARED. onPermissionError is a filtered view of the session error event that surfaces only those.
This error means the permission is missing from your manifest, which is a fix you make in miniapp.json. It is separate from the user denying the OS prompt, which produces no error and instead leaves the relevant stream silent.
Checking OS-grant state directly (isGranted) and prompting for a permission (request) are not implemented yet. They are planned to land on this same module alongside has / getAll, without renaming today’s methods. For now, treat the arrival of events as the signal that a permission was granted.