Verita User Service API (1.1.0)

Download OpenAPI specification:

License: Apache 2.0

User identity, authentication, and profile management for the Verita platform. Handles registration, login, profile updates, account preferences, and admin user management.

Authentication

Register a new user

Request Body schema: application/json
required
username
required
string [ 3 .. 20 ] characters ^[a-zA-Z0-9_]+$
email
required
string <email>
password
required
string >= 8 characters ^(?=.*[a-zA-Z])(?=.*\d).+$

Responses

Request samples

Content type
application/json
{
  • "username": "string",
  • "email": "user@example.com",
  • "password": "stringst"
}

Response samples

Content type
application/json
{
  • "accessToken": "string",
  • "refreshToken": "string",
  • "tokenType": "Bearer",
  • "expiresIn": 3600,
  • "user": {
    }
}

Log in and receive JWT tokens

Request Body schema: application/json
required
email
required
string <email>
password
required
string

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "password": "string"
}

Response samples

Content type
application/json
{
  • "accessToken": "string",
  • "refreshToken": "string",
  • "tokenType": "Bearer",
  • "expiresIn": 3600,
  • "user": {
    }
}

Invalidate the current session token

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "status": 0,
  • "error": "string",
  • "message": "string"
}

Exchange a refresh token for a new access token

Request Body schema: application/json
optional
refreshToken
string

Responses

Request samples

Content type
application/json
{
  • "refreshToken": "string"
}

Response samples

Content type
application/json
{
  • "accessToken": "string",
  • "refreshToken": "string",
  • "tokenType": "Bearer",
  • "expiresIn": 3600,
  • "user": {
    }
}

Request a password reset code by email

Sends a 6-digit reset code to the address if it belongs to a registered account. Always returns 204 regardless of whether the email exists, to avoid account enumeration.

Request Body schema: application/json
required
email
required
string <email>

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com"
}

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "status": 0,
  • "error": "string",
  • "message": "string"
}

Verify a password reset code and obtain a reset token

Exchanges the email + 6-digit code from the reset email for a short-lived, single-use reset token, which is then passed to /reset-password.

Request Body schema: application/json
required
email
required
string <email>
code
required
string^[0-9]{6}$

The 6-digit code from the reset email.

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "code": "string"
}

Response samples

Content type
application/json
{
  • "resetToken": "string"
}

Reset password using a token from /verify-reset-code

Request Body schema: application/json
required
token
required
string

The reset token returned by /verify-reset-code.

newPassword
required
string >= 8 characters ^(?=.*[a-zA-Z])(?=.*\d).+$

Responses

Request samples

Content type
application/json
{
  • "token": "string",
  • "newPassword": "stringst"
}

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "status": 0,
  • "error": "string",
  • "message": "string"
}

Check if a username is available

query Parameters
username
required
string

Responses

Response samples

Content type
application/json
{
  • "available": true
}

Check if an email address is available

query Parameters
email
required
string <email>

Responses

Response samples

Content type
application/json
{
  • "available": true
}

Internal

Read another user's preferences (internal)

Internal endpoint called by content-service to enforce the bookmark/like privacy toggles when serving another user's profile tabs. Gated by the shared X-Internal-Service-Token (ADR-0007), not a user JWT.

Authorizations:
bearerAuth
path Parameters
userId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "digestFrequency": "DAILY",
  • "showBookmarks": true,
  • "showLikes": true
}

List users eligible for digest generation (internal)

Internal endpoint called by content-service's scheduled digest job. Returns users whose digest preference matches the requested frequency. Gated by X-Internal-Service-Token (ADR-0007), not a user JWT.

Authorizations:
bearerAuth
query Parameters
frequency
required
string (DigestFrequency)
Enum: "DAILY" "WEEKLY" "OFF"
page
integer >= 0
Default: 0
size
integer [ 1 .. 500 ]
Default: 100

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 0,
  • "totalPages": 0,
  • "totalElements": 0,
  • "hasNext": true
}

Apply deltas to a user's profile stat counts (internal)

Internal endpoint called by content-service to keep an author's profile aggregate counts (postCount, likeReceivedCount) in sync as posts are published/unpublished and likes are added/removed. Gated by the shared X-Internal-Service-Token (ADR-0007), not a user JWT. Counts are clamped at zero; unknown user IDs are a no-op. TODO(#178): followerCount/followingCount deltas are intentionally not handled yet — the follow graph aggregate is not maintained (those two counts stay hidden in the UI).

Authorizations:
bearerAuth
path Parameters
userId
required
string <uuid>
Request Body schema: application/json
required
postCountDelta
integer
Default: 0
likeReceivedCountDelta
integer
Default: 0

Responses

Request samples

Content type
application/json
{
  • "postCountDelta": 0,
  • "likeReceivedCountDelta": 0
}

Users

Get the current user's full profile

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "displayName": "string",
  • "email": "user@example.com",
  • "avatarUrl": "http://example.com",
  • "bio": "string",
  • "website": "http://example.com",
  • "organisation": "string",
  • "expertiseAreas": [
    ],
  • "role": "USER",
  • "isBanned": true,
  • "postCount": 0,
  • "followerCount": 0,
  • "followingCount": 0,
  • "likeReceivedCount": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update the current user's profile

Authorizations:
bearerAuth
Request Body schema: application/json
required
displayName
string
bio
string or null <= 250 characters
website
string or null <uri>
organisation
string or null
expertiseAreas
Array of strings or null

Responses

Request samples

Content type
application/json
{
  • "displayName": "string",
  • "bio": "string",
  • "website": "http://example.com",
  • "organisation": "string",
  • "expertiseAreas": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "displayName": "string",
  • "email": "user@example.com",
  • "avatarUrl": "http://example.com",
  • "bio": "string",
  • "website": "http://example.com",
  • "organisation": "string",
  • "expertiseAreas": [
    ],
  • "role": "USER",
  • "isBanned": true,
  • "postCount": 0,
  • "followerCount": 0,
  • "followingCount": 0,
  • "likeReceivedCount": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete the current user's account

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "status": 0,
  • "error": "string",
  • "message": "string"
}

Replace the current user's avatar

Authorizations:
bearerAuth
Request Body schema: multipart/form-data
required
avatar
required
string <binary>

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "displayName": "string",
  • "email": "user@example.com",
  • "avatarUrl": "http://example.com",
  • "bio": "string",
  • "website": "http://example.com",
  • "organisation": "string",
  • "expertiseAreas": [
    ],
  • "role": "USER",
  • "isBanned": true,
  • "postCount": 0,
  • "followerCount": 0,
  • "followingCount": 0,
  • "likeReceivedCount": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Remove the current user's avatar

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "displayName": "string",
  • "email": "user@example.com",
  • "avatarUrl": "http://example.com",
  • "bio": "string",
  • "website": "http://example.com",
  • "organisation": "string",
  • "expertiseAreas": [
    ],
  • "role": "USER",
  • "isBanned": true,
  • "postCount": 0,
  • "followerCount": 0,
  • "followingCount": 0,
  • "likeReceivedCount": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get the current user's preferences

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "digestFrequency": "DAILY",
  • "showBookmarks": true,
  • "showLikes": true
}

Update the current user's preferences

Authorizations:
bearerAuth
Request Body schema: application/json
required
digestFrequency
required
string (DigestFrequency)
Enum: "DAILY" "WEEKLY" "OFF"
showBookmarks
required
boolean

Whether other users can see this user's bookmarks.

showLikes
required
boolean

Whether other users can see this user's liked posts.

Responses

Request samples

Content type
application/json
{
  • "digestFrequency": "DAILY",
  • "showBookmarks": true,
  • "showLikes": true
}

Response samples

Content type
application/json
{
  • "digestFrequency": "DAILY",
  • "showBookmarks": true,
  • "showLikes": true
}

Get a user's public profile by username

path Parameters
username
required
string

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "displayName": "string",
  • "email": "user@example.com",
  • "avatarUrl": "http://example.com",
  • "bio": "string",
  • "website": "http://example.com",
  • "organisation": "string",
  • "expertiseAreas": [
    ],
  • "role": "USER",
  • "isBanned": true,
  • "postCount": 0,
  • "followerCount": 0,
  • "followingCount": 0,
  • "likeReceivedCount": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a user's public profile

path Parameters
userId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "displayName": "string",
  • "email": "user@example.com",
  • "avatarUrl": "http://example.com",
  • "bio": "string",
  • "website": "http://example.com",
  • "organisation": "string",
  • "expertiseAreas": [
    ],
  • "role": "USER",
  • "isBanned": true,
  • "postCount": 0,
  • "followerCount": 0,
  • "followingCount": 0,
  • "likeReceivedCount": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Admin

List all users with optional search filter (admin only)

Authorizations:
bearerAuth
query Parameters
q
string

Filter by username or display name (case-insensitive).

page
integer >= 0
Default: 0
size
integer [ 1 .. 100 ]
Default: 20

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 0,
  • "totalPages": 0,
  • "totalElements": 0,
  • "hasNext": true
}

Change a user's role (admin only)

Authorizations:
bearerAuth
path Parameters
userId
required
string <uuid>
Request Body schema: application/json
required
role
required
string (UserRole)
Enum: "USER" "VERIFIED" "ADMIN"

Responses

Request samples

Content type
application/json
{
  • "role": "USER"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "displayName": "string",
  • "email": "user@example.com",
  • "avatarUrl": "http://example.com",
  • "bio": "string",
  • "website": "http://example.com",
  • "organisation": "string",
  • "expertiseAreas": [
    ],
  • "role": "USER",
  • "isBanned": true,
  • "postCount": 0,
  • "followerCount": 0,
  • "followingCount": 0,
  • "likeReceivedCount": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Ban or unban a user (admin only)

Authorizations:
bearerAuth
path Parameters
userId
required
string <uuid>
Request Body schema: application/json
required
banned
required
boolean

Responses

Request samples

Content type
application/json
{
  • "banned": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "displayName": "string",
  • "email": "user@example.com",
  • "avatarUrl": "http://example.com",
  • "bio": "string",
  • "website": "http://example.com",
  • "organisation": "string",
  • "expertiseAreas": [
    ],
  • "role": "USER",
  • "isBanned": true,
  • "postCount": 0,
  • "followerCount": 0,
  • "followingCount": 0,
  • "likeReceivedCount": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}