Affihub
DocsConceptsEmbed Widget

Embed Widget

Overview

The embed system lets you display partner dashboard data directly inside your own application. Instead of sending partners to portal.affihub.com, you can show their metrics, links, commissions, and payouts within your app's UI.

How it works

  1. Your server requests a short-lived JWT token for a specific partner
  2. Your frontend uses this token to call Affihub's embed API endpoints
  3. The endpoints return the same data as the partner portal

Generating an embed token

From your server, call the embed token endpoint with your API key:

curl -X POST "https://api.affihub.com/api/v1/embed/token" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"partner_id": "par_abc123"}'

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_in": 3600
}

The token is a HS256 JWT valid for 1 hour containing:

{
  "partner_id": "par_abc123",
  "program_id": "prog_xxx",
  "scope": "embed",
  "iat": 1712880000,
  "exp": 1712883600
}
⚠️

Generate tokens server-side only. Never expose your API key in client-side code.

Using the embed token

Pass the JWT as a Bearer token to the embed endpoints:

const res = await fetch("https://api.affihub.com/embed/data/dashboard", {
  headers: {
    Authorization: `Bearer ${embedToken}`,
  },
});
const dashboard = await res.json();

Available endpoints

All endpoints are prefixed with /embed/data/ and accept the JWT Bearer token:

Method Endpoint Description
GET /embed/data/dashboard Partner dashboard metrics
GET /embed/data/links List referral links
POST /embed/data/links Create a referral link
DELETE /embed/data/links/:id Delete a referral link
GET /embed/data/commissions Commission history
GET /embed/data/payouts Payout history

These return the same data as the corresponding /portal/data/* endpoints.

Full integration example

Server (Node.js)

app.get("/api/affiliate-token", async (req, res) => {
  // Identify the logged-in user and find their partner ID
  const partnerId = await getPartnerIdForUser(req.user.id);
 
  const response = await fetch(
    "https://api.affihub.com/api/v1/embed/token",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.AFFIHUB_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ partner_id: partnerId }),
    }
  );
 
  const { token } = await response.json();
  res.json({ token });
});

Client (React)

function AffiliateDashboard() {
  const [stats, setStats] = useState(null);
 
  useEffect(() => {
    async function load() {
      // Get embed token from your server
      const { token } = await fetch("/api/affiliate-token").then(r => r.json());
 
      // Fetch dashboard data from Affihub
      const data = await fetch(
        "https://api.affihub.com/embed/data/dashboard",
        { headers: { Authorization: `Bearer ${token}` } }
      ).then(r => r.json());
 
      setStats(data);
    }
    load();
  }, []);
 
  if (!stats) return <div>Loading...</div>;
 
  return (
    <div>
      <h2>Your Affiliate Dashboard</h2>
      <p>Clicks: {stats.total_clicks}</p>
      <p>Referrals: {stats.total_referrals}</p>
      <p>Earnings: ${(stats.total_earned_cents / 100).toFixed(2)}</p>
    </div>
  );
}

Token refresh

Embed tokens expire after 1 hour. Your frontend should handle token expiration:

async function fetchWithToken(url) {
  let res = await fetch(url, {
    headers: { Authorization: `Bearer ${token}` },
  });
 
  if (res.status === 401) {
    // Token expired — get a new one
    const { token: newToken } = await fetch("/api/affiliate-token")
      .then(r => r.json());
    token = newToken;
 
    res = await fetch(url, {
      headers: { Authorization: `Bearer ${token}` },
    });
  }
 
  return res.json();
}

Security

  • Tokens are signed with HMAC-SHA256 using the EMBED_JWT_SECRET
  • The scope: "embed" claim restricts access to embed endpoints only
  • Tokens are scoped to a single partner — they cannot access other partners' data
  • Token expiry is enforced server-side
  • Always generate tokens server-side to avoid exposing your API key