Skip to main content

Authentication Endpoints

This document provides detailed information about the authentication-related endpoints in the Amove Click API. These endpoints handle signup, login, multi-factor authentication, Google authentication, password reset, and profile management.

This API is bound to http://localhost:29123 on a machine running the Amove desktop agent. It is not a hosted service.

Login flow

The agent performs a three-step login:

  1. POST /authentication/login with a username and password. The response returns either a JwtToken (on success) or a Challenge = TOTP with a Session when MFA is required.
  2. If MFA is required, the client collects the TOTP code from an authenticator app and calls POST /authentication/mfa_respond with the Session and UserCode. The response returns a JwtToken.
  3. Use the returned JwtToken as the ?token= query parameter on subsequent protected endpoints.

Endpoints

  1. Login
  2. Logout
  3. MFA Respond
  4. Forgot Password
  5. Sign Up
  6. Confirm Sign Up
  7. Resend Confirmation Email
  8. Google Sign Up
  9. Google Login
  10. Get User
  11. Update User
  12. Reset Password

Login

Authenticates a user with username and password and returns either a JWT token or an MFA challenge.

  • URL: /authentication/login
  • Method: POST
  • Auth Required: No

Request Body

{
"username": "user@example.com",
"password": "string",
"type": "integer (enum)"
}
FieldTypeDescription
usernamestringUser's email address.
passwordstringUser's password.
typeinteger (enum)User type. Desktop clients use one of DesktopAdmin (16), DesktopCreativeUser (32), or DesktopStandardUser (64).

Response

{
"jwtToken": "EXAMPLE_TOKEN",
"challenge": 0,
"session": ""
}
FieldTypeDescription
jwtTokenstringJWT token to use on subsequent protected endpoints. Empty when an MFA challenge is required.
challengeinteger (enum)0 (None), 1 (TOTP), or 2 (SMS). When 1, the client must complete MFA via mfa_respond.
sessionstringOpaque session identifier. Present when challenge is non-zero. Pass it to mfa_respond.

Logout

Invalidates the supplied JWT token.

  • URL: /authentication/logout
  • Method: POST
  • Auth Required: No (the JWT to invalidate is carried in the body)

Request Body

{
"jwtToken": "EXAMPLE_TOKEN"
}

Response

200 OK with no body.

MFA Respond

Completes multi-factor authentication by submitting a TOTP code for a pending login session.

  • URL: /authentication/mfa_respond
  • Method: POST
  • Auth Required: No

Request Body

{
"userCode": "123456",
"session": "EXAMPLE_SESSION"
}
FieldTypeDescription
userCodestringTOTP code generated by an authenticator app (for example Google Authenticator).
sessionstringSession identifier returned from the preceding login call.

Response

Same shape as the login response. On success, jwtToken is populated and challenge is 0.

Forgot Password

Starts the forgot-password procedure. A reset email is sent if the username exists.

  • URL: /authentication/forgot_password
  • Method: POST
  • Auth Required: No

Request Body

{
"username": "user@example.com"
}

Response

200 OK. The response does not reveal whether the username matched an account.

Sign Up

Registers a new user. A confirmation email with a short activation code is sent to the supplied address.

  • URL: /authentication/signup
  • Method: POST
  • Auth Required: No

Request Body

{
"name": "Jane Doe",
"email": "user@example.com",
"password": "string"
}
FieldTypeDescription
namestringSign-up display name. Maximum 50 characters.
emailstringEmail address that will become the username. Maximum 50 characters.
passwordstringPassword for the new account.

Response

200 OK.

Confirm Sign Up

Confirms a new account by submitting the activation code emailed after signup.

  • URL: /authentication/confirm_signup
  • Method: POST
  • Auth Required: No

Request Body

{
"email": "user@example.com",
"token": "1234"
}
FieldTypeDescription
emailstringEmail address the code was sent to.
tokenstringActivation code (maximum 4 characters).

Response

Boolean. true when the account is activated successfully.

Resend Confirmation Email

Re-sends the confirmation email for a pending sign-up.

  • URL: /authentication/resend_confirmation_email
  • Method: POST
  • Auth Required: No

Request Body

{
"email": "user@example.com"
}

Response

200 OK.

Google Sign Up

Creates a new Amove account from a Google identity and returns a JWT token.

  • URL: /authentication/google_signup
  • Method: POST
  • Auth Required: No

Request Body

{
"idToken": "GOOGLE_ID_TOKEN"
}
FieldTypeDescription
idTokenstringGoogle-issued ID token obtained from a client-side Google sign-in flow.

Response

A string containing the JWT token for the newly created account.

Google Login

Authenticates an existing Google-linked Amove account and returns a JWT token.

  • URL: /authentication/google_login
  • Method: POST
  • Auth Required: No

Request Body

Same as Google Sign Up.

Response

A string containing the JWT token.

Get User

Returns the profile for the authenticated user.

  • URL: /authentication/user
  • Method: GET
  • Auth Required: Yes

Query Parameters

ParameterTypeDescription
tokenstringJWT token obtained from login.

Response

{
"accountName": "Example Org",
"accountId": "00000000-0000-0000-0000-000000000000",
"userId": "00000000-0000-0000-0000-000000000000",
"firstName": "Jane",
"lastName": "Doe",
"username": "user@example.com",
"userType": 16,
"jwtToken": "EXAMPLE_TOKEN",
"owner": true,
"migration": false,
"subscriptionType": 1,
"mfa": false,
"authProvider": 0
}
FieldTypeDescription
accountNamestringOrganization account name.
accountIdstring (uuid)Account identifier.
userIdstring (uuid)User identifier.
firstNamestringFirst name.
lastNamestringLast name.
usernamestringUsername (normally an email).
userTypeinteger (enum)UserType flag value.
jwtTokenstringSame token the caller supplied.
ownerbooleantrue when the user is the account owner.
migrationbooleantrue when the user is in a migration state.
subscriptionTypeinteger (enum)AccountSubscriptionType: 1 (Monthly), 2 (Yearly).
mfabooleantrue when MFA is enabled for the account.
authProviderinteger (enum)Authentication provider: 0 (AWSCognito), 1 (Google), 2 (EntraID), 4 (Okta), 8 (SAML), 16 (External).

Update User

Updates the authenticated user's profile fields.

  • URL: /authentication/update_user
  • Method: PUT
  • Auth Required: Yes

Query Parameters

ParameterTypeDescription
tokenstringJWT token.

Request Body

{
"accountName": "Example Org",
"firstName": "Jane",
"lastName": "Doe"
}

Response

Returns the updated user object in the same shape as Get User.

Reset Password

Sets a new password on the authenticated account.

  • URL: /authentication/reset_password
  • Method: POST
  • Auth Required: Yes

Query Parameters

ParameterTypeDescription
tokenstringJWT token.

Request Body

{
"password": "new-password",
"currentPassword": "old-password"
}

Response

200 OK.

Sample Code

Login and use the token

Python
import requests

base = "http://localhost:29123"

login = requests.post(
f"{base}/authentication/login",
json={
"username": "user@example.com",
"password": "p@ssw0rd",
"type": 16,
},
)
login.raise_for_status()
data = login.json()

if data["challenge"] == 1:
code = input("Enter TOTP code: ")
mfa = requests.post(
f"{base}/authentication/mfa_respond",
json={"userCode": code, "session": data["session"]},
)
mfa.raise_for_status()
token = mfa.json()["jwtToken"]
else:
token = data["jwtToken"]

user = requests.get(
f"{base}/authentication/user",
params={"token": token},
)
print(user.json())
JavaScript
const base = "http://localhost:29123";

const loginRes = await fetch(`${base}/authentication/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
username: "user@example.com",
password: "p@ssw0rd",
type: 16,
}),
});
const login = await loginRes.json();

let token = login.jwtToken;
if (login.challenge === 1) {
const mfaRes = await fetch(`${base}/authentication/mfa_respond`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
userCode: "123456",
session: login.session,
}),
});
token = (await mfaRes.json()).jwtToken;
}

const user = await fetch(
`${base}/authentication/user?token=${encodeURIComponent(token)}`
);
console.log(await user.json());
C#
using System.Net.Http.Json;

using HttpClient client = new() { BaseAddress = new Uri("http://localhost:29123") };

HttpResponseMessage loginRes = await client.PostAsJsonAsync(
"/authentication/login",
new { username = "user@example.com", password = "p@ssw0rd", type = 16 });
loginRes.EnsureSuccessStatusCode();

dynamic login = await loginRes.Content.ReadFromJsonAsync<dynamic>();
string token = login.jwtToken;

HttpResponseMessage userRes = await client.GetAsync($"/authentication/user?token={Uri.EscapeDataString(token)}");
Console.WriteLine(await userRes.Content.ReadAsStringAsync());

For error handling, see Error Model.