API Reference
users
5 endpoints
- /api/v1/users
/api/v1/users/{username}Get User
Get a user by username.
Readable by any caller holding user:read. UserResponse carries only
what a user publishes about themselves; their own account record is at
/users/me.
Path parameters
| username* | string |
Query parameters
| default_backend | string | default: "primary" |
Responses
| Field | Type | Description |
|---|---|---|
| uuid* | string | |
| username* | string | |
| first_name* | string | |
| last_name | string | null | |
| account_type* | enum | |
| avatar_image_file_uuid | string | null | |
| avatar_image_file_url | string | null | |
| created_at* | string (date-time) | |
| updated_at | string (date-time) | null |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
Example request
curl -X GET "https://api.davi.social/api/v1/users/{username}" \
-H "Authorization: Bearer <token>"/api/v1/users/{username}/profileGet User Profile
Get a user's profile page.
Public by design — this is what a shared profile link resolves to, so any
caller holding profile:read may read it and no ownership check applies. A
locked profile is suppressed here even though its owner can still see it.
A name held by an organization is not found here, deliberately. Users and organizations share one namespace, so a well-formed name that nobody can be shown is a real answer rather than a gap — organizations have addresses but no page behind them yet. This is the route that changes when they get one; until then the lookup is by account and an organization's name reaches no account, which is the 404.
The published read of a profile; composing one is Davi's own editor and is not part of this API.
Carries profile_page_uuid, which is what POST /contacts takes to save
the person behind the page.
Path parameters
| username* | string |
Query parameters
| default_backend | string | default: "primary" |
Responses
| Field | Type | Description | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| imageUrl | string | default: "" | ||||||||||||||||||||||||
| name | string | default: "" | ||||||||||||||||||||||||
| first_name | string | default: "" | ||||||||||||||||||||||||
| last_name | string | default: "" | ||||||||||||||||||||||||
| shortDescription | string | default: "" | ||||||||||||||||||||||||
| longDescription | string | default: "" | ||||||||||||||||||||||||
| callToAction | CallToAction | null | |||||||||||||||||||||||||
object · CallToAction
| ||||||||||||||||||||||||||
| currentRole | CurrentRole | null | |||||||||||||||||||||||||
object · CurrentRole
| ||||||||||||||||||||||||||
| customBackground | CustomBackground | null | |||||||||||||||||||||||||
object · CustomBackground
| ||||||||||||||||||||||||||
| avatarFrame | string | null | |||||||||||||||||||||||||
| socialLinks | ProfileLink[] | |||||||||||||||||||||||||
array items · ProfileLink
| ||||||||||||||||||||||||||
| links | ProfileLink[] | |||||||||||||||||||||||||
array items · ProfileLink
| ||||||||||||||||||||||||||
| longDescriptionContent | object[] | |||||||||||||||||||||||||
| stickers | object[] | |||||||||||||||||||||||||
| profile_page_uuid | string | null | UUID of the profile page (for use in save-contact flows) | ||||||||||||||||||||||||
| is_locked | boolean | True when the profile was issued by an organization and the owner's membership in that org is inactive. Derived at read time. default: false | ||||||||||||||||||||||||
| primary_card_uid | string | null | Identifier of the owner's primary card — the `uid` in /c/{uid} URLs. Lets the profile page advertise the card+json discovery link (/c/{uid}/json). NULL for bearer profiles and owners with no primary card. | ||||||||||||||||||||||||
| updated_at | string (date-time) | null | When the profile was last written. Moves on any edit, including one that replaces an image while leaving its url the same — which is what makes it usable for cache keys that a url alone cannot invalidate. | ||||||||||||||||||||||||
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
Example request
curl -X GET "https://api.davi.social/api/v1/users/{username}/profile" \
-H "Authorization: Bearer <token>"/api/v1/users/meGet Current User
Get the currently authenticated user.
Query parameters
| default_backend | string | default: "primary" |
Responses
| Field | Type | Description | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| uuid* | string | User UUID | ||||||||||||||||||||||||||||||||||||
| username | string | null | Username (set during onboarding) | ||||||||||||||||||||||||||||||||||||
| first_name | string | null | First name (set during onboarding) | ||||||||||||||||||||||||||||||||||||
| last_name | string | null | Last name | ||||||||||||||||||||||||||||||||||||
| phone_number | string | null | Phone number | ||||||||||||||||||||||||||||||||||||
| avatar_image_file_url | string | null | Avatar image URL | ||||||||||||||||||||||||||||||||||||
| created_at* | string (date-time) | Account creation timestamp | ||||||||||||||||||||||||||||||||||||
| iam_user_id | string | null | IAM user ID (without 'iam:' prefix) | ||||||||||||||||||||||||||||||||||||
| string | null | Email address from auth provider | |||||||||||||||||||||||||||||||||||||
| email_verified | boolean | null | Whether email is verified | ||||||||||||||||||||||||||||||||||||
| scopes | string[] | Granted permission scopes | ||||||||||||||||||||||||||||||||||||
| wallet_address | string | null | Primary wallet address | ||||||||||||||||||||||||||||||||||||
| primary_card_identifier | string | null | Primary card identifier (e.g., NFC serial number) | ||||||||||||||||||||||||||||||||||||
| profile_complete* | boolean | Whether user has completed their profile setup | ||||||||||||||||||||||||||||||||||||
| onboarding_required | boolean | Whether user needs to complete onboarding default: false | ||||||||||||||||||||||||||||||||||||
| subscription* | CurrentSubscriptionResponse | The user's subscription tier and entitlements | ||||||||||||||||||||||||||||||||||||
object · CurrentSubscriptionResponse
| ||||||||||||||||||||||||||||||||||||||
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
Example request
curl -X GET "https://api.davi.social/api/v1/users/me" \
-H "Authorization: Bearer <token>"/api/v1/users/me/subscriptionGet My Subscription
Get the current user's subscription tier and entitlements.
Query parameters
| default_backend | string | default: "primary" |
Responses
| Field | Type | Description | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tier* | string | The user's Davi subscription tier. One of a fixed set Davi declares — not an organization's membership tier, which is addressed by uuid or slug and varies per organization. | ||||||||||||
| display_name* | string | |||||||||||||
| status* | string | |||||||||||||
| started_at* | string (date-time) | |||||||||||||
| valid_until | string (date-time) | null | |||||||||||||
| entitlements* | PlatformEntitlements | |||||||||||||
object · PlatformEntitlements
| ||||||||||||||
| Field | Type | Description | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| detail | ValidationError[] | |||||||||||||
array items · ValidationError
| ||||||||||||||
Example request
curl -X GET "https://api.davi.social/api/v1/users/me/subscription" \
-H "Authorization: Bearer <token>"/api/v1/users/searchSearch Users
Search users by username, first name, last name, or email.
Finds a person to act on within an organization — someone to invite, or a
recipient to issue something to. exclude_staff chooses between those two
readings: invites want the existing team left out, while issuing to a
recipient wants them in, since the team (the caller included) are the
likely targets. It filters on the team, not on who holds a membership in
one of the organization's tiers.
organization_uuid is required: it is what makes this endpoint
authorizable. org:staff:manage is an ownership-deferred scope, so it is
only enforced once a resource is named — without an organization to check
against, the scope declaration is inert and any authenticated token could
search every user by email, name or username. The role check is run
against the caller's current role rather than the one embedded in an
org-scoped token, matching the other staff-management endpoints.
Query parameters
| q* | string | Search query min length 2 · max length 100 |
| organization_uuid* | string | Organization the search is being run for. Scopes the caller's authorization. |
| limit | integer | Max results default: 10 · ≥ 1 · ≤ 50 |
| exclude_staff | boolean | Omit users already on `organization_uuid`'s team. Defaults to true, which suits picking someone to invite; pass false to search everyone, including the caller. default: true |
| default_backend | string | default: "primary" |
Responses
| Field | Type | Description | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| total_items* | integer | Total number of items available | |||||||||||||||||||||
| total_pages* | integer | Total number of pages available | |||||||||||||||||||||
| current_page* | integer | Current page number | |||||||||||||||||||||
| items* | UserSearchSuggestion[] | List of items on the current page | |||||||||||||||||||||
array items · UserSearchSuggestion
| |||||||||||||||||||||||
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
| Field | Type | Description |
|---|---|---|
| errors* | object | Map of field names to error messages. Use '_root' for form-level errors. |
| message* | string | Human-readable error summary |
| code | string | null | Machine-readable error code |
| details | object | null | What the refusal is about, where it is something you can act on — the amount and currency owed on a `402`, the entitlement a tier did not grant on a `403`. Values are typed as the error carries them, so read a figure from here rather than from `errors`, whose values are always the copy a form shows against a field. |
Example request
curl -X GET "https://api.davi.social/api/v1/users/search" \
-H "Authorization: Bearer <token>"