Help Centre

Workflow SmartLink SSO API

Last updated 19 October 2026

A SmartLink is a signed link that registers a client for a workflow and signs them in to Money Alive in one click. Your own system makes one for each client, for example a button in your client portal. When the client opens it, their account is created if they don't have one, they join the workflow, and their videos open.

SmartLinks are switched on for your account by us. If you don't see SmartLink in the workflow builder, contact us.

Switch it on for a workflow

  1. Open the workflow. On the Onboarding card, press + and choose SmartLink.
  2. Switch the SmartLink on (1).
  3. Open Details and copy the Shared secret (2) and the Workflow App ID (3). You need both to make SmartLinks.

The SmartLink window

Keep the shared secret private, like a password. Anyone who has it can make SmartLinks for that workflow. Only use it on your server, never in a web page or an app a client can see inside.

The link

https://moneyalive.io/signable/token/login
Add What it is Needed
appId The Workflow App ID Yes
firstName The client's first name Yes
surname The client's surname Yes
username The client's email address Yes
phone The client's phone number No
expires When the link stops working, as a Unix time in seconds Yes
token The signature, made as shown below Yes

When a link expires

Every SmartLink must say when it stops working. Set expires to a time in the future, at most 7 days ahead. After that time the link is refused, so a link that is forwarded or found later can't be used to sign in.

Make a fresh link each time a client clicks through, for example when they press the button in your portal. Then a short expiry, such as 10 minutes, works well and is the safest choice.

expires is signed along with the other details, so it can't be changed once the link is made.

Make the signature

  1. Build the query string from the details, without token, encoding each value for a web address. For example:

    appId=83&firstName=Jane&surname=Smith&username=jane%40example.com&expires=1798761600
  2. Encode that whole query string for a web address again. = becomes %3D, & becomes %26, and the %40 from step 1 becomes %2540:

    appId%3D83%26firstName%3DJane%26surname%3DSmith%26username%3Djane%2540example.com%26expires%3D1798761600
  3. Put the shared secret in front, and take the SHA-1 hash of the result. That's the token.

    token = sha1(SHARED_SECRET + encoded_query_string)
  4. Add &token= and the token to the end of the query string from step 1. Keep the other details in the same order you signed them in.

Worked example

With the shared secret example-shared-secret, the details above give this token:

bd4970905eab62283adf1105025cb092562be03e

and this SmartLink:

https://moneyalive.io/signable/token/login?appId=83&firstName=Jane&surname=Smith&username=jane%40example.com&expires=1798761600&token=bd4970905eab62283adf1105025cb092562be03e

Use this example to check your own code before you switch to your real secret. The example's expires is a fixed time, so the link itself won't sign anyone in; your real links use a time a few minutes ahead.

Code

PHP
// The client's details, in the order you'll send them
$params = [
    'appId'     => $appId,
    'firstName' => $firstName,
    'surname'   => $surname,
    'username'  => $email,
    'expires'   => time() + 600, // 10 minutes from now
];

// Encode the details, then encode the whole string again before signing
$query = http_build_query($params);
$token = sha1($sharedSecret . urlencode($query));

$smartLink = 'https://moneyalive.io/signable/token/login?' . $query . '&token=' . $token;
Python
import hashlib
import time
from urllib.parse import urlencode, quote_plus

# The client's details, in the order you'll send them
query = urlencode({
    'appId': app_id,
    'firstName': first_name,
    'surname': surname,
    'username': email,
    'expires': int(time.time()) + 600,  # 10 minutes from now
})

# Encode the whole string again before signing
token = hashlib.sha1((shared_secret + quote_plus(query)).encode()).hexdigest()

smart_link = f'https://moneyalive.io/signable/token/login?{query}&token={token}'

What happens when it's opened

If something is wrong, the link is refused with one of these messages:

Message What to check
Invalid token provided That you encoded the query string a second time, and that the details are in the same order as when you signed them.
Missing expires from request That the link includes expires, and that it's a whole number of seconds.
Link has expired That expires is in the future when the client opens the link, and that your server's clock is right.
Link expires more than 7 days ahead That expires is no more than 7 days from now.

Related articles