Dashboard

Browser

Evaluate flags from client-side code with a public token and the OFREP HTTP API.

Browser and mobile code must never hold a secret key. Use the environment's public token instead. A public token is non-secret: it can evaluate flags, but it cannot read your rules or change anything.

Toggld does not ship a browser SDK package. Call the OFREP evaluation endpoints with fetch, or use an OpenFeature OFREP provider.

Find your public token

Open Settings → API Keys. Each environment section has one Public token, marked Non-secret. Select Copy. Public tokens start with ffp_.

Your credentials
Checking your dashboard session…
Secret SDK key

Secret keys are shown only once, when you create them. Create a key

Management key

Needed for the Management API. Use a key with the management role.

Pasted keys stay in this browser tab and clear when you close it. The docs never send them anywhere. Only requests you run from the API playground use them.

Each environment has exactly one public token. Use the token of the environment that your build targets.

Evaluate one flag

Send a POST request to /ofrep/v1/evaluate/flags/{key}. Put the user's attributes under context, and include a stable targetingKey so that percentage rollouts stay consistent.

flags.ts
const API_URL = "https://api.toggld.io";
const PUBLIC_TOKEN = "ffp_YOUR_PUBLIC_TOKEN";

export async function getBooleanFlag(
  key: string,
  fallback: boolean,
  context: Record<string, unknown>,
): Promise<boolean> {
  try {
    const response = await fetch(`${API_URL}/ofrep/v1/evaluate/flags/${encodeURIComponent(key)}`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${PUBLIC_TOKEN}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ context }),
      signal: AbortSignal.timeout(3000),
    });
    if (!response.ok) return fallback;
    const result = await response.json();
    return typeof result.value === "boolean" ? result.value : fallback;
  } catch {
    return fallback; // network error or timeout
  }
}

const showNewCheckout = await getBooleanFlag("new-checkout", false, {
  targetingKey: "user-123",
  plan: "pro",
});

A successful response is HTTP 200:

{ "key": "new-checkout", "value": true, "reason": "TARGETING_MATCH", "variant": "on" }

The response has metadata when the flag has metadata.

Evaluate every flag

Send a POST request to /ofrep/v1/evaluate/flags to evaluate every flag of the environment in one request. Use it on page load, then read values from the result.

const response = await fetch("https://api.toggld.io/ofrep/v1/evaluate/flags", {
  method: "POST",
  headers: {
    Authorization: "Bearer ffp_YOUR_PUBLIC_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ context: { targetingKey: "user-123" } }),
});

const { flags } = await response.json();
const values = new Map(
  flags.filter((flag) => !("errorCode" in flag)).map((flag) => [flag.key, flag.value]),
);

const showNewCheckout = values.get("new-checkout") ?? false;

The bulk response mixes successes and per-flag failures:

{
  "flags": [
    { "key": "new-checkout", "value": true, "reason": "STATIC", "variant": "on" },
    { "key": "pricing-test", "errorCode": "TARGETING_KEY_MISSING", "errorDetails": "…" }
  ]
}

A bulk response returns HTTP 200 even when some flags fail. Check each entry for errorCode.

Handle errors

Always keep a safe fallback value in code. Use it when any of these happen:

ResponseCauseBody
Network error or timeoutThe request did not complete.None
400Evaluation failed, for example a rollout without a targeting key.{ "key", "errorCode", "errorDetails" }
400The request body is not valid JSON (PARSE_ERROR) or has the wrong shape (INVALID_CONTEXT).{ "key", "errorCode", "errorDetails" }, without key for bulk evaluation
401The token is missing or wrong.{ "_tag": "Unauthorized", "message" }
404No flag with this key exists in the environment.{ "key", "errorCode": "FLAG_NOT_FOUND" }
429You reached a rate limit. Wait for the Retry-After seconds.{ "code": "RATE_LIMITED", "message" }
503A dependency is unavailable. Retry later.Varies

See Errors for every error code.

Cross-origin requests (CORS)

The OFREP endpoints accept requests from any origin:

  • Allowed method: POST.
  • Allowed request headers: Authorization and Content-Type.
  • Exposed response header: Retry-After.
  • Cookies are not used. Do not send credentials: "include".
  • Browsers can cache the preflight response for 10 minutes.

Only the OFREP endpoints allow cross-origin requests. The Management API and the sync API do not, and public tokens cannot use them anyway.

What public tokens cannot do

ActionPublic token
Evaluate one flag or every flagYes
Download flag definitions for local evaluationNo. HTTP 403.
Read or change flags, segments, environments, or keysNo. HTTP 403.
Read analytics or the audit logNo. HTTP 403.

You cannot rotate or revoke a public token. It stops working only when you delete its environment.

Privacy and safety

  • Everything in a response is public. Anyone who loads your page can call the API with your public token and read the evaluated values and metadata. Never put secrets in variant values or metadata.
  • Rules stay private. A public token returns evaluated values only. It never returns targeting rules or segment members.
  • Send only the context you need. The context goes to Toggld with each evaluation. Evaluation analytics do not store it.
  • Use a stable targeting key. For signed-in users, use the user ID. For anonymous visitors, generate a random ID and store it, for example in local storage.

Limits

Public tokens have their own rate limits: 120 requests per minute per IP address and environment, and 6,000 requests per minute per environment across all IP addresses. Use the bulk endpoint once per page load instead of one request per flag.

The API counts these evaluations for Analytics. Do not report them again through the telemetry endpoint.

On this page