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

# Integration Overview

> Understanding how Sticker embeds into your platform

## Architecture Overview

Sticker's embedded integration follows a simple but secure architecture that keeps your users authenticated across both platforms while providing a seamless procurement experience.

## Integration Components

<CardGroup cols={2}>
  <Card title="Backend Integration" icon="server">
    Two API endpoints to call from your backend server
  </Card>

  <Card title="Frontend Embedding" icon="window">
    iframe component to display Sticker in your UI
  </Card>

  <Card title="Organization Management" icon="building">
    Automatic provisioning of orgs, users, and billing
  </Card>

  <Card title="Session Authentication" icon="key">
    Secure, time-limited tokens for each user session
  </Card>
</CardGroup>

## Two API Endpoints, That's It

The entire integration requires just **two API calls**:

### 1. Organization Setup (One-Time)

Called when a customer enables procurement in your platform.

```
POST /v1/organizations/setup
```

**Creates:**

* Organization with Stripe customer for billing
* User profile linked to Supabase Auth
* Shipping locations for order delivery

### 2. Partner Handshake (Per-Session)

Called every time a user opens the supplies module.

```
POST /v1/partner/handshake
```

**Returns:**

* Session token (5 min, single-use)
* Complete iframe embed URL

## Integration Flow

### One-Time Setup Flow

This happens once when a customer enables procurement:

<Steps>
  <Step title="Customer Enables Supplies">
    A customer clicks "Enable Supplies" in your platform
  </Step>

  <Step title="Gather Data">
    Collect organization name, user info, and shipping addresses from your system
  </Step>

  <Step title="Call Organization Setup">
    Send data to Sticker:

    ```javascript theme={null}
    POST /v1/organizations/setup
    {
      "internalOrgId": "your-org-id",
      "organizationName": "Customer Org",
      "internalUserId": "your-user-id",
      "user": {
        "firstName": "...",
        "lastName": "...",
        "email": "..."
      },
      "shippingLocations": [...]
    }
    ```
  </Step>

  <Step title="Store Response">
    Optionally store the returned `profile.id` for reference
  </Step>

  <Step title="Enable UI">
    Show the supplies module in your navigation
  </Step>
</Steps>

### Per-Session Authentication Flow

This happens every time a user opens supplies:

<Steps>
  <Step title="User Clicks Supplies">
    User navigates to the supplies section
  </Step>

  <Step title="Call Handshake">
    From your backend, call Sticker:

    ```javascript theme={null}
    POST /v1/partner/handshake
    {
      "internal_user_id": "your-user-id"
    }
    ```
  </Step>

  <Step title="Get iframe URL">
    Response contains complete embed URL:

    ```json theme={null}
    {
      "iframe_embed_url": "https://shop.usesticker.com/embedded/{partner}?session_key={token}"
    }
    ```
  </Step>

  <Step title="Embed iframe">
    Display the iframe in your UI
  </Step>

  <Step title="User Shops">
    User browses, orders—all within your platform
  </Step>
</Steps>

## Data Models

Sticker maps users into organizations using a many-to-one structure:

* An **organization** is the customer business, company, practice, store, school, or legal entity.
* A **profile** is an employee or user inside that organization.
* One organization can have many profiles.
* Each distinct customer business must have a unique `internalOrgId`.

<Warning>
  Do not reuse a single `internalOrgId` for multiple unrelated businesses. Sticker treats that value as the business identity. Reusing it will group all of those users into one Sticker organization.
</Warning>

### What You Send

```typescript theme={null}
// Organization Setup Request
{
  internalOrgId: string;        // YOUR unique business/org ID
  organizationName: string;     // Display name
  
  internalUserId: string;       // YOUR user/employee ID
  user: {
    firstName: string;
    lastName: string;
    email: string;
    phoneNumber?: string;
  };
  
  shippingLocations?: [{
    internalShippingLocationId: string;
    name: string;
    address: {
      line1: string;
      city: string;
      province: string;
      postalCode: string;
    };
    isDefault?: boolean;
  }];
}
```

### What You Receive

```typescript theme={null}
// Organization Setup Response
{
  success: true,
  data: {
    organization: {
      id: string;             // Sticker org UUID
      stripeCustomerId: string;
    },
    profile: {
      id: string;             // Sticker profile UUID
      internal_user_id: string;  // Your ID echoed back
    },
    shippingLocations: [...],
    isNewOrganization: boolean;
  }
}

// Handshake Response
{
  success: true,
  session_key: string;
  iframe_embed_url: string;    // Use this directly!
  expires_at: string;
  profile: {
    id: string;
    first_name: string;
    last_name: string;
    email: string;
  }
}
```

## Security Model

<AccordionGroup>
  <Accordion title="API Key Authentication" icon="key">
    All API requests require your Partner API Key. Never expose it in client-side code.

    ```javascript theme={null}
    // Organization Setup
    Authorization: Bearer sk_live_xxx

    // Handshake
    X-API-Key: sk_live_xxx
    ```
  </Accordion>

  <Accordion title="Session Tokens" icon="clock">
    * **5 minute expiry** - Must be used quickly
    * **Single-use** - Invalidated after first use
    * **User-bound** - Tied to specific profile
    * **Partner-bound** - Only works with your iframe URL
  </Accordion>

  <Accordion title="iframe Sandboxing" icon="shield">
    The iframe runs with restricted permissions:

    ```html theme={null}
    sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation"
    ```
  </Accordion>
</AccordionGroup>

## What's Included Out of the Box

When you embed Sticker, your users get:

| Feature                | Description                              |
| ---------------------- | ---------------------------------------- |
| **Product Catalog**    | 10,000+ products across categories       |
| **Smart Search**       | Algolia-powered instant search           |
| **Shopping Cart**      | Multi-item cart with quantity management |
| **Multiple Locations** | Select from org's shipping addresses     |
| **Payment Methods**    | Org-level saved payment methods          |
| **Coupon Support**     | Partner-funded discounts                 |
| **Order History**      | View past orders and status              |
| **Favorites**          | Save frequently ordered items            |

## Environments

| Environment         | API Base URL                            | Keys        |
| ------------------- | --------------------------------------- | ----------- |
| **Production**      | `https://api.usesticker.com/v1`         | `sk_live_*` |
| **Staging/Sandbox** | `https://api.staging.usesticker.com/v1` | `sk_test_*` |

<Info>
  Use sandbox for development and testing. Sandbox data is isolated from production.
</Info>

## Rate Limits

| Endpoint           | Rate Limit |
| ------------------ | ---------- |
| Organization Setup | 100/minute |
| Handshake          | 300/minute |

Implement exponential backoff for 429 responses.

## Next Steps

<CardGroup cols={2}>
  <Card title="Organization Setup" icon="building" href="/integration/organization-setup">
    Provision organizations and users
  </Card>

  <Card title="User Handshake" icon="handshake" href="/integration/user-handshake">
    Authenticate users for each session
  </Card>

  <Card title="iframe Embedding" icon="window" href="/integration/iframe-embedding">
    Display Sticker in your application
  </Card>

  <Card title="Best Practices" icon="lightbulb" href="/integration/best-practices">
    Tips for a robust integration
  </Card>
</CardGroup>
