How to Set Up Signed Embed

Seamlessly Integrate notebook into external services.

How to Set Up

Prepare signed embed

  • Prepare API Key and Secret

    • Open Workspace settings and click menu API Keys.

    • Click the Add API Key button and create new API Key.

    • Make a note of the API Key and API Secret (they will be used later for API calls).

  • Open the notebook

    • Open the notebook you want to share.

    • Click the Share button in the header and select Signed Embed tab.

  • Publish signed embed

    • Choose the pages you want to publish.

    • Set the options for publishing.

    • Click the Publish button.

  • Configure signed embed settings.

    • Add API Key to use in Permitted API Keys section.

    • If you want to set parameter values when issuing a token, configure them in the Server-side parameters section.

Issue token from server

  • The following API is used to issue a token

    • The required arguments for calling the API can be found on the Setup guide tab.

    • Perform the API call on the server side to prevent the API Secret from being exposed externally.

    • Issue a token for each user session, and do not reuse it (it expires after 1 hour by default).

post
Body
api_keystring · min: 24 · max: 24Required

API Key. Can be issued from 'Workspace settings > API Keys'

Example: 6729a28bc7100424ad4e2e5d
api_secretstring · min: 32 · max: 32Required

API Secret. Generated when issuing 'API Key'

Example: c711defdff5f4e3e8e53d4f408579b9a
integration_idstring · min: 24 · max: 24Required

Integration ID. Can be obtained from the signed embed settings

Example: 671ef14b0d08cf6c657df7da
page_idstring · min: 24 · max: 24Required

Page ID to be displayed in the notebook. Can be obtained from the signed embed settings

Example: 671ecbbf2990c63fea3b3a26
token_user_idstring · min: 1Required

Specify the user ID within the application where the notebook is embedded. Ensure that the token can uniquely identify the token user for security reason.

expires_ininteger · min: 1 · max: 86400Optional

Token expiration time in seconds. Default is 3600 seconds (1 hour)

Example: 3600
cache_max_ageinteger · max: 86400Optional

Cache max age in seconds. Default is 86400 (24 hours)

Example: 86400
Responses
200
Generated token
application/json
post
POST /api/notebook/issueToken HTTP/1.1
Host: api.codatum.com
Content-Type: application/json
Accept: */*
Content-Length: 313

{
  "api_key": "6729a28bc7100424ad4e2e5d",
  "api_secret": "c711defdff5f4e3e8e53d4f408579b9a",
  "integration_id": "671ef14b0d08cf6c657df7da",
  "page_id": "671ecbbf2990c63fea3b3a26",
  "token_user_id": "text",
  "params": [
    {
      "param_id": "6722c7061b02448a4056d84d",
      "param_value": "\"Hello world\""
    }
  ],
  "expires_in": 3600,
  "cache_max_age": 86400
}
{
  "token": "(Generated-token)"
}

Embed iframe

Embed HTML into your service using the Signed Embed URL. You can set client-side options along with the token. Please check the Setup guide or Appendix for details.

  1. Create an iframe element with Signed Embed URL as the src attribute

  2. Wait for a {type: "READY_FOR_TOKEN"} message from the iframe via postMessage

  3. Send {type: "SET_TOKEN", token: "{{ TOKEN_HERE }}", ...clientSideOptions} message back to the iframe via postMessage

    • clientSideOptions allows you to set initial values for parameters. Please check the Appendix for details.

// Sample

const NOTEBOOK_ORIGIN = 'https://app.codatum.com';
const ingegrationUrl = 'https://app.codatum.com/protected/workspace/xxx/notebook/xxx?theme=LIGHT&locale=en-US';
const token = '{{ TOKEN_HERE }}';  // Issued token here
const clientSideOptions = {
  displayOptions: {
    sqlDisplay: "SHOW" | "RESULT_ONLY" | "HIDE",  // 
    expandParamsFormByDefault: false
  },
  params: [
    {
      param_id: "686d820209183cfa1045cb81",
      param_value: "\"Hello codatum\""  // JSON.stringify("Hello codatum")
    },
  ]
};

// Store iframe window reference
let notebookWindow: Window | null = null;

// Create and insert iframe
function createDashboard(containerId: string) {
  const container = document.getElementById(containerId);
  if (!container) return;

  const iframe = document.createElement('iframe');
  iframe.src = ingegrationUrl;
  iframe.allow = 'fullscreen;clipboard-write';
  container.appendChild(iframe);
  notebookWindow = iframe.contentWindow;
}

// Handle messages from iframe
function handleMessage(event: MessageEvent<{type: 'READY_FOR_TOKEN'}>): void {
  // Verify origin and source
  if (event.origin !== NOTEBOOK_ORIGIN || event.source !== notebookWindow) {
    return;
  }

  // Send token when iframe is ready
  if (event.data.type === 'READY_FOR_TOKEN') {
    const message = {
      type: 'SET_TOKEN',
      token: token,
      ...clientSideOptions,
    };    
    notebookWindow?.postMessage(message, NOTEBOOK_ORIGIN);
  }
}

function cleanup() {
  window.removeEventListener('message', handleMessage);
  notebookWindow = null;
}

export function createEmbeddedNotebook(containerId: string) {
  window.addEventListener('message', handleMessage);
  createDashboard(containerId);
  return cleanup;
}

Pattern2. Passing token via URL parameter

  1. Append token as a query parameter to the Signed Embed URL (?token=xxx)

  2. Optionally, add clientSideOptions as a query parameter (The value should be encodeURIComponent(JSON.stringify(value)) for each key)

  3. Create an iframe element with the modified URL as the src attribute

// URL generation sample code
const signedEmbedUrl = 'https://app.cdm.test/protected/workspace/6653ebab5a1acaa5bd5422a5/notebook/686d823e586c271be1472207?theme=LIGHT&locale=ja';
const token = '{{ TOKEN_HERE }}';
const clientSideOptions = {
  displayOptions: {
    sqlDisplay: "RESULT_ONLY",
    expandParamsFormByDefault: false
  },
  params: [
    {
      param_id: "686d820209183cfa1045cb81",
      param_value: "\"Hello codatum\""  // JSON.stringify("Hello codatum")
    },
  ]
};

const url = new URL(signedEmbedUrl);
url.searchParams.append('token', token);
for (const [key, value] of Object.entries(clientSideOptions)) {
  const encodedValue = encodeURIComponent(JSON.stringify(value));
  url.searchParams.append(key, encodedValue);
}

const generatedUrl = url.toString();
<!-- Sample HTML -->
<iframe src="{{ GENERATED_URL_HERE }}" allow="fullscreen; clipboard-write" />

Appendix

Client-side options

The client-side options (clientSideOptions) that can be passed when embedding the iframe are as follows:

key
description

displayOptions.sqlDisplay

Specifies the SQL display option.

"SHOW": Show the 'SQL blocks' and the underlying generated SQL queries "RESULT_ONLY": Hide SQL part inside the 'SQL blocks' and the underlying generated SQL queries "HIDE": Hide the 'SQL blocks' and the underlying generated SQL queries

displayOptions.hideParamsForm

Specifies true to hide the parameter form.

displayOptions.expandParamsFormByDefault

Specifies true to expand the parameter form by default. If hideParamsForm is true, it is ignored.

params[]

Specifies the initial value for client-side parameters. Client-side parameters that are not specified here will use the value set when the signed embed is published as the initial value.

params[].param_id

Specifies the parameter ID.

params[].param_value

Specifies the parameter value. The parameter value should be specified as a string by wrapping it with JSON.stringify().

You can use the default value of the parameter set when the signed embed is published by specifying "_RESET_TO_DEFAULT_" as the parameter value.\ The default value is resolved based on the relative date.

params[].is_hidden

Specifies true to hide the parameter input form. If hideParamsForm is true, it is ignored.

The following is a sample of the client-side options.

const clientSideOptions = {
  displayOptions: {
    sqlDisplay: "RESULT_ONLY",
    hideParamsForm: true
  },
  params: [
    {
      param_id: "686d820209183cfa1045cb81",
      param_value: "\"Hello codatum\""  // JSON.stringify("Hello codatum")
    },
    {
      param_id: "686d820209183cfa1045cb82",
      param_value: "_RESET_TO_DEFAULT_"  // Use the default value set when the signed embed is published
    },
    {
      param_id: "686d820209183cfa1045cb83",
      param_value: "\"2025-01-01\""  // JSON.stringify("2025-01-01")
    },
    {
      param_id: "686d820209183cfa1045cb84",
      param_value: "[\"2025-01-01\", \"2025-01-02\"]"  // JSON.stringify(["2025-01-01", "2025-01-02"])
    },
    {
      param_id: "686d820209183cfa1045cb85",
      param_value: "123"  // JSON.stringify(123)
    }
  ]
};

Message list

When implementing the pattern 1 for embedding the iframe, you can exchange messages using the postMessage function of the iframe. The following is a list of messages that can be sent and received.

Messages to the iframe

type
description

SET_TOKEN

Set the authentication token and start rendering notebook. This message must be sent after receiving the READY_FOR_TOKEN message.

This message can be sent multiple times to the same iframe, which will cause the iframe to reload internally with the new token and parameters.

The params field allows you to set initial values for parameters that are not fixed or defaulted on the server side. This is useful when you want to provide parameter input fields in your application.

{
    type: "SET_TOKEN",
    token: "...",
    displayOptions: {
      "sqlDisplay": "SHOW",
      "expandParamsFormByDefault": false
    },
    params: [
      {
        param_id: "662a5e9fce6482ca0231f06f",
        param_value: "\"Hello codatum\""
      }
    ]
  }
  

Messages from the iframe

type
description

READY_FOR_TOKEN

Notification that the notebook is ready to receive the token.

{type: "READY_FOR_TOKEN"}

PARAM_CHANGED

Sent each time the user modifies a parameter within the notebook.

{
  type: "PARAM_CHANGED",
    params: [
        {
            param_id: "662a5e9fce6482ca0231f06f",
            param_value: "\"Hello codatum\""
        },
    ]
}

EXECUTE_SQLS_TRIGGERED

Sent when 'Run all' is executed within the notebook.

{
    type: "EXECUTE_SQLS_TRIGGERED",
    params: [
        {
            param_id: "662a5e9fce6482ca0231f0aa",
            param_value: "123"
        }
    ]
}

Frequently Asked Questions

Getting "Missing param: xxx" error when issuing a token

  • To issue a token, all server-side parameters must be included in the request

  • If a parameter with the ID "xxx" is not included in the request, this error will occur

Getting "The following parameters must be set by the server" error when sending "SET_TOKEN" message

  • You're trying to modify server-side parameters via PostMessage

  • To modify server-side parameters, new token issuance is required

"SET_TOKEN" message not reflected

  1. Check if the parameter is not a server-side parameter

  2. Verify param_value is in the correct JSON string format

  3. Confirm param_id matches the actual parameter ID

Last updated

Was this helpful?