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

# Assignments via API

> Access Winning Variant programmatically from anywhere (including outside of Snowflake) to get or make experiment assignments.

## Overview

Use the API described below to get or set experiment assignments from anywhere. This is especially useful for use cases that exist *outside* of Snowflake, such as in your app/platform.

The hostname for the API can be retrieved by clicking the App from within Snowflake: Data Products > Apps > Winning Variant Experimentation. The hostname for "Variant API" is the one you'll use.

## Experiment Assignments

`POST /experiment-assignments`

Use this endpoint to get or set assignments for a list of subject IDs in a given experiment. If an assignment already exists, it is returned, otherwise a new one is created and returned.

### **Request Body**

The request accepts a JSON-formatted body with the following parameters:

| **Parameter**   | **Type**   | **Required** | **Description**                                                             |
| --------------- | ---------- | ------------ | --------------------------------------------------------------------------- |
| `experiment_id` | `string`   | Yes          | The ID of the experiment to get/set assignments for.                        |
| `subject_ids`   | `string[]` | Yes          | List of subject IDs to get/set assignments for within the given experiment. |

### **Response**

A JSON object with a single key, `assignments` , itself another object with key-value pairs. The key is the subject ID originally provided and the value is the variant it's assigned within the experiment.

### Examples

**Get an assignment for a single subject**

In this example, we request an assignment for user `user_123` in experiment `MY-EXPERIMENT`. The response indicates that the subject is assigned the `CONTROL` variant.

```
POST /experiment-assignments
Content-type: application/json
Accept: application/json
{
  "experiment_id": "MY-EXPERIMENT",
  "subject_ids": ["user_123"]
}

Response:
{
  "assignments": {
    "user_123": "CONTROL"
  }
}
```

**Get assignments for multiple subjects**

In this example, we request assignments for two users in the same experiment. The response includes the variant assignment for each, respectively.

```
POST /experiment-assignments
Content-type: application/json
Accept: application/json
{
  "experiment_id": "MY-EXPERIMENT",
  "subject_ids": ["user_123","user_456"]
}

Response:
{
  "assignments": {
    "user_123": "CONTROL",
    "user_456": "TREATMENT"
  }
}
```

## Public Access

Snowflake currently does not allow unauthenticated public internet access to any service on its platform. Since any experiments running outside of Snowflake will ultimiately need access to the Variant API running inside of the application, you will need to deploy some sort of reverse proxy or forwarding service that takes public traffic and authenticates it with Snowflake.

### Authenticate using Programmatic Access Tokens (Recommended)

The recommended approach to accessing Snowpark Container Services (including those deployed through the Winning Variant Native App) is to use [Programmatic Access Tokens](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) (PAT).

Follow the documentation provided above from Snowflake to enable this for your account. Once a PAT is generated for a user mapped to the `proxy` application role, you can deploy your own simple reverse proxy that appends the `Authentication` header or use a forwarding service, such as one through [Cloudflare](https://www.cloudflare.com/).

### Authenticate using OAuth

If you're unable to use Programmatic Access Tokens, you can use Snowflake's standard OAuth flow to authenticate traffic. Due to the necessary token exchanges and refreshes associated with this approach, Winning Variant has released its own open source reverse proxy, [icebreaker](https://github.com/winningvariant/icebreaker), built on top of nginx. This project handles the OAuth flow and refreshes for you automatically.

In order to keep our promise of data control and privacy, we provide instructions below on how to set up this reverse proxy within your own cloud environment. Alternately, Winning Variant is happy to host this for you as a managed service offering.

**1. Create a role**

Create a role in your account that will be mapped to the app's role, which only has access to the Variant API endpoint. You can name this whatever you like, but we use `WVPROXY` in our examples:

```sql theme={null}
CREATE ROLE WVPROXY;
```

**2. Create a dedicated user**

Create a user that will be used by the reverse proxy to access the services running in the Winning Variant native app.

* [Snowflake: Create User](https://docs.snowflake.com/en/sql-reference/sql/create-user)

**3. Enable key pair authentication for this user.**

* [Snowflake: Key Pair Authentication](https://docs.snowflake.com/en/user-guide/key-pair-auth)

**4. Assign your new user to your new role**

For example:

```sql theme={null}
GRANT ROLE WVPROXY TO USER <new user>;
```

Alternately, you can assign this new role to an existing role in your account:

```sql theme={null}
GRANT ROLE WVPROXY TO ROLE <existing role>;
```

**5. Map your account role to the app role**

Within the Winning Variant app settings, map your role to the `PROXY` application role created by the app. This will give it usage of the service that serves the Variant API.

<img src="https://mintcdn.com/winningvariant/ezeZudPOVanONtX3/images/proxy-role.png?fit=max&auto=format&n=ezeZudPOVanONtX3&q=85&s=6d63abf00b05d004cbda2187c5659ca0" alt="Winning Variant Reverse Proxy Role" className="mx-auto" style={{ width:"56%" }} width="423" height="447" data-path="images/proxy-role.png" />

**6. Deploy Reverse Proxy**

Build the [icebreaker](https://github.com/winningvariant/icebreaker) project, which deploys an [nginx](https://nginx.org/) service in your own cloud region and manages the OAuth flow (including refreshes) for you automatically. This gives you complete control of the service and the data that passes through the reverse proxy while allowing you to deploy it in the same region as your Snowflake account.

When deploying, you'll provide environment variables unique to your setup, including the Variant API ingress URL, your new user's username, and the private key used for authentication.

**Snowflake Network Ingress Policy**

If your organization enforces network policies, you may need to create an ingress policy to allow traffic from your reverse proxy. Read [Controlling network traffic with network policies](https://docs.snowflake.com/en/user-guide/network-policies) for details.

For example, if your reverse proxy has an egress IP address of '10.0.0.0':

```SQL theme={null}
CREATE NETWORK RULE winning_variant_variantapi TYPE = IPV4 VALUE_LIST = ('10.0.0.0/32');
```

**Firewall**

We recommend putting this service behind a web application firewall (WAF) that will help mitigate things such as DDOS attacks. Additionally, to reduce stress on the underlying Snowflake compute in the event of an attempted attack, you can limit access to the `/experiment-assignments` and `/healthz` endpoints only.

**Health Checks**

A health check is available at `/healthz`, which returns a `200` status code if the service is alive *and* able to communicate with the appropriate Snowflake database. This health check is used by Snowpark Container Services, but may also be used by you to monitor uptime.

Winning Variant would also like to monitor the uptime of your reverse proxy, so please provide the hostname of the service, when live, and [add this list of IP addresses to your allowlist](https://uptime.betterstack.com/ips.txt).
