Skip to main content

Evaluate a variable

POST /v1/variables/{key} resolves a single variable for a user context and returns the value the platform decided to serve, plus the reason it picked it.

Request

POST /v1/variables/show-banner HTTP/1.1
Host: api.redpennon.dev
X-API-Key: 00000000-0000-0000-0000-000000000000
Content-Type: application/json

{
"user": {
"id": "user-123",
"email": "alice@example.com",
"organisation_id": "org-456",
"ip": "192.0.2.1",
"app_version": "4.12.0",
"platform": "ios",
"country": "AU",
"audiences": ["beta-testers"],
"custom_data": {
"plan": "enterprise",
"trial_days": 7
}
}
}

Path parameter

NameRequiredDescription
keyyesVariable slug, unique within the API key's project. Case-insensitive; URL-encode special chars.

Headers

HeaderRequiredDescription
X-API-KeyyesEnvironment API key (UUID). Resolves the environment and (transitively) the project.
Content-TypeyesMust be application/json.

Body

FieldTypeRequiredDescription
userobject or nullnoTargeting context. Omit (or send {}) for anonymous evaluation.

The user object's recognised keys are:

KeyTypeMaps to targeting property
idstringuser_id
emailstringemail
organisation_idstringorganisation_id
ipstringip_address
app_versionstringapp_version
platformstringplatform
countrystringcountry
audiencesstring[]audience (SDK-tagged path)
custom_dataobjectcustom_property lookups (the targeting rule's custom_key indexes into this object)

Response

Always 200 on success, including when no value is served (deleted feature, archived feature, targeting disabled, unknown key). SDKs read value and, when it's null, fall back to the developer-supplied code default.

{
"key": "show-banner",
"value": true,
"variation": "on",
"reason": "targeting_rule_matched",
"feature": "marketing-banner"
}

Fields

FieldTypeDescription
keystringEchoes the request's variable key (lowercased to match the resolver).
valuebool | number | string | object | array | nullVariable value for the served variation. null whenever no value was served (see reason).
variationstring | nullSlug of the served variation. null when no value was served.
reasonstringOne of the Reasons below.
featurestring | nullSlug of the parent feature. null for variable_not_found (the key did not resolve to any feature).
evaluation_tracestring (optional)Opaque signed token. Present only when the request included a user with a stable identity (id or email) and a variation was served. Forward this string in a subsequent POST /v1/events call to get evaluation_trace_verified = true on the stored metric event (confirms the event came from a verified evaluation).

Reasons

ReasonWhen
targeting_rule_matchedA targeting rule's conditions matched; the rule's serve_variation (or split bucket) was served.
self_targeting_overrideA self-targeting override pinned a variation for the SDK-supplied user.id + environment.
default_variationNo targeting object configured; served the variable's VariableEnvironmentState default.
no_rule_matchedTargeting was enabled but no rule matched; served the per-env default variation.
feature_completeParent feature was marked Complete; targeting is short-circuited and the env-state default is served.
targeting_disabledTargeting toggle is off for this environment. value is null — the SDK should use its code default.
variable_not_foundThe key does not resolve to a variable in this project, or the parent feature is deleted or archived.
feature_deleted(Internal) Defence-in-depth branch; the resolver normally surfaces this as variable_not_found.
feature_archived(Internal) Same as above.

Errors

StatusBodyWhen
400{"error":"Invalid JSON."}Body did not parse as JSON.
400{"error":"\"user\" must be an object."}user was sent as a non-object (e.g. a string or array).
401{"error":"Invalid or missing API key."}X-API-Key missing, malformed, or doesn't resolve.
405Standard Django 405 Method Not Allowed HTML responseAnything other than POST.

There is no 404 for an unknown variable key — the endpoint always returns 200 with reason: "variable_not_found" so SDK clients can fail open uniformly.

Example: cURL

export REDPENNON_API_KEY=00000000-0000-0000-0000-000000000000
curl -X POST "https://api.redpennon.dev/v1/variables/show-banner" \
-H "X-API-Key: $REDPENNON_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user": {"id": "user-123"}}'

Example: SDK

See the per-language docs for SDK ergonomics: Node, Python, Go.