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

# Feature Flags

> Named, typed values you flip in the dashboard — live servers pick them up without a restart.

A feature flag is a **named, typed value**. Your server reads it and decides what to do with it. Change one in the [dashboard](https://dash.nonefivem.com) and every server reading it picks up the new value on its next refresh — no restart, no redeploy, no file edit.

<CardGroup cols={2}>
  <Card title="No Restart Required" icon="bolt">
    Flip a flag and live servers pick it up within seconds.
  </Card>

  <Card title="Typed Values" icon="code">
    Booleans, strings, numbers, and arbitrary JSON — not just on/off switches.
  </Card>

  <Card title="Server-Only Secrets" icon="shield">
    Mark a flag `server` and it is never published to players' clients.
  </Card>

  <Card title="Audit Log" icon="clock-rotate-left">
    Every change is recorded — who changed what, and when.
  </Card>
</CardGroup>

## Types

A flag holds one of four value types. The type and the value are validated together, so a `number` flag can never end up holding a string.

| Type      | Holds                                    |
| --------- | ---------------------------------------- |
| `boolean` | `true` or `false`                        |
| `string`  | Any string                               |
| `number`  | Any finite number                        |
| `json`    | An arbitrary JSON object, array or value |

## Runtimes

Every flag also has a **runtime**, which says where it may be read:

| Runtime  | Who can read it                  |
| -------- | -------------------------------- |
| `shared` | Your server and players' clients |
| `server` | Your server only                 |

Your server holds the API key and is the trusted side, so it always receives **every** flag. The runtime decides whether a value may also be relayed to players. A `server` flag is never published to clients — reading one from a client behaves exactly like reading a flag that does not exist.

<Warning>
  `shared` is the default. A flag is client-readable unless it says otherwise, so
  anything holding a secret (a webhook URL, a license key) must be created with
  `runtime: "server"`.
</Warning>

There is no client-only runtime: a value a client can read is one the server has already been sent.

## Keys

The key is the stable identifier your code reads a flag by.

<ParamField path="key" type="string" required>
  Lowercase slug, 1–64 characters. Must start with a letter or number and may
  contain only lowercase letters, numbers, hyphens and underscores —
  `^[a-z0-9][a-z0-9_-]*$`.
</ParamField>

Keys are **immutable**. Servers reference a flag by key, so renaming one would silently orphan every server reading it. The name and description are free-form and can be changed at any time.

## Limits

| Limit                        | Value           |
| ---------------------------- | --------------- |
| Flags without a subscription | **5**           |
| Flags with any subscription  | **50**          |
| Key length                   | 64 characters   |
| Name length                  | 100 characters  |
| Description length           | 500 characters  |
| Value size                   | 4 KB serialized |
| JSON nesting depth           | 4 levels        |

The allowance is a perk of being a paying customer — *any* active subscription raises it, not a flags-specific one. Every flag is shipped in the configuration payload each server polls, so the cap also bounds payload size.

### Locked flags

If a subscription lapses while you hold more flags than the free allowance, the flags beyond it become **locked**. Oldest flags stay editable; the newest ones lock.

<Note>
  A locked flag keeps serving its published value, so a billing lapse never
  changes behaviour on a live server. Only *editing* it is blocked — archiving
  and deleting stay allowed, since removing a flag is how you get back under the
  allowance.
</Note>

Locked flags are reported by [`GET /flags/quota`](/cloud/api-reference/flags/quota), and every flag in a list response carries a `locked` boolean.

## Archiving vs. deleting

| Action      | Effect                                                                                                                  |
| ----------- | ----------------------------------------------------------------------------------------------------------------------- |
| **Archive** | Removed from the published payload, so servers stop seeing it. The key stays reserved and cannot be reused. Reversible. |
| **Delete**  | Gone permanently, and the key becomes available again. Counts against your allowance until deleted.                     |

Archiving is the safe way to retire a flag. Reads of a missing flag fall back rather than throwing, so archiving one can never break a running server.

## How values reach your server

<Steps>
  <Step title="You change a flag">
    The API writes it to the database and republishes your organization's
    configuration payload to the edge cache.
  </Step>

  <Step title="Your server polls">
    Servers request [`GET /flags/config`](/cloud/api-reference/flags/config) with
    the `ETag` they already hold. An unchanged configuration is answered with a
    `304` and no body.
  </Step>

  <Step title="Your server publishes to clients">
    The CFX SDK writes the `shared` flags to `GlobalState`, which the game
    replicates to every player. Server-only flags never leave the server.
  </Step>
</Steps>

The `ETag` is a hash of the flags the payload contains, so an unchanged set of flags always produces the same one — and an edit that is later undone stops looking like a change.

## Audit log

Every mutation appends an entry recording the actor, the action, and the full before/after state. Flags are the kind of thing people flip during an incident and then disagree about afterwards.

| Action             | When                             |
| ------------------ | -------------------------------- |
| `flag.create`      | A flag was created               |
| `flag.update`      | Name or description changed      |
| `flag.value.set`   | The value changed                |
| `flag.runtime.set` | The runtime changed              |
| `flag.archive`     | The flag was archived            |
| `flag.unarchive`   | The flag was restored            |
| `flag.delete`      | The flag was permanently deleted |

Read it with [`GET /flags/audit`](/cloud/api-reference/flags/audit-log).

## Permissions

| Permission    | Grants                                      |
| ------------- | ------------------------------------------- |
| `FLAGS_READ`  | View flags and fetch the flag configuration |
| `FLAGS_WRITE` | Create, update, archive and delete flags    |

An API key used by a game server only needs `FLAGS_READ` — that is enough to poll the configuration endpoint.

## Start reading flags

<CardGroup cols={2}>
  <Card title="CFX SDK" icon="gamepad" href="/cloud/sdks/cfx/flags">
    Read flags from FiveM/RedM server and client scripts
  </Card>

  <Card title="NUI SDK" icon="window" href="/cloud/sdks/cfx/nui/feature-flags">
    Read flags from your NUI interfaces
  </Card>

  <Card title="Node.js SDK" icon="node-js" href="/cloud/sdks/nodejs/feature-flags">
    Read and manage flags from any Node.js app
  </Card>

  <Card title="API Reference" icon="book-open" href="/cloud/api-reference/flags/config">
    The REST endpoints behind every SDK
  </Card>
</CardGroup>
