targetingKey — optionally carrying durable properties stored by fw-server.
You own the ID. The SDK never auto-generates one.
The wire still says flagKey for the control point. Identity on that call is always targetingKey.
Why it exists
Percentage assignment hashes ontargetingKey. If the key changes every request, users flip variants. Registration exists so durable facts (plan, region, device model) do not have to ride on every evaluate.
When to use it
user, org, plan, and region are not reserved SDK fields. kind on register is 'user' or 'device'. plan and region appear in examples as property names you may send — you choose the keys.
How it relates
Identity rules
- Never auto-generated. A missing targeting key is
InvalidContextwhere the evaluation needs it, never a generated anonymous id. requireTargetingKeydefaults to false on the runtime config where the language exposes it. Set ittrueif you want keyless calls rejected even in tests.
- Node
- Python
- Go
- Java
Two identity paths
These compose; they do not compete.registerTarget— durable properties stored by fw-server (POST /v1/targets/register). Call once per login or device provisioning.- Per-evaluate attributes — win for that call. Use for request-only facts.
$-prefixed attributes are backend system directives, not person properties. fw_-prefixed target property keys are reserved and stripped server-side.
Registration in every language
registerTarget exists on all seven SDKs. It never throws — it runs in sign-in paths, where a targeting concern must not break authentication. Check ok. A silently unregistered target is how targeting rules end up matching nobody.
The recorded local set is readable (
getRegisteredTargets / language equivalent) so tests can assert registration without capturing stdout. The log sink is injectable.
The protocol test server implements evaluate, capture, and /health. It does not implement POST /v1/targets/register. Register tests use local mode, mocks, or an injected fetch.
Web and Swift also expose identify: register the target, then re-prefetch under that id so percentage ramps bucket on a stable key.
What it looks like
- Node
- Web
- Python
- Go
- Java
- Rust
- Swift
Groups
Group membership and group properties travel on the evaluation context. Canonical keys:fireweave.groups and fireweave.groupProperties. Plain groups / groupProperties are accepted aliases; canonical keys win if both are present.
Any other fireweave.* context key is rejected with InvalidContext. targetingKey and kind are also reserved in the evaluation context.
Privacy
- The SDK adds no person properties of its own. Whatever you put on the context is forwarded to fw-server.
- Prefer derived attributes (
email_domain) over raw PII if you must target on identity-adjacent facts. - Error messages are secret-redacted and must not echo attribute values.
- Nothing is persisted to disk by the SDK.
Related
- Control points — evaluate with this identity
- Adapters — remote vs local vs in-memory registration
- Testing — InMemory does not persist registration; local mode does

