> For the complete documentation index, see [llms.txt](https://docs.winga.me/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.winga.me/api-reference/evaluation-api.md).

# Evaluation API

The Evaluation API serves your flags to any runtime that can make an HTTP request. The [`@winga/js`](/sdks/javascript.md) SDK is a thin wrapper over these same endpoints, so non-JavaScript stacks get the exact same behaviour by calling them directly.

### Base URL

The base URL is...

```
https://api-dev.winga.me
```

All examples below use the production host.

### Authentication

Every request is authenticated with your project's eval key in the `X-Winga-Key` header. Only `proj_live_` keys ship today.

```
X-Winga-Key: proj_live_xxx
```

The key is scoped to a single project and to the set of environments it was issued for. There is no separate `Authorization` header.

### Get all flags

Returns every flag in the environment.

```
GET https://api.winga.me/v1/flags?env=production
X-Winga-Key: proj_live_xxx
```

```json
{
  "environment": "production",
  "flags": {
    "new-checkout": { "enabled": true, "value": true },
    "maintenance-mode": { "enabled": false, "value": false }
  }
}
```

Each flag is `{ enabled, value?, rolloutPct? }`. `value` and `rolloutPct` are omitted when absent.

### Get a single flag

```
GET https://api.winga.me/v1/flags/{key}?env=production
X-Winga-Key: proj_live_xxx
```

```json
{
  "environment": "production",
  "key": "new-checkout",
  "enabled": true,
  "value": true
}
```

If the flag does not exist in the environment, the response is a `404`:

```json
{
  "error": "flag_not_found",
  "message": "The requested flag key does not exist in this environment.",
  "docs": "https://docs.winga.me/errors/flag_not_found"
}
```

### Get multiple flags (batch)

Send a `POST` with the environment and the keys you want. Keys that do not exist are simply omitted from the response.

```
POST https://api.winga.me/v1/flags/batch
X-Winga-Key: proj_live_xxx
Content-Type: application/json
```

```json
{
  "env": "production",
  "keys": ["new-checkout", "maintenance-mode", "beta-dashboard"]
}
```

```json
{
  "environment": "production",
  "flags": {
    "new-checkout": { "enabled": true, "value": true },
    "maintenance-mode": { "enabled": false, "value": false },
    "beta-dashboard": { "enabled": true, "value": true }
  }
}
```

### Realtime stream (SSE)

```
GET https://api.winga.me/v1/stream?env=production
X-Winga-Key: proj_live_xxx
```

The response is `Content-Type: text/event-stream`. On every change the server emits one `data:` frame containing the environment's **full flag map** — `Record<string, FlagState>`, the same shape `GET /v1/flags` returns under its `flags` key. It is **not** a diff.

```
data: {"new-checkout":{"enabled":true,"value":true}}

data: {"new-checkout":{"enabled":false,"value":false}}
```

Authentication uses the same `X-Winga-Key` header as the REST endpoints. If the server's underlying listener errors, it closes the stream with no further frames — reconnect to resume.

> The stream emits the per-environment flat map directly. Earlier builds wrote the raw database subtree verbatim; the current shape is always `Record<string, FlagState>` (fixed in M12.4).

### Error responses

Every error uses the same shape:

```json
{
  "error": "error_code",
  "message": "Human-readable description",
  "docs": "https://docs.winga.me/errors/error_code"
}
```

| Code                    | HTTP | Meaning                                                                     |
| ----------------------- | ---- | --------------------------------------------------------------------------- |
| `invalid_api_key`       | 401  | Key missing, invalid, expired, or the index entry is malformed.             |
| `invalid_argument`      | 400  | The request body or query parameters are malformed.                         |
| `environment_not_found` | 404  | The environment does not exist for this project or key.                     |
| `flag_not_found`        | 404  | The flag key was not found in this environment.                             |
| `rate_limited`          | 429  | Too many requests — back off and retry (wired; not enforced until Phase 2). |
| `internal_error`        | 500  | Something broke on our end — we are alerted automatically.                  |

### Next steps

* Prefer a typed client? Use [`@winga/js`](/sdks/javascript.md).
* See language-specific REST examples under [Integrations](/integrations/go.md).
