Skip to content

Embed Your First Pane

This guide walks through every line needed to embed a live cloud data pane in a web page. By the end, you will have a working HTML page that displays EC2 instances from your AWS account.

What you need:

The complete example

status.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Infrastructure Status</title>

    <!-- 1. LightPane stylesheet -->
    <link rel="stylesheet" href="https://cdn.lightpane.cloud/sdk/v1/clouds-and-light.css">
</head>
<body>

    <h1>EC2 Instances</h1>

    <!-- 2. Access key configuration -->
    <script>
        var serviceDiscoveryConfig = {
            accessKey: 'csl_em_YOUR_ACCESS_KEY_HERE'
        };
    </script>

    <!-- 3. Service request -->
    <script>
        var serviceDiscoveryRequests = serviceDiscoveryRequests || [];
        serviceDiscoveryRequests.push({
            service: 'ec2',
            provider: 'aws',
            region: 'eu-west-2',
            source: 'live',
            attributes: ['name', 'instance_id', 'instance_type', 'state', 'private_ip']
        });
    </script>

    <!-- 4. Target div — the pane renders here -->
    <div data-sd-service="ec2" data-sd-source="live"></div>

    <!-- 5. LightPane SDK scripts (load at end of page) -->
    <script src="https://cdn.lightpane.cloud/sdk/v1/sd-core.js"></script>
    <script src="https://cdn.lightpane.cloud/sdk/v1/sd-fetch.js"></script>
    <script src="https://cdn.lightpane.cloud/sdk/v1/sd-render.js"></script>
    <script src="https://cdn.lightpane.cloud/sdk/v1/sd-format.js"></script>
    <script src="https://cdn.lightpane.cloud/sdk/v1/sd-boot.js"></script>

</body>
</html>

Replace csl_em_YOUR_ACCESS_KEY_HERE with your embed key. Save the file and open it in a browser.

What each part does

1. LightPane stylesheet

<link rel="stylesheet" href="https://cdn.lightpane.cloud/sdk/v1/clouds-and-light.css">

Base styles for pane layout, tables, and status indicators. This is optional — pane components inject their own CSS — but it provides consistent defaults.

2. Access key configuration

<script>
    var serviceDiscoveryConfig = {
        accessKey: 'csl_em_YOUR_ACCESS_KEY_HERE'
    };
</script>

Set this once per page. The SDK reads this config to authenticate API requests using your embed key as a Bearer token.

3. Service request

<script>
    var serviceDiscoveryRequests = serviceDiscoveryRequests || [];
    serviceDiscoveryRequests.push({
        service: 'ec2',
        provider: 'aws',
        region: 'eu-west-2',
        source: 'live',
        attributes: ['name', 'instance_id', 'instance_type', 'state', 'private_ip']
    });
</script>

Each push() call adds a service to the discovery batch. The SDK sends all requests in a single API call when the page loads.

Property Description
service The service to discover. See the Service Catalogue for all options.
provider aws, gcp, or azure.
region The cloud region to query.
source live for real-time data from your cloud account.
attributes Which columns to display. Omit to show all available attributes.

4. Target div

<div data-sd-service="ec2" data-sd-source="live"></div>

The SDK finds this div by matching data-sd-service and data-sd-source to the service request. It replaces the div contents with a rendered data table.

5. SDK scripts

<script src="https://cdn.lightpane.cloud/sdk/v1/sd-core.js"></script>
<script src="https://cdn.lightpane.cloud/sdk/v1/sd-fetch.js"></script>
<script src="https://cdn.lightpane.cloud/sdk/v1/sd-render.js"></script>
<script src="https://cdn.lightpane.cloud/sdk/v1/sd-format.js"></script>
<script src="https://cdn.lightpane.cloud/sdk/v1/sd-boot.js"></script>

Load these at the end of the page (or with defer). The scripts execute in order:

Script Purpose
sd-core.js Configuration and request registry
sd-fetch.js API communication — sends the batch request with Bearer auth
sd-render.js Table rendering — converts JSON responses into HTML tables
sd-format.js Data formatting — dates, status badges, IP addresses
sd-boot.js Bootstrap — triggers fetch and render when the DOM is ready

Troubleshooting

CORS error in browser console

Access to fetch at 'https://api.lightpane.cloud/...' has been blocked by CORS policy

Check that the domain you are serving the page from is listed in the allowed_origins constraint on your access key. If you are testing locally, add http://localhost:8080 (or your local port) to allowed origins.

401 Unauthorized

The access key is invalid, expired, or revoked. Check that:

  • The key was copied correctly (no extra spaces or line breaks)
  • The key has not expired — check the expiry in Access Keys on your account
  • The key has not been revoked

403 Forbidden

A constraint check failed. The API response body contains the specific reason:

Error message Cause Fix
"Origin not permitted for this token" The page domain is not in allowed_origins Add the domain to allowed origins on the key
"IP address not permitted for this token" The client IP is not in allowed_ips Update the allowed IPs
"Referer header required for this token" require_referer is enabled but no Referer header was sent Serve the page from a web server (not file://)
"Service X not permitted by this token" The key does not include this service Create a new key with the service included, or use a key scoped to all services

Pane renders but shows no data

The API returned zero resources. This is normal if:

  • The region has no resources of that type (e.g. no EC2 instances in us-west-1)
  • The cloud account has no resources of that type

Check the browser network tab — the API response will show "resources": [] with "success": true.

Pane does not render at all

Check that:

  • The data-sd-service value on the div matches the service value in the request
  • The data-sd-source value on the div matches the source value in the request
  • All five SDK scripts are loading (check the network tab for 404 errors)
  • The serviceDiscoveryConfig and serviceDiscoveryRequests scripts appear before the SDK scripts in the HTML

What next