Skip to content

Scopes

18 permissions, resource-dot-action. Coarse on purpose: you should be able to pick the right ones without reading a manual.

A credential carries a set of scopes chosen when it is minted. An endpoint that needs a scope the credential lacks returns 403 insufficient_scope and names the missing scope, so you never have to guess which one you forgot. Each endpoint's reference page shows the scope it needs.

Every scope#

ScopeWhat it lets the holder doNotes
account.readSee your plan and remaining creditsRead-only preset
projects.readRead your projects and their edit documentsRead-only preset
projects.writeCreate, edit and delete projects
media.readList the media you have uploadedRead-only preset
media.writeUpload media and import it from a URL
render.readCheck render progress and fetch preview framesRead-only preset
render.writeStart renders, using your monthly export allowanceCan spend
ai.transcribeTranscribe audio, spending your creditsCan spend
ai.speechGenerate speech, spending your creditsCan spend
ai.imageGenerate images and stickers, spending your creditsCan spend
ai.videoGenerate video, spending your creditsCan spend
ai.agentRun the AI editing agent, spending your creditsCan spend
ai.analyzeAnalyse footage for scenes, faces and speechCan spend
stock.readSearch the stock media libraryRead-only preset
webhooks.manageManage webhook endpoints for this appNever inherited
plugins.invokeCall third-party plugins you have installed, sending them the arguments of each callNever inherited
telegram.users.readSee the people using your Telegram bot and what they spentNever inherited
telegram.users.writeAllow, block and set daily limits for the people using your Telegram botNever inherited

Can spend means the scope can cost the owner real money (credits or export allowance). Read-only preset is the default offered when you mint a key. Never inherited means keys minted before the scope existed do not carry it.

Presets#

The console offers named bundles instead of 18 checkboxes, least privileged first:

  • Read only: Look at projects, media and render status. Cannot change or spend anything. (account.read, projects.read, media.read, render.read, stock.read)
  • Build & render: Everything above, plus creating and editing projects, uploading media and starting renders. (account.read, projects.read, media.read, render.read, stock.read, projects.write, media.write, render.write)
  • Build & render + AI: Everything above, plus transcription, generation and the editing agent. Spends credits. (account.read, projects.read, media.read, render.read, stock.read, projects.write, media.write, render.write, ai.transcribe, ai.speech, ai.image, ai.video, ai.agent, ai.analyze)

Older keys#

A key minted before scopes existed stores no scope list, and that means the legacy full grant: it behaves exactly as it always did. That grant never includes the scopes that did not exist then and that send data somewhere or reach real people: webhooks.manage, plugins.invoke, telegram.users.read, telegram.users.write. To use those, mint a new key.

Choosing them#

Mint time is the one moment least privilege is cheap. Afterwards it means rotating a credential that is already in production, which is why the picker is the first thing on the key form.

A useful set for a render pipeline (read projects, write them, render, poll):

Text
account.read projects.read projects.write render.read render.write

Note what is absent: no media.write (this pipeline points clips at URLs it already has) and no ai.* at all. If that key leaks, the worst case is somebody using your export allowance, not your credits.

The app ceiling#

Each app carries a ceiling: the most any of its keys or OAuth tokens may ever hold. New apps get the full vocabulary, so the ceiling is invisible until it is lowered, which happens for apps not verified for the expensive generation scopes. A key requesting more than its app's ceiling gets the intersection, and the ceiling is applied again on every request. Check what a credential actually ended up with:

Shell
curl https://api.vidmoat.com/v1/me \
  -H "Authorization: Bearer $VIDMOAT_KEY"

Scopes that will never exist#

Posting to Vidmoat Social: a public feed written to by third parties is a moderation liability. Anything admin. And key management: keys never mint keys, which is enforced at the route rather than by the absence of a scope, so it cannot be undone by adding one.

webhooks.manage is reserved for a future public webhook API. Today, webhook destinations are managed in the console; see webhooks.