Consents
A consent records that a user has authorised a specific OIDC client to access their identity and the listed scopes. Created on the first successful sign-in to a client; persists until the user revokes it or the client is deleted.
These endpoints are the user-side view — they manage the calling user's own consents (a.k.a. "connected apps" in the dashboard). For the admin-side, workspace-scoped view of users who consented to your clients, see End users.
All endpoints require a bearer access token for the user themselves — see Authentication.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET |
/v1/account/connected-apps |
List the calling user's active consents |
DELETE |
/v1/account/connected-apps/:id |
Revoke a consent |
List connected apps
GET /v1/account/connected-apps
Returns the calling user's non-revoked consents, sorted by consentedAt descending.
Response
{
"data": [
{
"id": "ocs_01KPG…",
"client": {
"clientId": "oc_plugipay_portal",
"name": "Plugipay",
"logoUrl": "https://huudis.com/assets/clients/plugipay.svg",
"isFirstParty": true
},
"scopes": ["openid", "profile", "email"],
"consentedAt": "2026-03-01T09:30:00.000Z"
},
{
"id": "ocs_01KPG…",
"client": {
"clientId": "oc_meja_studio",
"name": "MejaStudio",
"logoUrl": null,
"isFirstParty": false
},
"scopes": ["openid", "profile", "email"],
"consentedAt": "2026-03-04T11:02:00.000Z"
}
]
}
The client object is included inline so the dashboard's connected-apps list can render names and logos without a second round-trip. Logo URLs are stable Huudis-hosted URLs for first-party clients; third-party clients show whatever the admin set at registration (or null).
Revoke a consent
DELETE /v1/account/connected-apps/:id
Revokes the consent. Internally:
- The consent's
revokedAtis stamped. - All refresh tokens this user holds for the same
clientIdare revoked. - Existing access tokens stay valid until they naturally expire (typically ≤1 hour).
After revoke, the next time the user opens the app, they'll be redirected back to Huudis and asked to grant consent again — the same one-time consent screen they saw originally.
204 No Content.
Errors
| Status | error.code |
When |
|---|---|---|
404 |
NOT_FOUND |
No consent with that ID. |
403 |
FORBIDDEN |
The consent belongs to a different user. |
The consent object
| Field | Type | Description |
|---|---|---|
id |
string (ocs_…) |
Stable consent ID. |
client |
object | Expanded OIDC client — clientId, name, logoUrl, isFirstParty. |
scopes |
string[] | Scopes the user granted. The client may have requested more, but only granted scopes are honored. |
consentedAt |
ISO 8601 | When the user first consented to this client. |
When listed via the admin path GET /v1/ops/end-users/:id, each consent additionally includes clientName and revokedAt for the workspace's own clients.
First-party vs. third-party consent
- First-party clients (Plugipay portal, Storlaunch dashboard, etc.) skip the consent screen on first sign-in — users are assumed to trust Forjio-operated products. A consent row is still created so the user can revoke later from connected-apps; it just isn't a separate step in the flow.
- Third-party clients (anything
isFirstParty: false) always show the one-time consent screen. The user explicitly clicks "Allow" before being redirected back with a code.
Once consent is granted (either way), subsequent sign-ins to the same client are silent until the user revokes.
Consent vs. session
Consent says "this user is willing to let this client see scopes X, Y, Z." Session says "this user has a live login at this client right now."
Revoke a consent and you cut both: the client can never silently mint a new access token, and the user must reconsent on next sign-in. Revoke a session (via /account/sessions) and you only kill the current login — consent stays granted, the next sign-in flow is silent.
Scope-level granularity
Scopes are granted as a single bundle — users can't tick "give email but not profile". If a client later asks for an additional scope (extends the bundle), the user is re-prompted on next sign-in: "MejaStudio now wants phone in addition to email, profile. Allow?"
Huudis records the consented set at each grant. The current scopes field is always the most recent grant.
Programmatic revoke at scale
The End users admin endpoint revokes all consents a user has to one workspace's clients in a single call — useful when offboarding a customer from your product. The user's consents to other workspaces' clients are untouched.
There is no API to revoke all consents for a user globally — that's a property of the user themselves and only the user (or Forjio-internal ops) can perform.
Events
| Event type | Fires on |
|---|---|
huudis.oidc.consent_granted.v1 |
A user consents to a client for the first time. |
huudis.oidc.consent_revoked.v1 |
A consent is revoked (by the user or by an admin via end-user revoke). Reserved — not yet emitted in v1. |
Next
- OIDC clients — the clients consents apply to.
- End users — the admin-side, workspace-scoped view.
- Account — the user's full self-service surface.