Users
Users
User authentication and profile operations. Users can access multiple entities and manage their account settings.
The User object
Attributes
Set up required two-factor authentication
/users/two-factor/setupUse the ten-minute two_factor_setup challenge from primary login. This challenge only permits enrollment; it cannot access authenticated routes or replace an enabled authenticator.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.setupRequiredTwoFactor({
token: "token"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"secret": "secret",
"otpauth_uri": "https://example.com",
"qr_code": "qr-code"
}Confirm required two-factor enrollment
/users/two-factor/enableConfirm setup and atomically exchange the one-use enrollment challenge for a full interactive session. Returns ten recovery codes once. Clients must present them for saving before continuing. Revokes other user sessions.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.enableRequiredTwoFactor({
token: "token",
code: "code"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"recovery_codes": [
"recovery-codes"
],
"session": {
"id": "id",
"user_id": "user-id",
"ttl": 31536000,
"scope": "scope",
"entity_id": "entity-id",
"created_at": "2025-01-15T10:30:00.000Z",
"impersonator_user_id": "impersonator-user-id",
"updated_at": "2025-01-15T10:30:00.000Z",
"user": {
"id": "id",
"email": "user@example.com",
"name": "name",
"email_verified": true,
"account_id": "account-id",
"settings": "settings",
"metadata": "metadata",
"is_accountant": false,
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-15T10:30:00.000Z"
},
"redirect_origin": "redirect-origin"
}
}Set up an authenticator app
/users/me/two-factor/setupRequires an interactive session and reauthentication. Setup expires after ten minutes. Protection remains disabled until a valid code is confirmed. Scan the QR code with Google Authenticator or another TOTP app. An enabled authenticator cannot be replaced through setup.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.setupTwoFactor({
password: "password"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"secret": "secret",
"otpauth_uri": "https://example.com",
"qr_code": "qr-code"
}Enable two-factor authentication
/users/me/two-factor/enableConfirm the pending setup with a six-digit code. Revokes other sessions and returns ten recovery codes once. Save these codes securely; only hashes are retained.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.enableTwoFactor({
code: "code"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"recovery_codes": [
"recovery-codes"
]
}Disable two-factor authentication
/users/me/two-factor/disableRequires an interactive session, reauthentication and an unused authenticator or recovery code. Revokes other sessions and removes the stored secret and recovery codes.
Body parameters
Six-digit authenticator code or a single-use recovery code.
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.disableTwoFactor({
password: "password",
code: "code"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"enabled": true
}Complete two-factor login
/users/two-factor/verifyExchange the five-minute session_2fa_ challenge for an interactive session using an unused authenticator code or recovery code. Pending challenges cannot access other authenticated endpoints. Five failed attempts lock verification for fifteen minutes across all challenges for this user.
Body parameters
Six-digit authenticator code or a single-use recovery code.
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.verifyTwoFactor({
token: "token",
code: "code"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"id": "id",
"user_id": "user-id",
"ttl": 31536000,
"scope": "scope",
"entity_id": "entity-id",
"created_at": "2025-01-15T10:30:00.000Z",
"impersonator_user_id": "impersonator-user-id",
"updated_at": "2025-01-15T10:30:00.000Z",
"user": {
"id": "id",
"email": "user@example.com",
"name": "name",
"email_verified": true,
"account_id": "account-id",
"settings": "settings",
"metadata": "metadata",
"is_accountant": false,
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-15T10:30:00.000Z"
},
"redirect_origin": "redirect-origin"
}Login user
/users/loginAuthenticate a user with email and password. Returns a token and resolved user profile for the current brand or white-label origin. For users with two-factor authentication enabled, the token has scope two_factor_pending, an id beginning session_2fa_, and a five-minute TTL. It cannot access authenticated endpoints; exchange it at POST /users/two-factor/verify before treating the user as signed in. Users without an authenticator whose direct account or entity membership requires one receive a ten-minute two_factor_setup challenge with an id starting session_2fa_setup_. Complete POST /users/two-factor/setup and /users/two-factor/enable before sign-in can continue. Policies never inherit through ownership or related scopes.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.login({
email: "user@example.com",
password: "password",
shopify_return_url: "/shopify/apollo#token=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"id": "id",
"user_id": "user-id",
"ttl": 31536000,
"scope": "scope",
"entity_id": "entity-id",
"created_at": "2025-01-15T10:30:00.000Z",
"impersonator_user_id": "impersonator-user-id",
"updated_at": "2025-01-15T10:30:00.000Z",
"user": {
"id": "id",
"email": "user@example.com",
"name": "name",
"email_verified": true,
"account_id": "account-id",
"settings": "settings",
"metadata": "metadata",
"is_accountant": false,
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-15T10:30:00.000Z"
},
"redirect_origin": "redirect-origin"
}Create user
/users/signupCreate a new user account. For regular main-app signups this provisions an initial account membership unless a valid account invitation token joins the user to an existing account. White-label signups remain entity-user signups and ignore account invitation tokens.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.signup({
email: "user@example.com",
name: "name",
password: "password",
settings: "settings",
metadata: {
external_id: "123",
source: "shopify"
},
company_name: "company-name",
account_invitation_token: "account-invitation-token",
signup_attribution: {
utm_source: "google",
utm_medium: "cpc",
utm_campaign: "spring_launch",
gclid: "Cj0KCQiA_example-click.id_123",
gbraid: "0AAAAAD_example-gbraid",
wbraid: "CK_example-wbraid",
fbclid: "IwAR_example-fbclid"
}
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"id": "id",
"email": "user@example.com",
"name": "name",
"email_verified": true,
"account_id": "account-id",
"settings": "settings",
"metadata": {
"external_id": "123",
"source": "shopify"
},
"is_accountant": false,
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-15T10:30:00.000Z"
}Request password reset
/users/password-resetRequest a password reset email. Always returns success to avoid email enumeration.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.requestPasswordReset({
email: "user@example.com",
shopify_return_url: "/shopify/apollo#token=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"message": "message"
}Confirm password reset
/users/password-reset/confirmReset a user password with a valid password reset token.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.confirmPasswordReset({
token: "token",
password: "password"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"message": "message"
}Request account deletion
/users/me/account-deletionImmediately disables login and records a request to erase personal data that is not subject to statutory retention. Invoices and accounting records remain for the legally required period. Sign in with Apple authorization is revoked when a revocation token is available; provider failures are queued for retry without blocking the deletion request.
Returns
{
"requested_at": "2025-01-15T10:30:00.000Z",
"retention_notice": "retention-notice"
}Get account two-factor requirement
/accounts/two-factor-policyAccount owners/admins manage this policy. Applies only to direct account team members on their next interactive login, never to related entities or white-label users by ownership. Defaults to false.
Header parameters
Account Id on which the request is made. Optional if user is part of only one account.
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.getAccountTwoFactorPolicy({
account_id: "YOUR_ACCOUNT_ID"
});
console.log(response);Returns
{
"required": true
}Get two-factor authentication status
/users/me/two-factorGet two-factor authentication status
Returns
{
"enabled": true,
"has_password": true,
"required": true,
"recovery_codes_remaining": 0
}List current user accounts
/users/me/accountsReturn the accounts the authenticated user belongs to, including display names and account-level roles.
Returns
{
"data": [
{
"id": "acc_123",
"name": "Space Invoices",
"role": "owner"
},
{
"id": "acc_456",
"name": "Apollo",
"role": "member"
}
]
}Get current user
/users/meRetrieve the authenticated user's profile information. Returns the user details associated with the provided Bearer token.
Returns
{
"id": "6595a27b5d35015c3ef0c3fd",
"email": "example@spaceinvoices.com",
"email_verified": false,
"is_accountant": false,
"name": null,
"account_id": null,
"metadata": {},
"settings": {},
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}Set account two-factor requirement
/accounts/two-factor-policyAccount owners/admins manage this policy. Applies only to direct account team members on their next interactive login, never to related entities or white-label users by ownership. Defaults to false.
Header parameters
Account Id on which the request is made. Optional if user is part of only one account.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.updateAccountTwoFactorPolicy({
required: true
}, {
account_id: "YOUR_ACCOUNT_ID"
});
console.log(response);Returns
{
"required": true
}Set entity two-factor requirement
/entities/{id}/two-factor-policyRequires an interactive session and entity settings management permission. Applies only to direct entity users on their next interactive login. No account, sibling entity or ownership inheritance. Defaults to false.
Header parameters
Account Id on which the request is made. Optional if user is part of only one account.
Path parameters
Space Invoices resource identifier (format: {prefix}_{hex24})
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.updateEntityTwoFactorPolicy("inv_6595a27b5d35015c3ef0c3fd", {
required: true
}, {
account_id: "YOUR_ACCOUNT_ID"
});
console.log(response);Returns
{
"required": true
}Update current user
/users/meUpdate the authenticated user's profile. Currently supports updating the display name and preferred UI language (locale).
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.update({
locale: "sl"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"id": "6595a27b5d35015c3ef0c3fd",
"email": "example@spaceinvoices.com",
"email_verified": false,
"is_accountant": false,
"name": null,
"account_id": null,
"metadata": {},
"settings": {},
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}Update user FURS operator settings
/users/me/settings/fursUpdate FURS operator settings (tax number, label) for the current user. Settings are stored per-entity using the x-entity-id header. These settings are used when the user creates invoices through the web interface.
Header parameters
Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.updateFursSettings({
operator_tax_number: "12345678",
operator_label: "Alex Carter"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"id": "6595a27b5d35015c3ef0c3fd",
"email": "example@spaceinvoices.com",
"email_verified": false,
"is_accountant": false,
"name": null,
"account_id": null,
"metadata": {},
"settings": {},
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}Update user FINA operator settings
/users/me/settings/finaUpdate FINA operator settings (OIB, label) for the current user. Settings are stored per-entity using the x-entity-id header. These settings are used when the user creates invoices through the web interface.
Header parameters
Entity ID on which the request is made. Auto-selected when only one entity exists, required when multiple entities exist.
Body parameters
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.updateFinaSettings({
operator_oib: "12345678901",
operator_label: "Ivan Horvat"
}, {
entity_id: "YOUR_ENTITY_ID"
});
console.log(response);Returns
{
"id": "6595a27b5d35015c3ef0c3fd",
"email": "example@spaceinvoices.com",
"email_verified": false,
"is_accountant": false,
"name": null,
"account_id": null,
"metadata": {},
"settings": {},
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}Get entity two-factor requirement
/entities/{id}/two-factor-policyRequires an interactive session and entity settings management permission. Applies only to direct entity users on their next interactive login. No account, sibling entity or ownership inheritance. Defaults to false.
Header parameters
Account Id on which the request is made. Optional if user is part of only one account.
Path parameters
Space Invoices resource identifier (format: {prefix}_{hex24})
import SpaceInvoices from '@spaceinvoices/js-sdk/sdk';
const sdk = new SpaceInvoices('YOUR_API_KEY');
const response = await sdk.users.getEntityTwoFactorPolicy("inv_6595a27b5d35015c3ef0c3fd", {
account_id: "YOUR_ACCOUNT_ID"
});
console.log(response);Returns
{
"required": true
}