Skip to main content

POST /api/v1/users

Creates a new users resource.

Account email input is case-insensitive. The API stores and returns the email in lowercase.

Invite-only apps reject this public signup endpoint with 403, including calls that pass type=invitation. Users for invite-only apps must be invited through the authenticated dashboard invite endpoint.

This endpoint documentation is generated from the current Fastify route implementation and should be treated as the implementation-level contract for this version of the API.

Source route file: src/api/routes/external/public/users/post.ts

Request Method​

POST

Base URL​

https://api.userdocks.local:5000

Endpoint​

/api/v1/users

Path Variables​

No path variables.

Query Parameters​

VariableTypeRequiredDescription
typestringfalseQuery parameter parsed by route handler.
invitationTenantUuidstringfalseQuery parameter parsed by route handler.
languagestringtrueQuery parameter parsed by route handler.

HTTP Headers​

VariableTypeRequiredDescription
OriginstringfalseUsed for custom-domain lookup in public app resolution.
Content-TypestringtrueUse application/json for JSON request bodies.

Request Body​

Schema reference: createBaseUserSchemaWithoutAddresses

{
"email": "user@example.com",
"password": "VeryStrongPass123!",
"passwordConfirmation": "VeryStrongPass123!",
"acceptedTermsAndConditions": true,
"acceptedDataPrivacy": true,
"acceptPrivacyPolicy": false,
"appUuid": "11111111-1111-1111-1111-111111111111",
"referrer": "gzamj4h968dw5nw52g7hc1i0",
"phoneNumber": "+491234567890"
}

referrer is optional. When provided, it must match the referralCode of a non-disabled, non-deleted user in the resolved app. Invalid codes and codes from other apps are ignored and stored as null.

Successful Response​

Success status code(s): 201.

{
"kind": "users",
"totalItems": 1,
"itemsLength": 1,
"items": [
{
"uuid": "user_11111111-1111-1111-1111-111111111111",
"email": "user@example.com",
"sub": "auth0|user_11111111",
"name": "Jane Doe",
"givenName": "Jane",
"familyName": "Doe",
"middleName": null,
"nickname": "jane",
"preferredUsername": "jane.doe",
"profile": "https://example.com/users/jane",
"picture": "https://example.com/assets/jane.png",
"website": "https://example.com",
"emailVerified": true,
"gender": "female",
"birthdate": "1990-01-01",
"zoneinfo": "Europe/Berlin",
"locale": "en",
"phoneNumber": "+491234567890",
"phoneNumberVerified": true,
"referrer": "gzamj4h968dw5nw52g7hc1i0",
"referralCode": "ref_11111111",
"preferredLanguageUuid": "lang_11111111-1111-1111-1111-111111111111",
"isDisabled": false,
"appUuid": "app_11111111-1111-1111-1111-111111111111",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z",
"userTags": [
{
"tag": {
"uuid": "tag_11111111-1111-1111-1111-111111111111",
"appUuid": "app_11111111-1111-1111-1111-111111111111",
"name": "beta-user",
"description": "User belongs to beta segment",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
}
],
"addresses": [
{
"uuid": "addr_11111111-1111-1111-1111-111111111111",
"name": "billing",
"addressLineOne": "Main Street 1",
"addressLineTwo": "Floor 3",
"postalCode": "10115",
"locality": "Berlin",
"region": "Berlin",
"country": "DE",
"type": "business",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
],
"tenantsAsAdmin": [
{
"tenant": {
"uuid": "tenant_11111111-1111-1111-1111-111111111111",
"name": "Acme Tenant",
"isDisabled": false,
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
}
],
"tenantsAsUser": [
{
"tenant": {
"uuid": "tenant_11111111-1111-1111-1111-111111111111",
"name": "Acme Tenant",
"isDisabled": false,
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
}
]
}
]
}

Error Responses​

HTTP StatusExample Error
403{"errors":[{"validation":"forbidden","code":"[E0043]","message":"Forbidden: This app is invite only."}]}
400{"errors":[{"validation":"error","code":"[E4000]","message":"Bad Request / validation error"}]}
500{"errors":[{"validation":"error","code":"[E0000]","message":"Internal Server Error"}]}

Example​

const query = new URLSearchParams({
type: 'confirmation',
invitationTenantUuid: '11111111-1111-1111-1111-111111111111',
language: 'en',
});
const url = `https://api.userdocks.local:5000/api/v1/users?${query.toString()}`;

const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: '{"email":"user@example.com","password":"VeryStrongPass123!","passwordConfirmation":"VeryStrongPass123!","acceptedTermsAndConditions":true,"acceptedDataPrivacy":true,"acceptPrivacyPolicy":false,"appUuid":"11111111-1111-1111-1111-111111111111"}',
});
const data = await response.json();
console.log(response.status, data);