> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.athenaintel.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.athenaintel.com/_mcp/server.

# Embed Athena Assets

> Render native Athena assets inside your application

Embed a native Athena asset in your application so users can view—and, where supported, edit—it without leaving your product. `AthenaAssetEmbed` accepts an asset ID and automatically renders the appropriate Athena viewer.

> **Note**
>
> Embedding renders an asset's Athena interface. If you only need to read or update spreadsheet data without showing the interface, use the [Sheets API](/type-script-guides/sheets-api) instead.

## Supported asset types

Athena currently provides embedded viewers for:

* Spreadsheets
* Athena documents and Word documents
* User Interfaces
* PowerPoint presentations
* Images and PDFs
* Notebooks
* Figures
* Semantic models
* Video sessions

The controls available depend on the asset type. For example, a full spreadsheet embed includes the native toolbar, formula bar, sheet tabs, formatting controls, and collaboration experience, while a PDF embed provides its native document viewer.

Raw video, audio, text, web page, email, meeting, query snippet, dashboard, and AOP assets cannot currently be embedded. Some legacy native document and presentation formats must be exported to PDF before embedding.

## Before you begin

You need:

* The ID of a supported Athena asset that the current user can view
* An Athena user access token for browser applications, or an Athena API key kept on your server
* A container with an explicit height for the embedded asset

To create an asset programmatically, see [Create Assets](/type-script-guides/create-assets).

## Embed with React

The recommended integration for React applications is `AthenaAssetEmbed` from `@athenaintel/react`. The component generates a signed embed URL, renders the asset in an iframe, and synchronizes the current user's authentication with the embedded Athena application.

### Install the React SDK

```bash
npm install @athenaintel/react
```

### Render the full asset experience

```tsx
import {
  AthenaAssetEmbed,
  AthenaProvider,
} from '@athenaintel/react';
import '@athenaintel/react/styles.css';

interface AssetViewProps {
  accessToken: string;
  assetId: string;
}

export function AssetView({
  accessToken,
  assetId,
}: AssetViewProps) {
  return (
    <AthenaProvider config={{ token: accessToken }}>
      <div style={{ height: 800, width: '100%' }}>
        <AthenaAssetEmbed
          assetId={assetId}
          displayMode="full"
          readOnly={false}
          expiresInSeconds={60 * 60}
          title="Athena asset"
          onError={(error) => {
            console.error('Could not load the asset', error);
          }}
        />
      </div>
    </AthenaProvider>
  );
}
```

`displayMode="full"` renders the complete native experience available for that asset type. Use `displayMode="minimal"` for a lean viewing or editing surface.

`readOnly={false}` requests editing access; it does not grant it. If the current user can only view the asset, Athena automatically issues a read-only embed. Set `readOnly` to `true` when editing should never be available in the embedded experience.

> **Warning**
>
> Do not put an Athena API key in browser code. Authenticate browser applications with a short-lived user access token. Keep API keys in server-side code only.

### Component options

| Property           | Type                                | Default       | Description                                      |
| ------------------ | ----------------------------------- | ------------- | ------------------------------------------------ |
| `assetId`          | `string`                            | Required      | ID of the Athena asset to embed                  |
| `displayMode`      | `"minimal" \| "full"`               | `"full"`      | Amount of native Athena interface to render      |
| `readOnly`         | `boolean`                           | `false`       | Requests a read-only or editable embed           |
| `expiresInSeconds` | `number`                            | 30 days       | Lifetime of the signed embed URL                 |
| `onLoad`           | `() => void`                        | —             | Called when the iframe loads                     |
| `onError`          | `(error: Error) => void`            | —             | Called if Athena cannot create or load the embed |
| `loadingFallback`  | `ReactNode`                         | Spinner       | Content shown while the embed URL is created     |
| `errorFallback`    | `ReactNode \| (error) => ReactNode` | Error message | Content shown when loading fails                 |

The component also accepts standard iframe properties except `src`, `onLoad`, and `onError`.

## Embed with an iframe

For a non-React application—or for an Athena User Interface asset—generate an embed URL on your server and use it as the iframe source.

### Generate a signed embed URL

```ts
const response = await fetch(
  'https://api.athenaintel.com/api/embed/generate-token',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-KEY': process.env.ATHENA_API_KEY!,
    },
    body: JSON.stringify({
      asset_id: 'your-athena-asset-id',
      display_mode: 'full',
      read_only: false,
      expires_in_seconds: 60 * 60,
    }),
  },
);

if (!response.ok) {
  throw new Error(`Could not generate embed URL: ${response.status}`);
}

const { embed_url: embedUrl } = await response.json();
```

You can send `Authorization: Bearer <user-access-token>` instead of `X-API-KEY` when generating the URL on behalf of an authenticated Athena user.

The response includes:

```json
{
  "token": "signed-embed-token",
  "embed_url": "https://app.athenaintel.com/embed/signed-embed-token",
  "expires_at": 1785772800,
  "asset_id": "your-athena-asset-id",
  "read_only": false,
  "display_mode": "full"
}
```

### Render the URL

```html
<iframe
  src="EMBED_URL_FROM_YOUR_SERVER"
  title="Athena asset"
  width="100%"
  height="800"
  style="border: 0"
  allow="fullscreen"
></iframe>
```

The same iframe markup can be placed in the `index.html` of an Athena User Interface asset.

> **Warning**
>
> An embed URL is a bearer credential. Anyone who receives it can use the access encoded in the token until it expires. Prefer read-only embeds, use the shortest practical expiration, and never write embed URLs to analytics events or application logs.

## Access and collaboration

* The user generating an embed must be allowed to view the asset.
* An editable embed is issued only when that user can also edit the asset. Athena downgrades all other requests to read-only.
* Read-only embeds omit editing controls for asset types that support editing.
* Editable collaborative assets connect to the same live content as Athena, so changes and collaborators stay synchronized.
* The requested display mode and access level are signed into the token and cannot be upgraded by changing iframe query parameters.

## Troubleshooting

### The asset is read-only

Confirm that `readOnly` is `false` and that the user generating the embed has edit permission for the asset. Requesting an editable embed cannot override the user's Athena permissions.

### The embed has no visible height

`AthenaAssetEmbed` fills its parent container. Give the parent an explicit height, such as `height: 800px` or a viewport-based height.

### The embed token expired

Create a new embed URL. `AthenaAssetEmbed` handles URL generation for you when the component mounts; applications managing iframe URLs directly must renew them on the server.

### Authentication fails in the browser

Use a valid Athena user access token with `AthenaProvider`. Do not substitute a server API key in client-side code.