Skip to content

Integrate AgileBrain Exercises

Run AgileBrain exercises inside your product with a link, an embedded frame, or a pop-up, and receive each participant's scores on your server by webhook.

Code samples on GitHub →

Integration Points hub.agilebrain.com

LINK/run/{your-exercise-slug}Participant link, frame, or pop-up
EVENTsession.createdSession started
EVENTsession.completedScores sent to your server

How an Integration Works

AgileBrain hosts and scores the exercise. Your product sends participants to it and receives the result.

AgileBrain

Set Up the Exercise

AgileBrain sets up an exercise for your organization and sends you its link and deployment ID.

Your product

Open the Exercise

Send each participant to your exercise link with a participant ID.

AgileBrain Hub

Run and Score

The Hub runs the exercise and scores the session.

Your server

Receive Scores

The Hub posts session.completed to your webhook.

Run the Exercise

Use any of the three options below. The Hub runs the full participant experience.

  • Add a participant ID to the link as ?sessionId=. The Hub returns it as session.customId in every webhook.
  • Generate a new random value, such as a UUID, for each participant and exercise, and map it to the participant on your server. Never use an email address, a name, or a sequential ID.
  • Each participant ID can be used for one completed exercise.
  • Scores arrive on your server by webhook.
  • Give AgileBrain a return URL during onboarding and participants land there when they finish.
  • On phones, open the direct link so the exercise has the full screen.
embed.html
<!-- Direct link --><a href="https://hub.agilebrain.com/run/your-exercise-slug?sessionId=PARTICIPANT_ID">Start the exercise</a> <!-- Embedded frame --><iframesrc="https://hub.agilebrain.com/run/your-exercise-slug?sessionId=PARTICIPANT_ID"width="100%" height="700"style="border: none; border-radius: 8px;"allow="fullscreen"title="AgileBrain exercise"></iframe> <!-- Pop-up window (opens from a click) --><button type="button" onclick="window.open('https://hub.agilebrain.com/run/your-exercise-slug?sessionId=PARTICIPANT_ID','agilebrain', 'width=900,height=760')">Start the exercise</button>

Webhook Events

AgileBrain turns on the webhook for your organization during onboarding. The Hub then posts each session event to your server as JSON.

  • session.created fires when a session starts and carries no scores. session.completed fires when the session is scored.
  • One webhook receives events for every exercise in your organization. Filter on event and session.deploymentId.
  • Keep your receiver available and respond with any 2xx status within 10 seconds. Store the payload and process it after you respond.
  • Keep your webhook path secret and accept only participant IDs your server issued.

Scores

needScores maps each score name to a number. Treat the keys as opaque and do not assume a fixed list. Score definitions come with onboarding.

session.completed
POST https://your-server.example.com/agilebrain/<unguessable-path>Content-Type: application/json {"event": "session.completed","sentAt": "2026-01-15T14:30:00.000Z","session": {"customId": "3f6c1e2a-9b7d-4c1e-8a52-0d4f7b9e6a10","status": "COMPLETED","deploymentId": "REPLACE-WITH-DEPLOYMENT-ID","needScores": {"exampleScore": 0.61,"anotherScore": 0.48}}}

Payloads can include more fields than shown, such as participant details your exercise collects. Ignore fields you do not use.

Receive Your First Webhook

This Node.js receiver handles AgileBrain webhooks. It needs Node 18 or later and has no dependencies.

  • Save it as receiver.mjs and run node receiver.mjs.
  • Run the test delivery. Use the same path and deployment ID in both files. The receiver prints the participant ID and the scores.
  • Set WEBHOOK_PATH to a random path and DEPLOYMENT_ID to the value from onboarding, then replace issuedByYou and saveScores with your own lookup and storage.
  • Give AgileBrain the public HTTPS address of your receiver, including its path.
test-delivery.sh
curl -sS -o /dev/null -w 'HTTP %{http_code}\n' -X POST http://localhost:3000/agilebrain/REPLACE-WITH-RANDOM-PATH \-H "Content-Type: application/json" \-d '{"event":"session.completed","sentAt":"2026-01-15T14:30:00.000Z","session":{"customId":"3f6c1e2a-9b7d-4c1e-8a52-0d4f7b9e6a10","status":"COMPLETED","deploymentId":"REPLACE-WITH-DEPLOYMENT-ID","needScores":{"exampleScore":0.61}}}'
receiver.mjs
import { createServer } from 'node:http';

const PORT = 3000;
const WEBHOOK_PATH = '/agilebrain/REPLACE-WITH-RANDOM-PATH';  // keep secret
const DEPLOYMENT_ID = 'REPLACE-WITH-DEPLOYMENT-ID';           // from onboarding

createServer((req, res) => {
  const path = new URL(req.url, 'http://localhost').pathname;
  if (req.method !== 'POST' || path !== WEBHOOK_PATH) {
    res.writeHead(404).end();
    return;
  }

  let body = '';
  req.setEncoding('utf8');
  req.on('data', (chunk) => { body += chunk; });
  req.on('end', () => {
    res.writeHead(204).end(); // acknowledge first, then process

    let payload;
    try { payload = JSON.parse(body); } catch { return; }
    if (!payload || typeof payload !== 'object') return;

    const { event, session } = payload;
    if (session?.deploymentId !== DEPLOYMENT_ID) {
      console.log('Ignored delivery for deployment', session?.deploymentId);
      return;
    }

    if (event === 'session.completed') {
      // customId is the participant ID you passed as ?sessionId=
      if (!issuedByYou(session.customId)) return;
      saveScores(session.customId, session.needScores);
    }
  });
}).listen(PORT, () => console.log(`Listening on ${PORT}`));

function issuedByYou(participantId) {
  return true; // replace with a lookup of the IDs your server issued
}

function saveScores(participantId, scores) {
  console.log(participantId, scores); // replace with your storage
}

Request Access

AgileBrain grants access to approved partners under an agreement. Leave your details and our team will follow up.

Onboarding Includes

  • Your exercise link and deployment ID
  • Webhook setup
  • Score definitions

Planning a Partnership?

Talk to us about integration options and terms.

Talk to Us