Server API
Endpoint: https://signal.authsignal.com
The Authsignal Server API can be used to identify users, to query their MFA setup, and to track actions against them which could require an MFA challenge.
Libraries
Authentication
The Authsignal Server API uses your secret key to authenticate requests. You should only ever call the Authsignal Server API from your server where your secret key can be stored securely. Your secret key should never be exposed to any public client.
You can find your secret key in the API Keys section of the Authsignal Dashboard settings.
- cURL
- Node.js
- Ruby
- Python
- PHP
- C#
curl -u "YOUR_SECRET_KEY:" https://signal.authsignal.com
import { Authsignal } from "@authsignal/node";
const authsignal = new Authsignal({ secret: "YOUR_SECRET_KEY" });
Authsignal.setup do |config|
config.api_secret_key = ENV["AUTHSIGNAL_SECRET_KEY"]
end
import authsignal.client
authsignal_client = authsignal.Client(api_key='<SECRET API KEY HERE>')
Authsignal::setApiKey("<SECRET API KEY HERE>");
using Authsignal;
var authsignal = new AuthsignalClient(secret: "YOUR_SECRET_KEY");
Region selection
Authsignal's server SDKs defaults to the US (Oregon) region. If your tenant is in a different region, a different base URL must be configured.
Region | Base URL |
---|---|
US (Oregon) | https://signal.authsignal.com/v1 |
AU (Sydney) | https://au.signal.authsignal.com/v1 |
EU (Dublin) | https://eu.signal.authsignal.com/v1 |
Here are examples of different SDKs setting the base URL to use our AU endpoint.
- Node.js
- Ruby
- Python
- PHP
- C#
import { Authsignal } from "@authsignal/node";
const authsignal = new Authsignal({ secret: "YOUR_SECRET_KEY", apiBaseUrl: "https://au.signal.authsignal.com/v1" });
Authsignal.setup do |config|
config.api_secret_key = ENV["AUTHSIGNAL_SECRET_KEY"]
config.base_uri = "https://au.signal.authsignal.com/v1"
end
import authsignal.client
authsignal_client = authsignal.Client(api_key='<SECRET API KEY HERE>', api_url: 'https://au.signal.authsignal.com/v1')
Authsignal::setApiKey("<SECRET API KEY HERE>");
Authsignal::setApiHostname("https://au.signal.authsignal.com/v1")
using Authsignal;
var authsignal = new AuthsignalClient(secret: "YOUR_SECRET_KEY", baseAddress: "https://au.signal.authsignal.com/v1");
Retrieve user
The GET /users/:userId
endpoint retrieves a user and their MFA enrollment status. A user is considered to be enrolled if they have set up at least one authenticator which can be used to issue a challenge.
- cURL
- Node.js
- Ruby
- Python
- PHP
- C#
curl https://signal.authsignal.com/v1/users/usr_123 \
-u YOUR_SECRET_KEY:
const result = await authsignal.getUser({ userId: "usr_123" });
if (result.isEnrolled) {
// The user has set up MFA and can be challenged
} else {
// The user has either not set up MFA or they have disabled it
}
result = Authsignal.get_user(user_id: current_user.id)
is_enrolled = result[:is_enrolled]
result = authsignal_client.get_user(user_id="usr_123")
is_enrolled = result["isEnrolled"]
$result = Authsignal::getUser(userId: "usr_123");
$isEnrolled = $result["isEnrolled"];
var request = new UserRequest(UserId: "usr_123");
var response = await authsignal.GetUser(request);
if (response.IsEnrolled) {
// The user has set up MFA and can be challenged
} else {
// The user has either not set up MFA or they have disabled it
}
Request
userIdstring
The unique ID for this user in your database.
Response
isEnrolledboolean
Whether or not the user is enrolled for MFA and can be challenged.
allowedVerificationMethodsstring[]
An array of the allowed verification methods.
enrolledVerificationMethodsstring[]
An array of the user's enrolled authenticators.
emailstring
The email address of the user performing the action
{
"isEnrolled": true,
"enrolledVerificationMethods": [
"SMS",
"AUTHENTICATOR_APP",
"RECOVERY_CODE",
"EMAIL_MAGIC_LINK",
"PUSH",
"SECURITY_KEY",
"PASSKEY"
],
"allowedVerificationMethods": [
"AUTHENTICATOR_APP",
"PUSH",
"PASSKEY",
"SMS",
"EMAIL_MAGIC_LINK"
],
"defaultVerificationMethod": "AUTHENTICATOR_APP",
"email": "user-123@gmail.com"
}
Track user action
The POST /users/:userId/actions/:action
endpoint lets you record the actions which your users perform and it will determine if these actions need to be gated behind an MFA challenge.
- Curl
- Node.js
- Ruby
- Python
- PHP
- C#
curl https://signal.authsignal.com/v1/users/usr_123/actions/withdrawal \
-u YOUR_SECRET_KEY: \
-H "Content-Type: application/json" \
-d '{"redirectUrl": "https://example.com/finalize-withdrawal"}'
const result = await authsignal.track({
userId: "usr_123",
action: "withdrawal",
redirectUrl: "https://example.com/finalize-withdrawal",
});
if (result.state === "CHALLENGE_REQUIRED") {
// The user should be presented with an MFA challenge
}
result = Authsignal.track_action({
action_code: "signIn",
idempotency_key: SecureRandom.uuid,
redirect_url: redirect_url,
user_id: "1234",
email: "test@example.com",
device_id: "XXX-XXX",
user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0",
ip_address: "1.1.1.1",
custom: {
it_could_be_a_bool: true,
it_could_be_a_string: "test",
it_could_be_a_number: 400.00
},
crypto: {
asset: "ETH",
address: "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
txnHash: "0x01994f9ee1b415a81f096ad20da8ecb3ae40b076eb486bb4191d62ae71b7ad0d",
assetAmount: 0.01,
assetAmountUsd: 17.96
},
redirectToSettings: false
}
)
case result[:state]
when "ALLOW"
# Carry on with your operation/business logic
when "BLOCK"
# Stop your operations
when "CHALLENGE_REQUIRED"
# Step up authentication required, redirect or pass the challengeUrl to the front end
result[:challenge_url]
end
import authsignal.client
result = authsignal_client.track_action(
user_id="1234",
action_code="testPython",
payload={
"redirectUrl": "https://www.example.com/",
"email": "test@python.com",
"deviceId": "XXX-XXX",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0",
"ipAddress": "1.1.1.1",
"custom": {
"yourOwnCustomBoolean": True,
"yourOwnCustomString": "Blue",
"yourOwnCustomDecimal": 100.00,
},
"crypto": {
"asset": "ETH",
"address": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"txnHash": "0x01994f9ee1b415a81f096ad20da8ecb3ae40b076eb486bb4191d62ae71b7ad0d",
"assetAmount": 0.01,
"assetAmountUsd": 17.96
},
"redirectToSettings": false
}
)
match result["state"]
case authsignal.client.ALLOW:
# Carry on with your operation/business logic
case authsignal.client.BLOCK:
# Stop your operations
case authsignal.client.CHALLENGE_REQUIRED:
# Step up authentication required, redirect or pass the challengeUrl to the front end
response["challengeUrl"]
$idempotencyKey = "XXXX-XXXX";.
$redirectUrl = "https://www.yourapp.com/back_to_your_app";
$ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'] || $_SERVER['HTTP_X_REAL_IP'] || $_SERVER['REMOTE_ADDR'];
$payload = array(
"redirectUrl" => $redirectUrl,
"email" => "test@email",
"deviceId" => $authsignalCookie,
"userAgent" => $_SERVER["HTTP_USER_AGENT"],
"ipAddress" => $ipAddress,
"redirectToSettings" => false,
"custom" => array(
"yourCustomBoolean" => true,
"yourCustomString" => true,
"yourCustomNumber" => 1.12
),
"crypto" => array(
"asset" => "ETH",
"address" => "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"txnHash" => "0x01994f9ee1b415a81f096ad20da8ecb3ae40b076eb486bb4191d62ae71b7ad0d",
"assetAmount" => 0.01,
"assetAmountUsd" => 17.96
));
$result = Authsignal::trackAction(userId: "123345",
actionCode: "signIn",
payload: $payload);
switch ($result["state"]) {
case "ALLOW":
// Carry on with your operation/business logic
break;
case "BLOCK":
// Stop your operations
break;
case "CHALLENGE_REQUIRED":
// Step up authentication required, redirect or pass the challengeUrl to the front end
$response["challengeUrl"];
break;
}
var request = new TrackRequest(
UserId: "usr_123",
Action: "signIn",
RedirectUrl: "https://example.com/callback");
var response = await authsignal.Track(request);
if (response.State === UserActionState.CHALLENGE_REQUIRED) {
// The user should be presented with an MFA challenge
}
Request
userIdstring
The unique ID for this user in your database.
actionstring
The name of the action as defined in the Authsignal Portal.
idempotencyKeystring | undefined
A unique key which identifies the instance of the action that the user is performing. This can be an ID in your own app domain, such as a transaction ID or shopping cart ID, or if not provided one is generated automatically. Use this to lookup the status of the action after a challenge.
redirectUrlstring | undefined
The URL for the user to get redirected back to when exiting from the Challenge UI. Required when the page is presented via a redirect but not when presented as a popup.
ipAddressstring | undefined
The IP address of the user performing the action
emailstring | undefined
The email address of the user performing the action
userAgentstring | undefined
The user agent of the user performing the action
deviceIdstring | undefined
The ID of user's device. This could be a mobile device ID or the anonymousId returned by the Authsignal Browser web client.
customobject | undefined
A custom JSON object. Use this attribute to send a list of custom data points. Rules can be used to match against these data points.
cryptoobject | undefined
A crypto object. Use this attribute to send crypto related metadata and Know Your Transaction (KYT) use cases.
redirectToSettingsboolean | undefined
The flag to indicate if you want to redirect the user to their settings page, use this if you want to allow your user to manage their authenticators, defaults to false
{
"idempotencyKey":"d44e68c9-d20c-4bdb-874a-fab5da5f997e",
"email": "test@example.com",
"deviceId": "XXX-XXX",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0",
"ipAddress": "1.1.1.1",
"redirectUrl": "https://www.example.com/redirect-back",
"custom":{
"yourCustomBoolean": true,
"yourCustomString": "walletAddress",
"yourCustomNumber": 10.00
},
"crypto": {
"asset": "ETH",
"address": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"txnHash": "0x01994f9ee1b415a81f096ad20da8ecb3ae40b076eb486bb4191d62ae71b7ad0d",
"assetAmount": 0.01,
"assetAmountUsd": 17.96
},
"redirectToSettings": false
}
Response
stateenum
The current state of the action. The possible values are: CHALLENGE_REQUIRED, CHALLENGE_FAILED, CHALLENGE_SUCCEEDED, ALLOW, or BLOCK.
urlstring
The URL of the Challenge UI. You can redirect to this URL to challenge the user if the state determines that a challenge is required, or if you want to allow the user to enroll for MFA or to manage their existing MFA settings.
isEnrolledboolean
Whether or not the user is enrolled for MFA and can be challenged.
idempotencyKeystring
A unique key which identifies the instance of the action that the user is performing.
{
"state": "CHALLENGE_REQUIRED",
"idempotencyKey": "d44e68c9-d20c-4bdb-874a-fab5da5f997e",
"url": "https://mfa.authsignal.com/challenge",
"isEnrolled": true
}
Get action status
The GET /users/:userId/actions/:action/:idempotencyKey
endpoint lets you determine the result of a challenge after the user has been redirected back from the Challenge UI (or after the popup has been closed, if showing the page in a modal).
- cURL
- Node.js
- Ruby
- Python
- PHP
- C#
curl https://signal.authsignal.com/v1/users/usr_123/actions/withdrawal/ik_123 \
-u YOUR_SECRET_KEY:
const result = await authsignal.getAction({
userId: "usr_123",
action: "signIn",
idempotencyKey: "ik_123",
});
if (result.state === "CHALLENGE_SUCCEEDED") {
// The user successfully completed the MFA challenge
// Proceed with the withdrawal
}
result = Authsignal.get_action(
user_id: "1234",
action_code: "signIn",
idempotency_key: "15cac140-f639-48c5-92db-835ec8d3d144")
if (result.state === "CHALLENGE_SUCCEEDED") {
// The user successfully completed the MFA challenge
// Proceed with the signIn
}
result = authsignal_client.get_action(
user_id="1234",
action_code="signIn",
idempotency_key="0ae73782-d8c1-49bc-be75-09612a3b9d1c",
)
if result["state"] == "CHALLENGE_SUCCEEDED":
print("Procceed with business logic")
# The user has successfully completed the challenge, and you should proceed with
# the business logic
$result = Authsignal::getAction(userId: "123",
actionCode: "signIn",
idempotencyKey: "2320ce18-91be-47a8-9bbf-eec642807c34");
if($result["state"] === "CHALLENGE_SUCCEEDED"){
// The user has successfully completed the challenge,
// and you should proceed with the business logic
}
var request = new ActionRequest(
UserId: "usr_123",
Action: "signIn",
IdempotencyKey: "ik_123");
var response = await authsignal.GetAction(request);
if (response.State === UserActionState.CHALLENGE_SUCCEEDED) {
// The user successfully completed the MFA challenge
}
Request
userIdstring
The unique ID for this user in your database.
actionstring
The name of the action as defined in the Authsignal Portal.
idempotencyKeystring | undefined
A unique key which identifies the instance of the action that the user is performing. This can be an ID in your own app domain, such as a transaction ID or shopping cart ID, or if not provided one is generated automatically.
Response
stateenum
The current state of the action. The possible values are: CHALLENGE_REQUIRED, CHALLENGE_FAILED, CHALLENGE_SUCCEEDED, ALLOW, or BLOCK.
stateUpdatedAttimestamp
The time in ISO 8061 format when the state of the action was last updated.
createdAttimestamp
The time in ISO 8061 format when the action was first created via track.
{
"state": "CHALLENGE_REQUIRED",
"stateUpdatedAt": "2022-07-25T03:19:00.316Z",
"createdAt": "2022-07-25T03:19:00.317Z",
"ruleIds": []
}
Enroll verified authenticator
The POST /users/:userId/authenticators
endpoint can be used to enroll an authenticator on behalf of a user if it has already been verified.
- cURL
- Node.js
- Ruby
- Python
- PHP
- C#
curl https://signal.authsignal.com/v1/users/usr_123/authenticators \
-u YOUR_SECRET_KEY: \
-H "Content-Type: application/json" \
-d '{"oobChannel": "SMS", "phoneNumber": "+64271234567"}'
await authsignal.enrollVerifiedAuthenticator({
userId: "usr_123",
oobChannel: "SMS",
phoneNumber: "+64271234567",
});
Authsignal.enrol_authenticator(user_id: "1234",
authenticator:{ oob_channel: "SMS",
phone_number: "+64270000000" })
authsignal_client.enrol_authenticator(
user_id="1234",
authenticator_payload={"oobChannel": "SMS", "phoneNumber": " 64277770770"},
)
Authsignal::enrolAuthenticator(userId: "1234",
authenticator: array("oobChannel" => "SMS",
"phoneNumber" => "+64270000000"));
var request = AuthenticatorRequest(
UserId: userId,
OobChannel: OobChannel.SMS,
PhoneNumber: "+64270000000");
var response = await authsignal.EnrollVerifiedAuthenticator(request);
Request
userIdstring
The unique ID for this user in your database.
oobChannelenum
The channel of the out-of-band (OOB) authenticator. Possible values are EMAIL_MAGIC_LINK or SMS.
phoneNumberstring | undefined
The user's verified phone number in E.164 format.
emailstring | undefined
The user's verified email address.
{
"oobChannel": "SMS",
"phoneNumber": "+130912341234"
}