Skip to main content
decide, declare and identify reject fields they do not know, so a typo can never become a silent no-op. The message names the field, with its path for nested ones.

Causes

  • A misspelling: window_second for window_seconds, hypothesi for hypothesis. Fix the name; the allowed list in the message is the contract.
  • camelCase on the wire: userId, windowSeconds. The API takes snake_case. The server SDK accepts camelCase and converts; a hand-written request must not.
  • The wrong bucket: traits or properties on decide or identify. User facts go in identifiers, attributes or context; event facts go in properties on events. See Users, identifiers and attributes.
  • A field from another endpoint: user_id on declare (Declare configures an element without a user: user_id belong on decide, not here), or name on decide.
  • A declaration field under a publishable key: control, rewards and the rest are a 400 for a publishable key, which may send only element, user_id, identifiers, attributes, context and idempotency_key.
  • A reserved content key: a content object with a field named type (contains a field named 'type', which the format…). The format grammar uses type; rename the field.

Events are the exception

events ignores unknown fields, so an integration can forward a richer record. Two names are rejected rather than ignored: created_at (system-owned) and the retired as_of; both messages say to send the time as timestamp.

In a batch

A bad item is reported inside the 200 at its index with the same message, and never fails its siblings. Walk results for "status": "error". See Batch calls.