Signed Embedding
Signed embedding provides a seamless and secure way to integrate Zenlytic content into your application using dynamically generated signed URLs. This method is especially suitable for scenarios where smooth experience and controlled access to analytics data are paramount. The signed URL ensures that each embedded analytics instance is secure, time-limited, and tailored to individual user permissions.
#
Use CasesSigned embedding is particularly useful in:
- External-facing applications where enhanced customization is crucial.
- Situations where access to analytics needs to be controlled on a per-session basis.
- Environments where analytics content needs to be securely shared to the user base of an application.
#
Implementation GuideSigned URl Security
Protect this signed URL as you would an access token or password credentials - do not write it to disk, do not pass it to a third party, and only pass it through a secure HTTPS encrypted transport
Generating Signed URLs
API Request for a Signed URL
- Make a request to the API endpoint to obtain a signed URL.
- Include necessary authentication credentials (client_id and client_secret you receive from your Zenlytic representative) and user-specific parameters in the request.
- See details in API Reference below
Parameters for iframe
- Signed URL retrieved in the previous step
- Pass the url to the iframe like in the examples below
Pass the url to the iframe:
<iframe src="<MY_SIGNED_URL>" style="height:700px;width:100%;border:none;" title="Dashboard" description="Zenlytic Dashboard"></iframe>
To request a chat embedded url, you'd change the
target_url
tohttps://app.zenlytic.com/chat
<iframe src="<MY_SIGNED_URL>" style="height:700px;width:100%;border:none;" title="Dashboard" description="Zenlytic Dashboard"></iframe>
Handling URL Expiry
- Implement logic to handle the expiry of a signed URL, refreshing the url you receive from the endpoint.
#
API ReferenceEndpoint
- URL:
https://api.zenlytic.com/api/v1/embed/signed_url
- Purpose: To generate a signed URL for embedding analytics.
Request
- Method:
POST
- Headers: Include basic authentication header. You will need to base64 encode your credentials in the form
client_id:client_secret
, then pass under theAuthorization
header with theBasic
prefix. Python code to create the header is given below:
import base64
def create_basic_auth_header(client_id, client_secret): # Concatenate the client ID and client secret credentials = f"{client_id}:{client_secret}" # Encode the credentials using base64 credentials_encoded = base64.b64encode(credentials.encode()).decode() # Create the Basic Auth header auth_header = f"Basic {credentials_encoded}" return auth_header
# Example usageclient_id = "your_client_id_here"client_secret = "your_client_secret_here"auth_header = create_basic_auth_header(client_id, client_secret)print(auth_header)
Body Parameters:
Structure
external_user_id
: (Required) The identifier of the user for whom the analytics is being embedded. This is the user's unique identifier in your system.target_url
: (Required) The complete url in your Zenlytic interface for the content you want to embed. For example,https://app.zenlytic.com/dashboards/73b64533-c027-43b8-b8a8-6069534235413
orhttps://app.zenlytic.com/chat
.user_attributes
: (Optional) The user_attributes to use when applying row and column level permissions for this user. If you have already requested for a givenexternal_user_id
then make another request with differentuser_attributes
passed, the most recent user_attributes will be used. The format of user attributes is:
{ "department": "Marketing", "account_id": 1327789}
extra_prompt_context
: (Optional) This is extra context added to Zoë to make your user's experience customized. You could say things like "Only speak to me in French" or "Always address me as Doctor." This is only visible to Zoë, not to the user.chat_header_message
: (Optional) This is the welcome header that Zoë shows to the user. For example, you could have Zoë say "Welcome Paul," or send " " to not display this value.chat_welcome_message
: (Optional) This is the initial message that Zoë shows to the user. For example, you could have Zoë say "How can I help you find your data today?"chat_initial_prompts
: (Optional) This is an array of initial prompts to display in Zoë. This helps a user see example questions they can ask. For example, ["What were sales in 2023?", "How many customers joined in the last week?"]first_name
: (Optional) The first name of the user in your system. Defaults to 'Embedded'.last_name
: (Optional) The last name of the user in your system. Defaults to 'User'.role_name
: (Optional) The role you want the user to assume in the application. Options areembed
andembedded_with_scheduling
Defaults toembed
. See user role details for more information
Example Body Parameters
{ "external_user_id": "237645tgfghe6", "target_url": "https://app.zenlytic.com/chat", "user_attributes": { "account_id": 1327789 }, "extra_prompt_context": "Always address me in French", "chat_header_message": "Welcome Paul,", "chat_welcome_message": "How can I help you today?", "chat_initial_prompts": ["What are my sales in the last month?", "How many customers joined in the last week?"], "role_name": "embed"}
- Example Request
import requests
data = { "external_user_id": "237645tgfghe6", "target_url": "https://app.zenlytic.com/chat", "user_attributes": { "account_id": 1327789 }}headers = { "Authorization": "Basic mdfiothisisanexampleqewnqjo3eiqjdfqi3oirfqqj301r0j2oqfioewiq3i=", "Content-Type": "application/json"}url = "https://api.zenlytic.com/api/v1/embed/signed_url"requests.post(url, headers=headers, data=data)
Response
Structure:
signed_url
: The generated URL for embedding.expires_in
: Expiry in seconds from now.
Example Response:
{ "signed_url": "https://app.zenlytic.com/embed/chat?userID=12345&userJWT=abc123", "expires_in": 86400}
Error Handling
- Common Errors:
- Authentication failures. This will occur if you do not pass the client_id and client_secret correctly, or if those credentials are invalidated.
- Missing or invalid parameters.
- Server-side errors in URL generation.
#
CustomizationTo dynamically change the database chosen in the query, you can set the zenlytic_connection_database
user attribute. See additional docs on the behavior of this attribute here.
#
Communication#
Zenlytic Embedded iframe EventsZenlytic provides an event system for embedded iframes to communicate with the parent application. Currently, we support one event: questionRunFinished
. Additional events can be added upon request.
#
Listening for EventsTo handle events from the Zenlytic iframe, add an event listener to the window object. Here's an example of how to properly listen for and handle events:
window.addEventListener('message', (message) => { if (message.origin !== 'https://app.zenlytic.com') { // Ignore messages not from Zenlytic return; } switch (message.data.type) { case 'questionRunFinished': console.log(`Question ${message.data.detail.id} finished running!`); // Handle the event here break; // Add cases for future events as they become available }});
#
Supported EventsquestionRunFinished
This event is triggered when a question in the embedded iframe finishes running.
Event details include:
id: The ID of the question that finishedslices: An array of column IDs representing slices in the questionmetrics: An array of column IDs representing metrics in the questionfilters: An array of filters applied to the questiontime_periods: The current and compare time periods for the questionrow_limit: The row limit set for the questionsql: The SQL query used to generate the question resultcompare_query: The SQL query used for comparison (if applicable)
#
Security NoteAlways verify that the origin of the message is https://app.zenlytic.com
(or your custom domain, if you are an enterprise customer) before processing the event to ensure the message comes from Zenlytic.
For any questions or requests for additional events, please contact Zenlytic support.
#
Troubleshooting- Invalid URL Errors: Ensure all required parameters are correctly included in the API request.
- Expired URL Access Attempts: Implement automatic URL regeneration or user prompts for re-authentication.
- Access Denied Errors: Verify user permissions and roles to ensure they align with the access rights of the analytics content.