Buddy Docs Open Studio

Identity Callback URL

The most private option: no user data is embedded in the widget at all. When a session begins, Buddy POSTs the session id to your endpoint, signing the request so you can verify it really came from the platform. You respond with the user's attributes.

Flow

  1. A session starts in the widget (no user token needed).
  2. Buddy POSTs { sessionId, agentId, timestamp } to your callback URL.
  3. The request carries an X-Platform-Signature HMAC of the exact body, using your callback secret.
  4. You verify the signature, look up the user for that session, and return their attributes.

The request Buddy sends

POST /buddy/identity HTTP/1.1
Content-Type: application/json
X-Platform-Signature: <hex HMAC-SHA256 of the raw body>

{ "sessionId": "sess_…", "agentId": "agt_…", "timestamp": 1717000000 }

Response shape

Return JSON with at least a userId. Optional email, role and a customAttributes object are mapped through.

{
  "userId": "user_123",
  "email": "ada@example.com",
  "role": "customer",
  "customAttributes": { "plan": "pro", "lifetimeValue": 4200 }
}

Verify the signature

// Express — verify the request really came from Buddy.
import crypto from 'node:crypto';

app.post('/buddy/identity', express.text({ type: '*/*' }), (req, res) => {
  const expected = crypto
    .createHmac('sha256', process.env.BUDDY_CALLBACK_SECRET)
    .update(req.body)            // the raw body bytes, verbatim
    .digest('hex');
  const got = req.get('X-Platform-Signature') || '';
  if (got.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) {
    return res.status(401).end();
  }
  const { sessionId } = JSON.parse(req.body);
  const user = lookupUserForSession(sessionId);
  res.json({ userId: user.id, email: user.email, role: user.role });
});

Troubleshooting

CodeMeaning & fix
AUTH_CALLBACK_TIMEOUTYour endpoint didn't respond in time. Buddy retries once, then falls back to anonymous. Keep the handler fast.
AUTH_CALLBACK_FAILEDNon-2xx response or unreachable URL. Confirm the URL is public HTTPS.
AUTH_CALLBACK_BAD_RESPONSEResponse had no userId. See the response shape.