Part 1 - User Registration
Like most mobile applications, lōm starts by asking the user to create an account. This part of the walkthrough covers how Experience Users and Endpoints can be used to accomplish user registration.

In the lōm mobile app, pressing the “Create Account” button on the lōm main screen takes the user to the “Create Account” screen. This screen asks the user for an email and a password. The client-side code confirms the email is in a proper format and the passwords match. It then performs an Experience API Endpoint request to create the user.
The API for lōm follows a typical REST format. This means we’ll use a POST request against the users
collection to create a new user resource.
To accomplish this ourselves, let’s create an Experience Endpoint with this route:
POST /users
This new endpoint will accept email
and password
as POST data, like so:
{ "email": "user@example.com", "password": "the-provided-password" }
To create this endpoint in Losant, the first thing we have to do is create an endpoint within our application Experience.
Click Edit
within the Experience
section of your application’s sub-navigation to manage your application’s Experience. First-time users will be presented with a wizard that will automatically create a basic example experience. This guide will not use any of those auto generated resources, so it’s recommended that you skip the bootstrap for now.
Click the Endpoints
tab in the top navigation. On the Endpoints page, you’ll see an Add
button in the top right corner of the endpoints list. Click Add
to create the new endpoint for user registration.
- Set the
Method
toPOST
. - Set the
Route
to/users
. - Set the description to anything you’d like.
- Set the
Access Control
toAll public users
.
Experience endpoints have three authentication options: all public users, any authenticated user, and users that belong to a specific group. Since it’s used to originally create the user, this registration route must be publicly available. All routes within lōm, other than account creation and user login, will require authentication.
When done, click the Create Endpoint
button at the bottom to create this endpoint, and then return to the list of endpoints.
At this point, we have the /users
endpoint defined, but there’s no logic to run when it’s requested. If you were to request it now, Losant will automatically return a 404. In order to give this endpoint some intelligence, we have to create an experience workflow. All experience endpoints are backed by workflows that contain the Endpoint trigger node and Endpoint Reply node.
Create a new workflow for this endpoint from your application’s Workflows
menu inside of the Visual Workflow Engine
section. Make sure to choose Experience
as the Workflow Type.
Now we have an empty workflow that we can use to power our /users
endpoint. The first step is to add an endpoint trigger to the workflow canvas.
In the trigger’s configuration, select the endpoint we just created (i.e. POST /users). This workflow will now run whenever that API endpoint is requested.
For now, let’s make a simple workflow that simply returns 200 (OK) whenever anything is requested. We’ll also use a Debug node so you can see the format of the data as it comes into the workflow.
Add a Debug node and an Endpoint Reply node to the canvas.
- Add a Debug node and connect it to the Endpoint Trigger node.
- Add an Endpoint Reply node and connect it to the Endpoint Trigger node.
- In the Endpoint Reply config, set the
Response Code Template
to200
. - In the Endpoint Reply config, set the
Response Body Template
toOK
Click the Save & Deploy
button to deploy this workflow. You can now request this API endpoint using your favorite API tester, like Postman or CURL.
curl -H "Content-Type: application/json" -X POST \
-d '{"email":"test@example.com","password":"my-password"}' \
https://example.onlosant.com/users
Once you make this request, you’ll see an entry in the Debug tab with the payload that includes the email and password.
From here you can see that the email and password are available on the payload at data.body.email
and data.body.password
. Losant automatically hides the values of fields that could be considered sensitive, which is why it doesn’t show a value for the password field.
Now that we’re receiving an email and password, the first thing we have to do is check to see if the email already exists. If a user exists, this workflow should return a 409 (Conflict) back to the client.
First, add a Get User node to the workflow and connect it to the endpoint trigger.
- Set the
ID or Email Template
to{{ data.body.email }}
. As we saw earlier, this is the location on the payload where the incoming email is available. - Set the
Result Path
todata.existingUser
. This will put the user, if found, back on the payload so we can access it in later steps. If no user is found, this field will be set tonull
.
If the user exists, data.existingUser
will be something other than null
. Next, add a Conditional node to check for whether or not an existing user already exists. Connect it to the get user node.
- Set the
Expression
to{{ data.existingUser }} === null
. If the expression returns true (the user does not exist), the workflow will take the right path. If the expression is false, the workflow will take the left path.
At this point, we’re ready to return the 409 (Conflict)
back to the client if the user already exists. Add an Endpoint Reply node and connect it to the left (false) output of the conditional node.
- Set the
Response Code Template
to409
. - Set the
Response Body Template
to{ "error": "Email already exists." }
. - Add a
Content-Type
header with the valueapplication/json
.
This API will properly check that a user exists and will return an error if it does. You can test this by creating an example user through the Losant interface, and then making a request with that same user email against this endpoint.
Click the Save & Deploy
button to deploy this workflow.
curl -H "Content-Type: application/json" -X POST \
-d '{"email":"example@example.com","password":"my-password"}' \
https://example.onlosant.com/users
If you make this curl
request with an already existing user, you should receive this response:
{ "error": "Email already exists." }
The last thing to do is actually create the user. Add a Create User node and attach it to the right (true) output of the conditional node.

- Set the
Email Address Template
to{{ data.body.email }}
. - Set the
Password Template
to{{ data.body.password }}
. - Set the
Result Path
todata.newUser
.
This node will create a new user inside your application Experience. lōm only collects email and password, however, experience users also have built-in fields for first and last names. User tags can be used to store any other information specific to your application’s users.
The new user will be put back on the payload at data.newUser
, so we can return it to the client as the result of this API request. Next, add an Endpoint Reply node and connect it to the Create User node.
- Set the
Response Code Template
to201
, which is the HTTP status code for “created”. - Choose
Payload Path
forResponse Body Source
. - Set the
Response Body Payload Path
todata.newUser
. - Add a
Content-Type
header with the valueapplication/json
.
This node will now return the contents of the new user, in JSON format, back to the client as the body of the response.
When done, deploy this workflow using the Save & Deploy
button. You can now test this route by attempting to create a new user.
curl -H "Content-Type: application/json" -X POST \
-d '{"email":"my.awesome.user@example.com","password":"my-password"}' \
https://example.onlosant.com/users
{
"email": "my.awesome.user@example.com",
"userTags": { },
"applicationId": "58e0152c1c3ce300017cc5bf",
"creationDate": "2018-11-15T17:17:37.169Z",
"lastUpdated": "2018-11-15T17:17:37.553Z",
"passwordLastUpdated": "2018-11-15T17:17:37.553Z",
"experienceUserId": "58e02cac0d1a3b00011f0d81",
"avatarUrl": "....",
"id": "58e02cac0d1a3b00011f0d81",
"experienceGroups": []
}
Once this route is requested successfully, you’ll see the new user in the experience user list.
The next thing we want to do is send our new user a welcome email once they’ve registered. Add an Email node and connect it to the Endpoint Reply node.
- Set the
To Address Template
to{{ data.body.email }}
. - Set the
From Address Template
to whatever email address you’d like. - Set the
Email Subject Template
to whatever you’d like. - Set the
Email Body Template
to whatever HTML contents you’d like.
Now whenever a user registers, they’ll receive your friendly welcome email. The built-in email node does have a limit of one message per minute. If you plan on registering a bunch of users, you may want to switch to the SendGrid node, which will use your own SendGrid account to send as many emails as you’d like.
The very last step is to add some basic input validation on the incoming data. We want to make sure the client did send us an email and password before doing any other work. If a field is missing, this API will return a 400 (Bad Request) back to the client. Add a conditional node directly after the endpoint trigger.
- Set the
Expression
to{{ data.body.email }} && {{ data.body.password }}
. This expression checks that both email and password exist.
You can now connect the right (true) output of the new Condition node to the existing Get User node, which will now only attempt to run the rest of this workflow if the client actually provided an email and password. To reply with an error, add an Endpoint Reply to the left (false) output of the Conditional node.
- Set the
Response Code Template
to400
. - Set the
Response Body Template
to `{ “error”: “Email and password fields required.” } - Add a
Content-Type
header with the valueapplication/json
.
You can now test this endpoint by attempting to register a user with a missing field. Click the Save & Deploy
button to deploy this workflow.
curl -H "Content-Type: application/json" -X POST \
-d '{"password":"my-password"}' \
https://example.onlosant.com/users
{ "error": "Email and password fields required." }
This concludes Part 1 of the application experience walkthrough. As of now, lōm has a fully functional user registration endpoint. The next part covers how users will log in once they’ve registered.
Continue to Part 2: User Authentication