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

# Create a portal session

> Creates a pre-authenticated partner portal URL for a visitor email. This is the foundation of the **embedded portal experience** — show Introw directly inside your own product with one login and full branding.

**How to embed:**
1. Allow-list the domains that may embed Introw under **Settings → Developers → Embed** (only these domains can load the portal in an `<iframe>`).
2. From your backend, call this endpoint with the visitor's email and your secret API key (`portal-sessions:write` scope). Keep the key server-side — never call this from the browser.
3. Drop the returned `url` into an `<iframe>`. The URL carries a short-lived sign-in token, so the partner is logged in automatically with no login screen.

The visitor must already have portal access in the organisation resolved from the API key; otherwise the request returns `401`. Pass `roomId` to deep-link the visitor into a specific room (collaboration space) after authentication. Each URL is single-use and short-lived — generate a fresh one per visitor session.



## OpenAPI

````yaml /openapi.json post /api/v1/auth/session
openapi: 3.1.0
info:
  title: Introw API
  version: '2026-05-20'
  description: >-
    Customer-facing API for Introw. Manage partners, delegate commission payout
    operations to your finance software, embed the partner portal in your
    product with pre-authenticated sessions, and ingest affiliate conversions.
servers:
  - url: https://api.introw.io
  - url: https://api.staging.introw.io
security:
  - ApiKeyAuth: []
tags:
  - name: Partners
    description: >-
      Read and manage partners for the organisation associated with the
      authenticated API key.
  - name: Payouts
    description: >-
      Read and update commission payouts. Delegate approval, scheduling, and
      payment status to your ERP or accounts-payable stack.
  - name: Commission lines
    description: >-
      Create, read, update, decline, and detach commission line items. Lines can
      live in the pending pool or be attached to a payout.
  - name: Auth
    description: >-
      Create pre-authenticated partner portal sessions. Exchange a visitor email
      for a short-lived, single-use portal URL that you embed in an iframe
      inside your own product — one login, fully branded, no login screen for
      the partner.
  - name: Affiliate
    description: >-
      Ingest affiliate conversions from your backend or directly from the
      browser via affiliate.js. Every conversion is anchored to a signed,
      server-side click token (the first-party `_introw_aff` cookie),
      deduplicated, and mapped onto a campaign form submission — so attribution
      cannot be forged or double-counted.
paths:
  /api/v1/auth/session:
    post:
      tags:
        - Auth
      summary: Create a portal session
      description: >-
        Creates a pre-authenticated partner portal URL for a visitor email. This
        is the foundation of the **embedded portal experience** — show Introw
        directly inside your own product with one login and full branding.


        **How to embed:**

        1. Allow-list the domains that may embed Introw under **Settings →
        Developers → Embed** (only these domains can load the portal in an
        `<iframe>`).

        2. From your backend, call this endpoint with the visitor's email and
        your secret API key (`portal-sessions:write` scope). Keep the key
        server-side — never call this from the browser.

        3. Drop the returned `url` into an `<iframe>`. The URL carries a
        short-lived sign-in token, so the partner is logged in automatically
        with no login screen.


        The visitor must already have portal access in the organisation resolved
        from the API key; otherwise the request returns `401`. Pass `roomId` to
        deep-link the visitor into a specific room (collaboration space) after
        authentication. Each URL is single-use and short-lived — generate a
        fresh one per visitor session.
      operationId: createPortalSession
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePortalSessionBody'
            example:
              email: partner.user@acme.example
              roomId: room_01HVK6Y8Z8Q7J8J8J8J8J8J8J8
      responses:
        '200':
          description: Portal session URL created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreatePortalSessionResponse'
              example:
                url: >-
                  https://partners.acme.example/rooms/room_01HVK6Y8Z8Q7J8J8J8J8J8J8J8?token=eyJhbGciOiJIUzI1NiJ9.example
          headers:
            x-ratelimit-limit-minute:
              description: Maximum number of requests allowed in the current minute.
              schema:
                type: string
            x-ratelimit-remaining-minute:
              description: Number of requests remaining in the current minute.
              schema:
                type: string
        '401':
          description: >-
            API key is missing or invalid, or the visitor is not authorized for
            the portal.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '403':
          description: API key does not include the portal-sessions:write scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '422':
          description: Request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
components:
  schemas:
    CreatePortalSessionBody:
      type: object
      properties:
        email:
          description: >-
            Email address of the partner portal visitor. Must already be
            authorized for the portal in the API key's organisation; otherwise
            the request returns 401.
          type: string
          format: email
          pattern: >-
            ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
        roomId:
          description: >-
            Optional room (collaboration space) id to deep-link into after
            authentication. When omitted, the visitor lands on the portal home.
          anyOf:
            - type: string
              minLength: 1
            - type: 'null'
      required:
        - email
      additionalProperties: false
    CreatePortalSessionResponse:
      type: object
      properties:
        url:
          description: >-
            Pre-authenticated, single-use partner portal URL. Embed it directly
            in an iframe (the embedding domain must be allow-listed under
            Settings → Developers → Embed). The URL contains a short-lived
            token, so treat it as a secret and generate a fresh one per visitor
            session.
          type: string
          format: uri
      required:
        - url
      additionalProperties: false
    PublicApiError:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              description: Stable machine-readable error code.
              type: string
            message:
              description: Human-readable error message.
              type: string
            details:
              description: Optional structured details for validation and debugging.
          required:
            - code
            - message
          additionalProperties: false
      required:
        - error
      additionalProperties: false
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: Introw API key shown once when the credential is created.

````