# Self-Hosted API

### Introduction

The Self-Hosted API is a standalone release of our Decision API that enables you to host the Decision API inside your own infrastructure.\
It enables you to host the *decision* part of the Decision API alongside your servers, thus decreasing response time.\
The data collection part of the Flagship platform is still hosted on our side, and the Self-Hosted API just relay the hit tracking calls to our own cloud-hosted data collection.

#### How does it work?

The Self-Hosted API uses the Go SDK internally in bucketing mode to synchronize the use cases with the Flagship platform. The decision logic (context targeting & visitor assignments) is done locally, which makes it really fast.

Here is a high level overview of the Self-Hosted API architecture:

![1012](https://files.readme.io/47a26f9-self-hosted-api.png)

#### Why use the Self-Hosted API

The Self-Hosted API is a relevant infrastructure choice if:

* You want a very low latency when calling the API (<10ms)
* You do not want to use the SDK with the bucketing mode for any reason (like not wanting to add a third-party dependancy to your stack)

#### Caveats

**Visitor assignments caching**

Thanks to our hashing algorithm, a unique visitor (with a unique ID) will always see the same variation of a campaign, if the traffic allocation of the variations stays the same.\
If you're using a high level Flagship feature such as Experience Continuity, 1 visitor 1 experiment or Dynamic Allocation, or if you manually change the traffic allocation of your variations, the hashing algorithm is not enough. You need some sort of assignment cache to store the visitor assignment to the variation.\
Flagship cloud-hosted Decision API provides such a caching mechanism for you by default using our own high-velocity key-value store.

If you want to use those features with the Self-Hosted API, you need to configure your own cache to store visitor assignments. See the [Configuration](#configuration) below to set it up.

### Installation

The Flagship Self-Hosted API can be installed and deployed in your infrastructure either by downloading and running the binary, or pulling and running the docker image in your orchestration system

#### Using a binary

You can download the latest binary here: <https://github.com/flagship-io/self-hosted-api/releases>

#### Using a Docker image

You can pull the latest docker image from docker hub:\
`docker pull flagshipio/self-hosted-api:latest`

### Running

#### Using a binary

Download the latest release on github and then simply run:

`ENV_ID={your_environment_id} API_KEY={your_api_key} ./app`

The server will run on the port 8080 by default. You can override this configuration (see [Configuration](#configuration))

#### Running with Docker

Run the following command to start the server with Docker

`docker run -p 8080:8080 -e ENV_ID={your_env_id} -e API_KEY={your_api_key} flagshipio/self-hosted-api`

### Configuration

You can configure the self-hosted Decision API using 2 ways:

* YAML configuration file
* Environment Variables

#### Using a configuration file

Create a `config.yaml` along your app file, or mount it in docker in location /config.yaml:

`docker run -p 8080:8080 -v ./config.yaml:/config.yaml flagshipio/self-hosted-api`

The configuration file should look like this:

```yaml
env_id: "env_id" # Your Flagship Environment ID
api_key: "api_key" # Your Flagship API Key

# Cache
cache:
  type: local # or 'redis' or 'none' (if you do not want to using visitor cache)
  options:
    dbPath: ./data
    #redisHost: 'localhost:6379' # for redis storage
    #redisUsername: username     # (Optional) for redis storage
    #redisPassword: password     # (Optional) for redis storage
```

#### Using environment variables

You can override each configuration variables from the configuration file using environment variables.\
Just name your env variables the same as the config file, but with the following rules:

* Env variable name should be UPPERCASE\
  Example: ENV\_ID
* Sub configuration level are defined using a `_` sign\
  Example: CACHE\_TYPE\
  Example: CACHE\_OPTIONS\_DBPATH

Here is a Docker example using environment variables to setup local caching:

`docker run -p 8080:8080 -e ENV_ID={your_env_id} -e API_KEY={your_api_key} -e CACHE_TYPE=local -e CACHE_OPTIONS_DBPATH=./data -v ./config.yaml:/config.yaml flagshipio/self-hosted-api`

Here is a Docker Compose example of using Redis as a visitor cache engine:

```yaml
version: "3"
services:
  decision:
    build: .
    ports:
      - 8080:8080
    environment:
      ENV_ID: "env_id"
      API_KEY: "api_key"
      CACHE_TYPE: redis
      CACHE_OPTIONS_REDISHOST: "redis:6379"
    depends_on:
      - redis

  redis:
    image: redis
```

#### Configuration parameters

You can use the following parameters to customize the Self Hosted API.\
Each parameter is named as in the config.yaml file, and the matching environment variable is parenthesis.

| Parameter                                                   |  Type  | Required |                                                     Description                                                     |
| ----------------------------------------------------------- | :----: | -------: | :-----------------------------------------------------------------------------------------------------------------: |
| env\_id (ENV\_ID)                                           | string |      yes |           The Flagship environment ID. You can get it from the Flagship platform. Default to empty string           |
| api\_key (API\_KEY)                                         | string |      yes |   The Flagship API Key for this environment ID. You can get it from the Flagship platform. Default to empty string  |
| polling\_interval (POLLING\_INTERVAL)                       |   int  |       no |          The polling frequency (in seconds) to synchronize with your Flagship configuration. Default to 60          |
| cache.type (CACHE\_TYPE)                                    | string |       no |    If you want to enable caching for the visitor assignment. Can be "redis" or "local". Default to empty string.    |
| cache.options.dbPath (CACHE\_OPTIONS\_DBPATH)               | string |       no | If you chose local cache type, this is the path of the file where the cache will be stored. Default to empty string |
| cache.options.redisHost (CACHE\_OPTIONS\_REDISHOST)         | string |       no |                        If you chose redis cache type, this is the host for your redis server                        |
| cache.options.redisUsername (CACHE\_OPTIONS\_REDISUSERNAME) | string |       no |                      If you chose redis cache type, this is the username for your redis server                      |
| cache.options.redisUsername (CACHE\_OPTIONS\_REDISPASSWORD) | string |       no |                      If you chose redis cache type, this is the password for your redis server                      |
| cache.options.redisDb (CACHE\_OPTIONS\_REDISDB)             |   int  |       no |        If you chose redis cache type, this is the db number for your redis server. Default to 0 (default DB)        |

### API Reference

The Self-Hosted API has the same relative endpoints than the cloud-base [Decision API V2 (latest)](doc:decision-api) . The only difference is that you do not need to put your environment ID inside the URL path (because the environment ID is already configured when starting the Self-Hosted API).

So instead of calling\
`https://decision.flagship.io/v2/{{YOUR_ENVIRONMENT_ID}}/campaigns`

You would call\
`https://your.selfhosted.api.instance/v2/campaigns`

You can find the Swagger API doc at the `/swagger/index.html` URL when running the application.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.abtasty.com/server-side/decision-api/self-hosted-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
