Skip to content

OAuth Scopes

Civitai OAuth scopes are bitwise flags. To request multiple scopes, OR them together and pass the decimal integer as the scope parameter on the /authorize URL.

text
scope = UserRead | AIServicesRead | AIServicesWrite | BuzzRead
      = 1 | 16384 | 32768 | 65536
      = 114689

Scope reference

BitValueScopeWhat it grants
01UserReadRead profile & settings
12UserWriteUpdate profile & settings
24ModelsReadBrowse & download models
38ModelsWriteUpload & edit models
416ModelsDeleteDelete models
532MediaReadView images, videos & posts
664MediaWriteUpload media & create posts
7128MediaDeleteDelete media & posts
8256ArticlesReadRead articles
9512ArticlesWriteCreate & edit articles
101 024ArticlesDeleteDelete articles
112 048BountiesReadView bounties
124 096BountiesWriteCreate & manage bounties (buzz spend)
138 192BountiesDeleteDelete bounties
1416 384AIServicesReadView generation & training history
1532 768AIServicesWriteGenerate, train & scan (buzz spend)
1665 536BuzzReadView buzz balance & history
17131 072CollectionsReadView collections
18262 144CollectionsWriteManage collections
19524 288SocialWriteFollow, react, comment & review
201 048 576SocialTipReserved — see below
212 097 152NotificationsReadRead notifications
224 194 304NotificationsWriteManage notification preferences
238 388 608VaultReadView vault
2416 777 216VaultWriteManage vault
33 554 431FullAll scopes

Buzz-spend scopes

Two scopes carry an implicit buzz-spend authorization — granting them lets your app draw from the user's buzz balance:

  • AIServicesWrite — every generation/training/scan request the app makes is billed to the consenting user. This is the only scope subject to the per-app buzz limit cap users can set at consent.
  • BountiesWrite — bounty creation costs buzz at post time. Spend is gated by the user's overall balance only; per-app caps don't apply.

(SocialTip would be a third — see the reserved note below.)

Pair either with BuzzRead if you want to surface the user's remaining balance in your UI before a spend.

SocialTip is currently reserved

The SocialTip bit is defined in the scope enum but every server endpoint that requires it (tipping, donation goals, event tipping) is gated by blockApiKeys: true, which denies all API-key and OAuth callers regardless of scope. Granting SocialTip today is a no-op. The bit stays reserved (and locked at 1<<20) so we don't reshuffle the bitmask when tipping is unblocked for OAuth in the future.

Presets

The app-registration UI exposes four convenience presets. You can also target them from the scope URL parameter directly:

PresetDecimalScopes
Read Only10 701 093All *Read scopes
Creator11 492 205Read Only + Models / Media / Articles / Bounties / Collections Write + SocialWrite
AI Services114 688AIServicesRead | AIServicesWrite | BuzzRead
Full Access33 554 431Every defined scope

Use a preset's number on /authorize and the consent screen will still show the user every flag underneath — there's no shortcut around per-scope consent.

Asking for less than you registered

The allowedScopes you set during registration is a ceiling, not a floor. You can ask for any subset of those bits on any individual /authorize call — useful when one user only needs read access but another wants to spend buzz, and you want a single registered app for both.

If you request a scope bit your app isn't registered for, the user is shown the consent screen anyway but Civitai will trim the token to your allowed scopes when it issues it. Read the scope value back from the token-endpoint response — it's authoritative.

Checking scopes at the API boundary

Pass the access token as Authorization: Bearer <token> on any Civitai endpoint. The endpoint returns 403 insufficient_scope if the token's scope is missing the bit it requires:

json
{
  "error": "insufficient_scope",
  "error_description": "Token does not have UserRead scope"
}

That's the signal to re-run the flow with a wider scope (or, more often, to display "this action needs additional permissions" in your UI).

Civitai Developer Documentation