CONTEXT SDK

Embed your Feedback Agent.

Securely connect each signed-in product user to an isolated feedback history, with rich product and runtime context.

01

Secure authentication flow

The Agent ID is public. The Agent Key is a long-lived server credential and must never enter HTML, browser JavaScript, URLs, mobile bundles, analytics, or logs. Your backend exchanges it for a user-scoped token that expires after 15 minutes.

1 · Your backendAgent Key → POST /api/agent/auth/token2 · RedFeedSigned token: workspace + agent + user + expiry3 · Your browserSDK receives only the short-lived user token4 · Every requestAuthorization: Bearer <user-token>

RedFeed ignores browser-supplied identity fields. Conversation ownership always comes from the signed token, so users in the same application cannot read or modify one another's feedback.

02

Create a token on your backend

Add an authenticated endpoint to your application. Use the signed-in user's stable internal ID. Store the Agent Key in your server secret manager.

// Your application backend
app.post("/api/redfeed-token", requireUser, async (req, res) => {
  const response = await fetch("https://redfeed.io/api/agent/auth/token", {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "authorization": `Bearer ${process.env.REDFEED_AGENT_KEY}`
    },
    body: JSON.stringify({
      agentId: "agt_your_agent_id",
      userId: req.user.id,
      email: req.user.email,
      origin: "https://app.example.com"
    })
  });

  if (!response.ok) return res.status(502).json({ error: "Token exchange failed" });
  res.json(await response.json());
});

Do not accept userId or email from this endpoint's request body. Read them from your authenticated server session.

03

Web SDK

The SDK calls your backend for a short-lived token and passes it directly to the RedFeed iframe without placing it in the URL.

<script src="https://redfeed.io/sdk/redfeed.js?v=2"></script>
<div id="redfeed-agent" style="min-height:720px"></div>
<script>
  const feedback = RedFeed.mount({
    target: "#redfeed-agent",
    agentId: "agt_your_agent_id",
    getUserToken: async () => {
      const response = await fetch("/api/redfeed-token", { method: "POST" });
      if (!response.ok) throw new Error("Unable to start feedback");
      return (await response.json()).token;
    },
    context: {
      company: currentUser.company,
      plan: currentUser.plan,
      appVersion: APP_VERSION,
      page: location.href
    }
  });
</script>

Open as a modal

RedFeed.open({
  agentId: "agt_your_agent_id",
  getUserToken: () => fetchUserToken(),
  context: getCurrentContext()
});

04

Context fields

Send only fields your privacy policy permits. userId and email are always replaced by verified token claims. Unknown non-identity fields are preserved as metadata.

Verified identityuserId, email · token claims onlyAccountcompany, plan, arr, signedUpAtProductpage, appVersion, osVersion, device, locale, experimentRuntime and AItraceId, errorCode, feature, model, promptVersion

05

Single-page applications

Keep the returned instance and update non-identity context when the route, plan, trace, or application state changes. Refresh the token after your signed-in user changes.

feedback.setContext({
  page: location.href,
  feature: route.name,
  traceId: telemetry.currentTraceId()
});

await feedback.setUserToken(await fetchUserToken());

06

iOS and Android

Open a URL containing only the public Agent ID inside your WebView. Mint the short-lived token through your authenticated backend, then inject it after the page loads. Restrict the message target to https://redfeed.io.

https://redfeed.io/widget/?agentId=agt_your_agent_id

Message payload:

{
  "type": "redfeed:auth",
  "userToken": "short_lived_user_token",
  "context": { "appVersion": "4.2.0" }
}

07

Agent API

Native and server-rendered integrations use the same user token. Send the public Agent ID in the body or query and the token in the authorization header.

StartPOST /api/agent/sessionMessagePOST /api/agent/messageFinishPOST /api/agent/finishUser historyGET /api/agent/history?agentId=...
Authorization: Bearer short_lived_user_token
Content-Type: application/json

{
  "agentId": "agt_your_agent_id",
  "context": { "feature": "checkout" }
}

Session, message, finish, and history operations enforce the token's user ownership. Workspace administrators continue to see all feedback for their own enterprise in the authenticated RedFeed console.