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

# Foff SDK overview: choose TypeScript, Python, or Go

> Choose an official Foff SDK to integrate feature flags into your app. All SDKs follow the same pattern: configure, create a client, resolve flags, and close.

Foff provides official SDKs for TypeScript/JavaScript, Python, and Go. Each SDK follows the same four-step pattern: create a `Config`, create a client, call `getFeatureConfig` to resolve the right value for a given hierarchy, and close the client when your process exits. All SDKs poll the Foff API in the background and serve reads from an in-memory cache, so flag lookups are always fast and never block your request path.

<CardGroup cols={3}>
  <Card title="TypeScript" icon="js" href="/sdks/typescript">
    Install via npm. Requires Node.js 18+. Works with any Node.js framework.
  </Card>

  <Card title="Python" icon="python" href="/sdks/python">
    Install via pip. Requires Python 3.10+. Supports both sync and async clients.
  </Card>

  <Card title="Go" icon="code" href="/sdks/golang">
    Install via go get. Requires Go 1.22.10+. Thread-safe with goroutine-based polling.
  </Card>
</CardGroup>

## Minimum runtime requirements

| SDK        | Minimum version |
| ---------- | --------------- |
| TypeScript | Node.js 18+     |
| Python     | Python 3.10+    |
| Go         | Go 1.22.10+     |

## Common integration pattern

All three SDKs follow the same steps regardless of language.

<Steps>
  <Step title="Create a Config">
    Supply your API key, the base URL, your scope name, and an optional polling interval (in seconds). The polling interval defaults to 30 seconds. Set it to `0` to disable polling.

    | Field             | Required | Description                                          |
    | ----------------- | -------- | ---------------------------------------------------- |
    | `APIKey`          | Yes      | Your Foff API key.                                   |
    | `BaseURL`         | Yes      | `https://foff.twospoon.ai/live`                      |
    | `Scope`           | Yes      | The scope to fetch configs for (e.g. `production`).  |
    | `PollingInterval` | No       | Seconds between background refreshes. Default: `30`. |
  </Step>

  <Step title="Create a client">
    Pass your config to the SDK's client constructor. The client validates your config, makes an initial blocking fetch of all configs for the scope, and starts a background polling loop.
  </Step>

  <Step title="Resolve flags with getFeatureConfig">
    Call `getFeatureConfig(featureName, orderedHierarchy)` anywhere in your code. Pass the feature name and an ordered list of hierarchy values from least-specific to most-specific (e.g. `["org-1", "team-a", "user-123"]`). The SDK resolves the most specific match and falls back to the default value if no override exists.
  </Step>

  <Step title="Close the client">
    Call `close()` on shutdown to stop background polling and release resources.
  </Step>
</Steps>

## API endpoint

All SDKs call a single endpoint to fetch configs:

```
GET https://foff.twospoon.ai/live/api/v1/scopes/{scope}/configs
```

The client fetches this endpoint once at startup and then on every polling interval. Reads always come from the in-memory cache — no network call happens when you call `getFeatureConfig`.

## Hierarchy resolution

When you call `getFeatureConfig`, the SDK resolves the value from most-specific to least-specific:

1. It checks the full combination first — e.g. `org-1 + team-a + user-123`.
2. It then tries shorter prefixes — `org-1 + team-a`, then `org-1`.
3. If nothing matches, it returns the feature's default value.
4. If the feature doesn't exist at all, it returns `null` (or `nil`/`None` in Go and Python).

This lets you define overrides at any level of your hierarchy and the SDK finds the right one automatically.

<Note>
  Store your API key in an environment variable such as `FOFF_API_KEY`. Never hard-code it in source files or commit it to version control.
</Note>
