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

# Launch a user via postMessage

> > ⚠️ **Different host.** Like [POST /auth/launch](/api-reference/authentication/launch-a-user-into-the-app), this lives on the **app host** (`app.etherfuse.com` / `sandbox.etherfuse.com`), **not** the API host. It is a browser-facing page, not a JSON API.

The `postMessage` variant of launch, for embedding the flow in an **iframe or popup**. Open `/auth/launch` with no body; on load it asks its embedder (your page) for credentials over `postMessage`, and you reply. Use this when you don't want to server-render a [form POST](/api-reference/authentication/launch-a-user-into-the-app). It also lets you handle session expiration and launch into different targets seamlessly, without a redirect page.

## postMessage contract

1. On load, the launch frame posts an `etherfuse:auth:request` message to its embedder.
2. Your page replies with an `etherfuse:auth:response` carrying the fields below.
3. If you need a moment to sign a JWT, send `etherfuse:auth:await` first so the frame doesn't time out.

## Fields

- **`grant_type`** and **`assertion`**: a raw partner JWT (`grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer`) or a `refresh_token` from a prior [server-side exchange](/api-reference/authentication/exchange-a-partner-jwt) (`grant_type=refresh_token`).
- **`target`**: the app path to land on. Must be an allowed target. See [User Launch Flows](/guides/user-launch-flows#targets). Any other path is rejected.
- **`return_url`** *(optional)*: where to send the user when they leave.

The JWT's `sub` and `scope` follow the same rules as [POST /auth/launch](/api-reference/authentication/launch-a-user-into-the-app).

<RequestExample>
  ```html iframe theme={null}
  <iframe src="https://sandbox.etherfuse.com/auth/launch"></iframe>

  <script>
    const origin = "https://sandbox.etherfuse.com";
    window.addEventListener("message", (event) => {
      if (event.origin !== origin) return;
      if (event.data?.type !== "etherfuse:auth:request") return;
      // event.source is the launch iframe — reply to it.
      event.source.postMessage(
        {
          type: "etherfuse:auth:response",
          grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
          assertion: SIGNED_JWT,
          target: "/kyb",
        },
        origin,
      );
    });
  </script>
  ```

  ```javascript window.open theme={null}
  // Open WITHOUT noopener so the window keeps `window.opener` and can
  // postMessage back to your page.
  const launcher = window.open("https://sandbox.etherfuse.com/auth/launch", "etherfuse");

  window.addEventListener("message", (event) => {
    if (event.origin !== "https://sandbox.etherfuse.com") return;
    if (event.data?.type !== "etherfuse:auth:request") return;
    launcher.postMessage(
      {
        type: "etherfuse:auth:response",
        grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
        assertion: SIGNED_JWT,
        target: "/kyb",
      },
      event.origin,
    );
  });
  ```
</RequestExample>


## OpenAPI

````yaml GET /auth/launch
openapi: 3.1.0
info:
  title: Etherfuse FX API
  description: Partner-facing ramp API for onramps, offramps, swaps, and KYC.
  license:
    name: Proprietary
  version: 1.0.0
servers:
  - url: https://api.sand.etherfuse.com
    description: Sandbox
security:
  - ApiKeyAuth: []
tags:
  - name: Authentication
    description: >-
      Partner JWT authentication — exchange a JWT for an access token, or launch
      a user into the app.
  - name: Lookup
    description: >-
      Public reference data: exchange rates, stablebonds, bond costs, country
      codes.
  - name: Assets
    description: Rampable stablecoins and stablebonds available per blockchain.
  - name: Onboarding
    description: Hosted and programmatic customer onboarding.
  - name: Bank Accounts
    description: Register and retrieve customer bank accounts.
  - name: Quotes
    description: Price quotes for onramps, offramps, and swaps.
  - name: Orders
    description: Create, track, and manage ramp orders.
  - name: Swaps
    description: Crypto-to-crypto swaps.
  - name: Sponsored
    description: Token approvals for sponsored (gasless) offramps.
  - name: Customers
    description: Customer (child-organization) records.
  - name: Wallets
    description: Register and manage customer wallets.
  - name: KYC
    description: Submit and check customer KYC status.
  - name: Webhooks
    description: Event notification subscriptions.
  - name: Organizations
    description: Organization identity, child orgs, and partner fees.
paths:
  /auth/launch:
    servers:
      - url: https://sandbox.etherfuse.com
        description: Sandbox app (NOT the API host)
    get:
      tags:
        - Authentication
      summary: Launch a user via postMessage
      description: >-
        > ⚠️ **Different host.** Like [POST
        /auth/launch](/api-reference/authentication/launch-a-user-into-the-app),
        this lives on the **app host** (`app.etherfuse.com` /
        `sandbox.etherfuse.com`), **not** the API host. It is a browser-facing
        page, not a JSON API.


        The `postMessage` variant of launch, for embedding the flow in an
        **iframe or popup**. Open `/auth/launch` with no body; on load it asks
        its embedder (your page) for credentials over `postMessage`, and you
        reply. Use this when you don't want to server-render a [form
        POST](/api-reference/authentication/launch-a-user-into-the-app). It also
        lets you handle session expiration and launch into different targets
        seamlessly, without a redirect page.


        ## postMessage contract


        1. On load, the launch frame posts an `etherfuse:auth:request` message
        to its embedder.

        2. Your page replies with an `etherfuse:auth:response` carrying the
        fields below.

        3. If you need a moment to sign a JWT, send `etherfuse:auth:await` first
        so the frame doesn't time out.


        ## Fields


        - **`grant_type`** and **`assertion`**: a raw partner JWT
        (`grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer`) or a
        `refresh_token` from a prior [server-side
        exchange](/api-reference/authentication/exchange-a-partner-jwt)
        (`grant_type=refresh_token`).

        - **`target`**: the app path to land on. Must be an allowed target. See
        [User Launch Flows](/guides/user-launch-flows#targets). Any other path
        is rejected.

        - **`return_url`** *(optional)*: where to send the user when they leave.


        The JWT's `sub` and `scope` follow the same rules as [POST
        /auth/launch](/api-reference/authentication/launch-a-user-into-the-app).
      operationId: auth_launch_postmessage
      responses:
        '200':
          description: >-
            An HTML page that requests credentials from the embedder over
            `postMessage`, establishes the session, and redirects the browser to
            `target`.
      security: []
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: API key sent in the Authorization header.

````