Users

Manage user profiles, preferences, settings, and account details in the Expense API

Retrieve and manage the authenticated user's profile, preferences, settings, and account details — the starting point for any Expense API integration.

Overview

The Expense API user endpoints operate through the /me context, meaning all operations apply to the currently authenticated user. After authenticating with a user-scoped token (via the authorization_code grant), the /me endpoint is your first call — it returns the user's identity, preferences, and capabilities.

The user context is essential because most Expense API endpoints (expenses, reports, approvals) are scoped to the authenticated user's permissions and organization memberships.

Key concepts

ConceptDescription
PersonA unique individual in the Findity system. A person can have multiple users (employees) across multiple organizations
CapabilitiesThe meta.capabilities object indicates system-wide abilities like impersonation and admin access
ImpersonationActing as another user — used by admin tools and support integrations
Extra recipientsAdditional email addresses that can receive expense-related notifications
CountersPer-organization badge counts for expenses, approvals, notifications, and rejections

Get current user

Retrieve the authenticated user's profile. This is typically the first call after obtaining a user-scoped access token.

GET /v1/expense/me

Query parameters

ParameterTypeDescription
includestringOptional properties: preferences, extraRecipients, meta.capabilities, temporaryApprovers

Example request

curl -X GET "https://stage-api.findity.com/api/v1/expense/me?include=preferences,meta.capabilities" \
  -H "Authorization: Bearer {access_token}"

Example response

{
  "id": "370e10197a2740dea1f39d21bc9e4a8c",
  "email": "[email protected]",
  "firstName": "Emma",
  "lastName": "Expense",
  "mobilePhone": "+4670123456789",
  "defaultCurrency": "USD",
  "language": "en_US",
  "IBAN": "US2138890474392778363181",
  "BIC": "ABCDEF123",
  "formattingRegion": "sv_SE",
  "address": {
    "id": "2ee7643987df40b38537b32ccda585d9",
    "street1": "132, My Street",
    "postalCode": "12401",
    "city": "New York",
    "countryCode": "US"
  },
  "meta": {
    "capabilities": {
      "canImpersonate": false,
      "canViewAdmin": false
    }
  }
}

Update current user

Update the authenticated user's profile information.

PUT /v1/expense/me

Example request

curl -X PUT "https://stage-api.findity.com/api/v1/expense/me" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Emma",
    "lastName": "Expense",
    "defaultCurrency": "SEK",
    "language": "sv_SE",
    "IBAN": "SE3550000000054910000003",
    "BIC": "ESSESESS",
    "address": {
      "street1": "Sveavägen 10",
      "postalCode": "111 57",
      "city": "Stockholm",
      "countryCode": "SE"
    },
    "formattingRegion": "sv_SE"
  }'

Updatable fields

FieldTypeDescription
firstNamestringUser's first name
lastNamestringUser's last name
defaultCurrencystringPreferred currency code (e.g., SEK, USD, EUR)
languagestringLanguage/locale code (e.g., en_US, sv_SE)
bankAccountNumberstringBank account number
IBANstringInternational bank account number
BICstringBank identifier code
formattingRegionstringRegion used for formatting dates and numbers
addressobjectAddress with street1, postalCode, city, countryCode

Action parameter

The PUT /me endpoint also supports an action query parameter instead of a request body:

ActionDescription
enableSupportAccessGrants Findity support temporary access to the user's account
disableSupportAccessRevokes support access
PUT /v1/expense/me?action=enableSupportAccess

User settings (fields format)

User settings can also be fetched and updated using the fields format — the same dynamic form system used for expenses. This is useful when building a full settings UI.

Fetch settings

GET /v1/expense/me/settings/fields

Returns a fields structure with grouped settings:

Field groupContents
settings.personalGroupName, email, phone, address, password, receipt email
settings.bankGroupBank account, IBAN, BIC
settings.experienceGroupCurrency, language, formatting region
settings.appGroupApp theme, camera defaults, prompt preferences
settings.notificationGroupCard transaction notifications, email preferences
temporaryApprovalGroupTemporary approver assignments

Update settings

PUT /v1/expense/me?format=fields

Send the full fields structure back with updated values. Fields with requiresUpdate: true trigger server-side recalculation — follow the same update loop pattern described in the Fields system guide.

Counters

Retrieve badge counts across all organizations the user belongs to. Use this to show notification badges in your UI.

GET /v1/expense/me/counters

Example response

{
  "meta": { "count": 2, "total": 2 },
  "data": [
    {
      "organizationId": "8ab28c4e6f858814016f8a9bd6b20054",
      "expenses": 19,
      "approvals": 0,
      "rejections": 0,
      "notifications": 3,
      "transactions": 0,
      "inbox": 0
    },
    {
      "organizationId": "8ab28c4f6fd37d39016fd6fee0470003",
      "expenses": 10,
      "approvals": 11,
      "rejections": 0,
      "notifications": 0,
      "transactions": 0,
      "inbox": 0
    }
  ]
}

Counter fields

FieldDescription
expensesNumber of new/draft expenses
approvalsNumber of items pending approval (if user is an approver)
rejectionsNumber of recently rejected expenses
notificationsNumber of unread notifications
transactionsNumber of card transactions
inboxNumber of expenses created via email or card auto-creation

Profile image

Manage the user's profile picture.

OperationMethodEndpoint
Get profile imageGET/v1/expense/me/profileimage
Upload profile imagePUT/v1/expense/me/profileimage
Delete profile imageDELETE/v1/expense/me/profileimage

When uploading, set the Content-Type header to the image format (e.g., image/jpeg, image/png). The request body should be the binary image data.

Email and phone management

Email and phone number changes require a two-step verification process to prevent unauthorized changes.

Change email

  1. Request a verification code:
curl -X POST "https://stage-api.findity.com/api/v1/expense/me/email?action=change" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]" }'
  1. Verify with the code:
curl -X POST "https://stage-api.findity.com/api/v1/expense/me/email?action=verify" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "verificationCode": "123456" }'

Change phone number

Follows the same two-step pattern using /v1/expense/me/phone:

  1. POST /me/phone?action=change with { "phoneNumber": "+46701234567" }
  2. POST /me/phone?action=verify with { "verificationCode": "123456" }

To remove a phone number entirely: DELETE /v1/expense/me/phone

📱

Phone numbers must be in international format with a plus-code prefix (e.g., +46701234567).

Change password

POST /v1/expense/me/password

Example request

{
  "oldPassword": "currentPassword123!",
  "newPassword": "newSecurePassword456!"
}

A successful response returns new access and refresh tokens, since the password change invalidates the previous session:

{
  "expiresIn": 3600,
  "accessToken": "eae3a3a225368f247b419e...",
  "refreshToken": "59fec24de9f49918f50a31..."
}
🔒

Passwords must be at least eight characters long with at least one number, one uppercase letter, and one lowercase letter.

🔄

After a successful password change, immediately replace your stored access and refresh tokens with the new ones returned in the response. The old tokens are invalidated and will no longer work.

Extra recipients

Extra recipients are additional email addresses that receive expense-related notifications alongside the user's primary email.

OperationMethodEndpoint
List extra recipientsGET/v1/expense/me/extrarecipients
Add extra recipientPOST/v1/expense/me/extrarecipients?action=add
Verify extra recipientPOST/v1/expense/me/extrarecipients?action=verify
Delete extra recipientDELETE/v1/expense/me/extrarecipients/{extraRecipientId}

Each extra recipient has a status of CONFIRMED or NOT_CONFIRMED — they must complete email verification before receiving notifications.

Impersonation

Users with impersonation privileges can search for and act as other users. This is used for admin tools, support scenarios, and delegated expense management.

Search impersonation targets

GET /v1/expense/impersonation/users/search
ParameterTypeDescription
searchTextstringFree text search across users
maxintegerMax records to return
offsetintegerPagination offset
sortstringSort with order, e.g., firstName:desc,lastName:asc

Example response

{
  "meta": { "total": 2, "count": 2 },
  "data": [
    {
      "personId": "a61fa8a24d9d49f7b75d1874257e044a",
      "firstName": "Emma",
      "lastName": "Expense",
      "email": "[email protected]",
      "impersonatorType": "PERSON",
      "profilePictureUrl": "https://expense.findity.com/api/v1/expense/profileimage/a61fa..."
    }
  ]
}

The impersonatorType indicates the scope of impersonation:

TypeDescription
PERSONCan act as the person across all their organizations
EMPLOYEECan act as the person within a specific organization only
⚠️

Impersonation requires special permissions. Check meta.capabilities.canImpersonate on the /me response before showing impersonation features in your UI.

Integration best practices

Fetch user context immediately after authentication

Call GET /me?include=meta.capabilities as the first request after obtaining a user-scoped token. This confirms the token is valid, identifies the user, and reveals system-level capabilities like impersonation access.

Use counters for badge notifications

Poll GET /me/counters periodically to update badge counts in your UI. This single endpoint returns counts across all organizations, so you don't need to query each organization separately.

Cache user profile data

User profile data (name, currency, language) changes rarely. Fetch it once at login and store it in your session. Only refresh when the user explicitly edits their profile.

Respect the fields format for settings

When building a settings screen, use the fields format (GET /me/settings/fields) rather than constructing the UI manually. This ensures your settings UI stays in sync with any new settings Findity adds, and handles the requiresUpdate loop for interdependent settings.

Handle verification flows gracefully

Email and phone changes are asynchronous — the user receives a verification code externally. Design your UI to handle the two-step flow: show an input for the verification code after requesting the change, and handle error codes like EXPIRED_VERIFICATION_CODE by prompting the user to request a new code.

Error handling

Common errors when working with user endpoints:

Status codeError codeDescription
400NO_KNOWN_JSON_PROPERTIESFailed to parse the JSON body. Check your request payload.
400INVALID_JSON_BODYNo known or only read-only properties received. Verify you're sending updatable fields.
400EMAIL_IS_BLANKEmail address is required but was empty.
400INVALID_EMAILThe provided email address is not valid.
400EMAIL_ALREADY_IN_USEAn account already exists with this email address.
400INVALID_PHONE_NUMBERThe phone number format is invalid. Use international format with plus-code.
400PHONE_NUMBER_ALREADY_USEDThe phone number is already associated with another account.
400INVALID_VERIFICATION_CODEThe verification code is incorrect.
400EXPIRED_VERIFICATION_CODEThe verification code has expired. Request a new one.
400PASSWORD_VALIDATION_ERRORPassword doesn't meet requirements (8+ chars, 1 number, 1 uppercase, 1 lowercase).
400INCORRECT_CURRENT_PASSWORDThe current password provided doesn't match.
404ORGANIZATION_NOT_FOUNDPerson does not belong to any organization (for counters endpoint).

Next steps