Authentication
Overview
To use any authenticated API, you must first acquire a valid API token.
Crisisworks uses OAuth2 time-limited access tokens, and offers an auth endpoint to fetch the tokens. MFA is supported using TOTP codes.
Crisisworks account & Duty Status
API users use the same security system as regular users.
It is recommended your API-enabled user account is only used for the API, as such give it a name like API User.
At minimum, this user will require the API User position allocated to it. If you cannot find this position, contact Datalink support.
Ensure this user also has the levels of access required to access the data it needs to view or edit for the specific registers.
If this API user is going to edit data in registers, the API user MUST BE ON DUTY in the event in one or more positions to have access to read or write data in the registers.
If the API user is only updating assets or asset contacts, this data is not in a register, so they don't need to be on duty in any events.
Fetching an authentication token
To fetch an authentication token, call the auth API command and supply the user credentials. Then supply that token to all authenticated API commands using the Authorization header to perform the command on behalf of that user.
Authentication tokens are OAuth2 JWT Access Tokens which expire after a short period. Therefore, for recurring use of the API you should store the username and password securely at your side and call the auth endpoint to fetch a new token.
The API also supports optional TOTP MFA, and you can supply mfaCode at the same time as supplying the username and password. The POSIX authtool utility can be used for this.
To call the auth API, use the following:
POST https://{{host}}/api/json/auth
Accept: application/json
Content-Type: application/json;charset=UTF-8
X-Site: {{site}}
{
"version": "1",
"uuid": "{{uuid}}",
"platform": "Windows",
"name": "Sync asset contacts",
"username": "{{username}}",
"password": "{{password}}",
"mfaCode": "{{mfaCode}}"
}uuid
string
Yes
A unique code that represents the connected device. For devices this is the device's UUID code. For servers, this should be the server's URL.
platform
string
Yes
A freetext string representing the type of connection — e.g. iPad, iPhone, Windows, Linux
version
string
Yes
The version of the client software — e.g. 11
name
string
Yes
The name of the device or integration — e.g. "Integration X"
username
string
Yes
The user username
password
string
Yes
The user's password
mfaCode
string
No
An optional TOTP MFA code
If the user is successfully authenticated, the command returns a JSON object with the following values:
{
"status": 200,
"token": "eyJraWQiOiJCelhSZVwvdW9cL0VUczJjUUJF...",
"type": "accessToken"
}token
string
An OAuth2 Access Token which can be used to perform actions on behalf of a nominated user
status
int
200 for success, 400 for invalid intput, 401 for invalid credentials, 500 for internal server errors
type
string
The type of token returned (this will always be 'accessToken')
If the user's credentials are invalid, the server responds with a 401 HTTP error.
{
"status":401,
"message":"Invalid user, password or mfaCode"
}The access token will have a 1 hour expiry, so you will need to re-authenticate for each session.
Using oauthtool for CLI-based MFA
oauthtool for CLI-based MFAThe oauthtool utility is open source software that can be downloaded using your package manager.
Debian/Ubuntu:
sudo apt install oathtoolMacOS:
brew install oath-toolkitWindows (WSL or Chocolatey):
choco install oath-toolkit
To generate TOTP codes using oathtool, you need the TOTP secret key from Crisisworks. Which can be found by clicking the link "Get code for manual entry" under the QR code when registering the TOTP device.
Next, register the TOTP by entering the following command with your TOTP secret.
oathtool --totp -b "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"Each time this is run, this command will return a six-digit TOTP code. You can run it once and enter into Crisisworks to register the tool with Crisisworks for MFA.
Using an authentication token
Once you have acquired the auth token, you can use it for all APIs via the Authorization header as follows.
GET https://{{host}}/api/json/item/id/1
Accept: application/json
Content-Type: application/json;charset=UTF-8
Authorization: Bearer {{token}}
X-Site: {{site}}Treat your secrets securely
The examples in this guide take shortcuts for readability, with the main one being the storage of secrets in environment variables.
For production use:
API users typically have high degrees of access.
Treat your API user's password and TOTP secret as sensitive secrets.
Don’t hardcode secrets in scripts — use environment variables or secure vault utilities.
For secure storage options, consider using these utilities such as these.
CredentialManager in PowerShell
Secrets Manager on AWS
pass on Linux
Password managers (such as 1Password) also offer CLI tools to store secrets
Examples
Authenticating in BASH
The following simple example shows how to call the auth command from a bash script.
# ---- Configuration ----
HOST="api.cw.crisisworks.com"
SITE="sandbox"
UUID="example-uuid-123"
USERNAME="your.username"
PASSWORD="your.password"
CLIENT_NAME="Test Harness"
# ---- Build JSON payload ----
read -r -d '' PAYLOAD <<EOF
{
"version": "1",
"uuid": "$UUID",
"platform": "curl",
"name": "$CLIENT_NAME",
"username": "$USERNAME",
"password": "$PASSWORD"
}
EOF
# ---- Send authentication request and capture response ----
RESPONSE=$(curl -s -X POST "https://${HOST}/api/json/auth" \
-H "Accept: application/json" \
-H "Content-Type: application/json;charset=UTF-8" \
-H "X-Site: ${SITE}" \
-d "$PAYLOAD")
# ---- Output or process response as needed ----
echo "$RESPONSE"
Authenticating with MFA in BASH
The following shell script illustrates how to authenticate with MFA in bash and curl.
#!/bin/bash
# ---- Configuration ----
HOST="api.cw.crisisworks.com"
SITE="mysite"
UUID="example-uuid-123"
USERNAME="your.username"
PASSWORD="your.password"
TOTP_SECRET="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # Base32-encoded TOTP secret
CLIENT_NAME="Test Harness"
# ---- Generate current MFA TOTP code using oathtool ----
MFA_CODE=$(oathtool --totp -b "$TOTP_SECRET")
# ---- Build JSON payload ----
read -r -d '' PAYLOAD <<EOF
{
"version": "1",
"uuid": "$UUID",
"platform": "curl",
"name": "$CLIENT_NAME",
"username": "$USERNAME",
"password": "$PASSWORD",
"mfaCode": "$MFA_CODE"
}
EOF
# ---- Send authentication request and capture response ----
RESPONSE=$(curl -s -X POST "https://${HOST}/api/json/auth" \
-H "Accept: application/json" \
-H "Content-Type: application/json;charset=UTF-8" \
-H "X-Site: ${SITE}" \
-d "$PAYLOAD")
# --- Extract the token using jq ---
TOKEN=$(echo "$RESPONSE" | jq -r '.token')
# --- Check token was retrieved ---
if [ -z "$TOKEN" ] || [ "$TOKEN" == "null" ]; then
echo "❌ Failed to retrieve token."
exit 1
fiNow you can call the authenticated commands using the token.
# --- Now make some authenticated API calls ---
RESPONSE=$(curl -s -X GET "https://${HOST}/api/json/ping" \
-H "Accept: application/json" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json;charset=UTF-8" \
-H "X-Site: $SITE")
# --- Output the ping response ---
echo $RESPONSE Authenticating with MFA in PowerShell
The following example shows how to authenticate in Windows PowerShell.
# --- Configuration ---
$host = "api.cw.crisisworks.com"
$site = "mysite"
$uuid = "example-uuid-123"
$username = "your.username"
$password = "your.password"
$totpSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # Base32-encoded TOTP secret
$clientName = "Test Harness"
# --- Generate MFA code using oathtool ---
# Ensure oathtool is in PATH (e.g., from Chocolatey or WSL)
$mfaCode = & oathtool --totp -b $totpSecret
# --- Prepare request payload ---
$body = @{
version = "1"
uuid = $uuid
platform = "curl"
name = $clientName
username = $username
password = $password
mfaCode = $mfaCode
} | ConvertTo-Json -Depth 3
# --- Send POST request to fetch token ---
$response = Invoke-RestMethod -Method Post `
-Uri "https://$host/api/json/auth" `
-Headers @{
"Accept" = "application/json"
"Content-Type" = "application/json;charset=UTF-8"
"X-Site" = $site
} `
-Body $body
# --- Extract the token from the response ---
$token = $response.token
# --- Verify token and use it ---
if (-not $token) {
Write-Error "❌ Failed to retrieve token."
exit 1
}Now you can call the other API commands using the token.
# --- Call the authenticated /ping endpoint ---
$pingResponse = Invoke-RestMethod -Method Get `
-Uri "https://$host/api/json/ping" `
-Headers @{
"Authorization" = $token
"Accept" = "application/json"
"Content-Type" = "application/json;charset=UTF-8"
"X-Site" = $site
}
# --- Output the ping response ---
$pingResponseAuthenticating in PHP
// Configuration
$host = "api.cw.crisisworks.com";
$site = "mysite";
$uuid = "example-uuid-123";
$username = "your.username";
$password = "your.password";
$totpSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // Base32-encoded TOTP secret
$clientName = "Test Harness";
// Build the payload
$payload = json_encode([
"version" => "1",
"uuid" => $uuid,
"platform" => "curl",
"name" => $clientName,
"username" => $username,
"password" => $password,
"mfaCode" => $mfaCode,
]);
// Send the request
[$statusCode, $body] = sendByCurl(
'POST',
$url . '/api/json/auth',
[
'Accept' => 'application/json',
'Content-Type' => 'application/json;charset=UTF-8',
],
$payload
);
// Handle the result
if ($statusCode >= 200 && $statusCode < 300) {
$bodyDecoded = json_decode($body, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception("Could not parse JSON during auth registration");
}
} else {
throw new Exception("Got invalid http status code $statusCode during auth registration");
}
if (!($bodyDecoded['token'] ?? null)) {
throw new Exception("Did not receive an auth token during registration");
}
// Use this token for future authenticated calls
$token = $bodyDecoded['token'];The above code uses a function to perform the HTTP call
function sendByCurl(string $method, string $url, array $headers, string $payload = null): array
{
$headersAsStrings = [
'Content-Length: ' . strlen($payload),
];
foreach ($headers as $key => $val) {
$headersAsStrings[] = $key . ': ' . $val;
}
$ch = curl_init();
// configuration directives
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// set 30 second timeout on APIs
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 60000);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 60000);
// set the header, method and payload
curl_setopt($ch, CURLOPT_HTTPHEADER, $headersAsStrings);
if (strtoupper((string)$method) === 'GET') {
// do nothing
} else {
if (strtoupper((string)$method) === 'POST') {
curl_setopt($ch, CURLOPT_POST, 1);
} else {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
}
}
if ($payload) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
}
curl_setopt($ch, CURLOPT_ENCODING, ''); // not gzip, deflate
// Call the URL
$body = curl_exec($ch);
$statusCode = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
// Test the response to ensure valid json
if ($statusCode === 200) {
json_decode($body, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$statusCode = 400; // invalid response data
}
}
curl_close($ch);
return [$statusCode, $body];
}Last updated
Was this helpful?
