> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runrally.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Embed the creator portal

> Put any creator portal module inside your own web app, signed in as the creator, with a short-lived token from your backend.

Everything a creator can do in the portal is available as a standalone module you can mount in your own product: the application form on your marketing site, earnings inside your dashboard, the whole portal in one iframe. The embedded module uses the same creator identity, data and history as the hosted portal.

**Settings → Embed** writes the snippets below for your framework with your host filled in, and a brief you can hand to a coding agent working on your web app.

## Modules

| Module | What it shows |
| - | - |
| `apply` | Public application form for a program. No sign-in. |
| `program-page` | Public program landing page. No sign-in. |
| `terms` | The program's terms on their own page. No sign-in. |
| `onboarding` | The signed-in creator's setup checklist. |
| `briefs` | Briefs the creator can accept or decline. |
| `content` | Plan, upload and submit content. |
| `create` | The AI-assisted creative workspace. |
| `calendar` | The creator's schedule. |
| `learn` | Learning paths and steps. |
| `performance` | Their published content's metrics. |
| `earnings` | Ledger, balances and payout requests. |
| `resources` | Knowledge base and brand assets. |
| `support` | Support channels and threads. |
| `portal` | The full creator portal in one iframe. |

## Public modules

The three public modules need only your host and the program's slug:

```html theme={null}
<script src="https://app.runrally.io/embed/embed.js"></script>
<div id="creator-apply"></div>
<script>
  Rally.mount(document.getElementById("creator-apply"), {
    module: "apply",
    program: "your-program-slug",
    host: "https://app.runrally.io",
    theme: { primary: "#171717" },
  });
</script>
```

## Signed-in modules

Signed-in modules take a **token** your backend mints for the creator who is logged into your product. The token is short-lived and single-use; the module exchanges it for its own session.

<Steps>
  <Step title="Mint a token on your backend">
    Use an API key with the `embed:mint` scope. Look the creator up by the email they use in your product:

    ```bash theme={null}
    curl -X POST https://app.runrally.io/v1/embed/tokens \
      -H "Authorization: Bearer co_your_api_key" \
      -H "Content-Type: application/json" \
      -d '{"creator_email":"sam@example.com","module":"earnings","ttl_seconds":300}'
    ```

    The response is `{ "token": "…", "creator_id": "…" }`. A `404` means this person is not a creator in your program yet; send them to the `apply` module instead.
  </Step>

  <Step title="Mount the module">
    <Tabs>
      <Tab title="HTML">
        ```html theme={null}
        <script src="https://app.runrally.io/embed/embed.js"></script>
        <div id="creator-earnings"></div>
        <script>
          Rally.mount(document.getElementById("creator-earnings"), {
            module: "earnings",
            token: TOKEN_FROM_YOUR_BACKEND,
            host: "https://app.runrally.io",
            theme: { primary: "#171717" },
            onEvent: (e) => console.log(e),
          });
        </script>
        ```
      </Tab>

      <Tab title="React">
        A small component that loads the script and mounts on a `div`. **Settings → Embed** has the same for Next.js, Vue and Svelte.

        ```tsx theme={null}
        import { useEffect, useRef } from "react";

        export function RallyEmbed({ token }: { token: string }) {
          const ref = useRef<HTMLDivElement>(null);
          useEffect(() => {
            const s = document.createElement("script");
            s.src = "https://app.runrally.io/embed/embed.js";
            let handle: { destroy: () => void } | undefined;
            s.onload = () => {
              handle = (window as any).Rally.mount(ref.current!, {
                module: "earnings",
                token,
                host: "https://app.runrally.io",
                theme: { primary: "#171717" },
              });
            };
            document.head.appendChild(s);
            return () => { handle?.destroy(); s.remove(); };
          }, [token]);
          return <div ref={ref} />;
        }
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

Never mint tokens in the browser: the API key would be visible to anyone. Mint on your server for the signed-in user and pass only the token down.

## Options

| Option | Purpose |
| - | - |
| `theme.primary` | Your brand colour; the module picks matching text colours. |
| `onEvent` | Called as the creator does things (a brief accepted, a payout requested) so your app can react. |
| `tenant` | Only needed when your Rally host serves more than one workspace. |

If you use a custom domain for Rally, use it as `host` so cookies and links stay on your domain.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.