Embedding Scoop
Embed Scoop dashboards in your SaaS application using JWT tokens
Developer Guide: Embedding Scoop
Scoop provides a secure, token-based system for embedding analytics dashboards (Canvases) directly into your own SaaS application. This allows you to present Scoop's powerful visualizations to your users without them needing a separate Scoop login.
🚀 How It Works
The embedding system uses JSON Web Tokens (JWT) signed with an RSA key pair (RS256).
- Generate Key Pair: You generate an RSA Key Pair. You keep the Private Key secret on your backend. You upload the Public Key to Scoop Admin.
- Sign Token: When your user visits your app, your backend generates a JWT signed with your Private Key. This token asserts the user's identity and permissions (e.g., "User X has read access to Workspace Y").
- Frontend Handshake: Your frontend passes this token to the Scoop Embed SDK.
- Validation: Scoop verifies the token signature using your uploaded Public Key and grants access.
🔑 1. Token Payload Structure
Your backend must generate a JWT with the following claims:
| Claim | Type | Description |
|---|---|---|
iss | String | Issuer. Must match your Scoop App ID (e.g., my-saas-app). |
sub | String | Subject. The unique User ID in your system (e.g., user_123). |
workspace_id | String | The Scoop Workspace ID this user should access (e.g., W517). |
inbox_id | String | (Optional) The specific Dataset ID to focus on. |
permissions | Array | List of permissions. Usually ["read", "query"]. |
exp | Number | Expiration Time. Unix timestamp. We recommend short-lived tokens (e.g., 1 hour). |
iat | Number | Issued At. Unix timestamp. |
jti | String | JWT ID. A unique nonce to prevent replay attacks. |
Example Payload
{
"iss": "my-saas-app",
"sub": "user_88",
"workspace_id": "W517",
"permissions": ["read", "query"],
"exp": 1735689600,
"iat": 1735686000,
"jti": "unique-request-id-555"
}💻 2. Generating the Token (Python Example)
Here is a Python script using PyJWT to generate a valid token.
import jwt
import time
import uuid
# Your RSA Private Key (PEM format)
PRIVATE_KEY = """-----BEGIN RSA PRIVATE KEY-----
... your private key content ...
-----END RSA PRIVATE KEY-----"""
def generate_embed_token(user_id, workspace_id):
payload = {
"iss": "my-saas-app",
"sub": user_id,
"workspace_id": workspace_id,
"permissions": ["read", "query"],
"iat": int(time.time()),
"exp": int(time.time()) + 3600, # Expires in 1 hour
"jti": str(uuid.uuid4())
}
# Sign with RS256
token = jwt.encode(payload, PRIVATE_KEY, algorithm="RS256")
return token
# Usage
token = generate_embed_token("user_123", "W517")
print(token)🎨 3. Frontend Integration
Once your backend generates the token, pass it to your frontend. Use the Scoop React SDK (or an iFrame) to render the canvas.
import { ScoopCanvas } from '@scoop-analytics/react-embed';
function MyAnalyticsDashboard({ embedToken }) {
return (
<div style={{ height: '800px' }}>
<ScoopCanvas
token={embedToken}
canvasId="C_SALES_DASHBOARD"
width="100%"
height="100%"
/>
</div>
);
}🔒 Security Best Practices
- Never expose your Private Key in frontend code. Token generation must happen server-side.
- Use short expiration times (
exp). If a token is leaked, it should become useless quickly. - Restrict Workspace IDs. Ensure your code only issues tokens for the Workspace ID associated with that specific customer tenant.
Updated about 3 hours ago