XUND
Getting started

Authentication

Create the auth code the app needs, on your server, from your Client Id and API key.

The Symptom & Illness Check App needs a short-lived auth code every time it is loaded. Your server creates it from your Client Id and API key and hands it to the page that embeds the app.

Working examples

Complete, runnable PHP, .NET, and Android projects are in the frontend integration examples on GitHub.

Creating the auth code

  1. Hash your API key with SHA-256 and write the hash as lowercase hex.
  2. Choose a state: a UUID. Use a new random one, or — if you want it back in webhooks — a UUID you generate and map to a session or user on your server; see Webhooks and your own identifier.
  3. Compute secretHash: HMAC-SHA-256 of state + clientId, with the lowercase hex string from step 1 as the key. Send the result as lowercase hex.
  4. Call GET https://login.xund.solutions/api/authorize?clientId=…&secretHash=…&state=… and read authCode from the JSON response.

Node.js:

import { createHash, createHmac, randomUUID } from 'node:crypto'

export async function createAuthCode({ clientId, apiKey, state = randomUUID(), returnStateInWebhook = false }) {
  const hashedApiKey = createHash('sha256').update(apiKey).digest('hex')
  const secretHash = createHmac('sha256', hashedApiKey).update(state + clientId).digest('hex')
  const url = new URL('https://login.xund.solutions/api/authorize')
  url.search = new URLSearchParams({ clientId, secretHash, state, ...(returnStateInWebhook && { scope: 'state' }) })
  const response = await fetch(url)
  if (!response.ok) {
    throw new Error(`authorize failed with ${response.status}`)
  }
  const { authCode } = await response.json()
  return { authCode, state }
}

PHP:

function createAuthCode(string $clientId, string $apiKey, string $state, bool $returnStateInWebhook = false): string {
    $hashedApiKey = hash('sha256', $apiKey);
    $secretHash = hash_hmac('sha256', $state . $clientId, $hashedApiKey);
    $query = ['clientId' => $clientId, 'secretHash' => $secretHash, 'state' => $state];
    if ($returnStateInWebhook) {
        $query['scope'] = 'state';
    }
    $response = file_get_contents('https://login.xund.solutions/api/authorize?' . http_build_query($query));
    if ($response === false) {
        throw new RuntimeException('authorize request failed');
    }
    return json_decode($response)->authCode;
}

The response looks like this:

{ "authCode": "…", "state": "5e93d7a1-f240-43b5-8937-33419ea9cb6a" }

Pass authCode to the embed.

Keep the API key on your server

Never ship the API key to a browser or a mobile app — anyone who extracts it can create auth codes for your account. The page or app asks your own backend for a fresh authCode, and only your backend holds the API key. The same rule applies to the API; see Where your credentials live.

Sessions

Create one auth code for each page load. The app's session ends when its token expires; a new page load with a new auth code starts a new session.

Last updated on

On this page