Resource Scope Catalog API
The Resource Scope Catalog lets the owner of a registered resource define its own scopes — permissions that show up as individually-consentable items on the Rakomi consent screen, without waiting on a platform release. A resource with no registered scopes behaves exactly as it did before this API existed: nothing changes for existing integrations.
The canonical machine-readable spec is the API reference. What follows is a human guide; field-level shapes are authoritative in the OpenAPI document.
Concepts
Section titled “Concepts”- Resource — the audience your access tokens are minted for (an RFC 8707 resource indicator). You register scopes on a resource your tenant already owns. Resources are not self-service in this release — contact Rakomi to have a resource registered for your tenant.
- Scope — a capability string (e.g.
acme:calendar:read) that a client can request and a user can individually approve or refuse. sensitivity—normal(default is the more restrictiveelevatedif you omit this field) orelevated. Onlynormal-sensitivity scopes are ever shown as individually-checkable items on the consent screen. Anelevatedscope’s authorization path is deliberately out-of-band — it never appears as a checkbox next to a routine sign-in.status— every new registration starts under review and is not grantable until approved. A resource owner can list a pending scope; it is simply not yet grantable. There is no self-service approval endpoint in this release — approval is performed by Rakomi, and no API or dashboard action promotes a pending entry.
Register a scope
Section titled “Register a scope”POST /v1/resources/{resourceId}/scopesContent-Type: application/json{ "scope_name": "acme:calendar:read", "sensitivity": "normal", "display_metadata": { "kind": "locale_text", "locale_text": { "en": "Read your calendar events", "pl": "Odczyt wydarzeń w kalendarzu", "de": "Kalenderereignisse lesen", "fr": "Lire les événements du calendrier", "es": "Leer eventos del calendario" } }}Response 201: the created catalog entry.
{ "id": "…", "resource_id": "…", "scope_name": "acme:calendar:read", "status": "pending_review", "sensitivity": "normal", "requires_platform_enable": false, "display_metadata": { "kind": "locale_text", "locale_text": { "en": "…", "pl": "…", "de": "…", "fr": "…", "es": "…" } }, "created_at": "…", "updated_at": "…"}display_metadata — two ways to supply consent-screen copy
Section titled “display_metadata — two ways to supply consent-screen copy”display_metadata is a closed, two-shape field. Pick the one that matches who is authoring the copy:
{ "kind": "locale_text", "locale_text": { ... } }— you supply the copy yourself, one string per supported locale. All locales are required; a registration missing any one of them is rejected. Your text is shown in the language the end user’s screen is already in — Rakomi never translates, edits or corrects its meaning. Before storage, surrounding whitespace is trimmed, runs of whitespace are collapsed to a single space, and invisible, bidirectional and control characters are removed; a value that is empty after that removal is rejected. Each locale value is limited to 256 characters after normalisation, and the object is closed: an unrecognised locale key is rejected, never ignored.{ "kind": "i18n_key", "i18n_key": "consent.scopes.<name>" }— reserved for scopes whose copy is authored and translated by Rakomi itself. A key outside theconsent.scopes.*namespace is rejected; this shape is not a way to point at arbitrary existing text.
For nearly every integrator, locale_text is the right choice — it is the only shape that lets you
supply your own copy at all.
Errors:
400 resource_scope_catalog/reserved_namespace—scope_namecollides with a Rakomi-reserved prefix (mcp:,rakomi:,sso:,agent:, or a bare protocol scope name).400 resource_scope_catalog/malformed_scope_name— shape or length violation.400 resource_scope_catalog/i18n_key_outside_namespace— ani18n_keyoutsideconsent.scopes.*.400 validation/invalid_request— the request body failed schema validation: alocale_textvalue is missing, blank, longer than 256 characters, or an unrecognised locale key was supplied.400 resource_scope_catalog/locale_text_invalid— alocale_textvalue became empty after invisible, bidirectional and control characters were removed.400 resource_scope_catalog/resource_cap_exceeded— this resource is at its scope-count limit.400 resource_scope_catalog/tenant_aggregate_cap_exceeded— your tenant is at its aggregate limit across every resource it owns.403 resource_scope_catalog/platform_resource_immutable— you may not modify the platform’s own resource through this API.404 resource_scope_catalog/resource_not_found— unknown or not-ownedresourceId(distinct fromresource_scope_catalog/not_found, which refers to a missing catalog entry).409 resource_scope_catalog/duplicate— that scope name is already registered on this resource.
List a resource’s registered scopes
Section titled “List a resource’s registered scopes”GET /v1/resources/{resourceId}/scopesReturns the scopes registered on the resource, including ones still under review.
Response 200:
{ "data": [ /* catalog entries, same shape as the 201 above */ ], "pagination": { "next_cursor": null, "has_more": false }}The response is always an envelope, never a bare array. Honour has_more / next_cursor even though the
current implementation returns a single page. An unknown or not-owned resourceId yields a 200 with an
empty data array — not a 404.
Remove a scope
Section titled “Remove a scope”DELETE /v1/resources/{resourceId}/scopes/{id}Response 204. Removing a scope is itself the full revocation for any future token mint; it does not retroactively touch tokens already issued.
Errors:
404 resource_scope_catalog/not_found— no catalog entry with thatidon that resource.403 resource_scope_catalog/platform_resource_immutable— you may not modify the platform’s own resource through this API.
What the end user sees
Section titled “What the end user sees”Once a scope is approved and a client requests it, normal-sensitivity scopes render as individually
checkable items on the Rakomi consent screen, alongside the platform’s own permissions — clearly
labelled as defined by the resource, not by Rakomi and not necessarily by the requesting application.
The user can tick some, all, or none of them; nothing here is all-or-nothing. The full record of what
was shown and what was approved is retained for accountability regardless of how the screen
summarized it.