Chameleon
Chameleon is a product adoption platform for building in-product Experiences — Tours, Microsurveys, Launchers, and Tooltips. Datafly Signal forwards your first-party events to Chameleon’s Observe API server-side, so you can target Experiences in real time on what users actually do, without adding another client-side script.
Because Signal delivers from your own server, Chameleon receives events even when the browser is offline, an ad blocker is active, or the user has navigated away.
Why route Chameleon through Datafly Signal
- Profiles are updated from the server, not the browser. Events reach Chameleon even when a tracker blocker or a failed page unload would have dropped a client-side call, so the profile reflects what actually happened.
- One consent decision governs every destination. Chameleon is gated by the same consent state as the rest of your stack, so a withdrawal applies everywhere at once.
Prerequisites
- A Chameleon account with the Observe (events) feature enabled.
- A Chameleon Secret API key. Generate one in Chameleon under Settings → Tokens (
app.chameleon.io/settings/tokens). Use the Secret API key, not the public account token — the account token is rejected with a401once identity verification is enabled. Tokens can only be downloaded once, so store it securely. - The same user identifier (
uid) you pass to Chameleon’s in-app snippet (chmln.identify(uid, ...)). Events must carry the sameuidso Chameleon attaches them to the right profile.
Configuration
| Field | Required | Description |
|---|---|---|
| Account Secret (Secret API Key) | Yes | Your Chameleon Secret API key, sent as the X-Account-Secret header. |
Configure in Signal
- In the Signal dashboard, open Integrations and add Chameleon.
- Paste your Account Secret (Secret API Key).
- Attach the Chameleon blueprint to a pipeline. The default Product / SaaS preset maps
page,Signed Up,Logged In,Feature Used,Trial Started, andOrder Completed. - Save and enable the pipeline.
API Endpoint
Signal delivers each event with a POST to Chameleon’s Observe events hook:
POST https://api.chameleon.io/v3/observe/hooks/events
X-Account-Secret: <your Secret API key>
Content-Type: application/jsonA successful response returns the created event id:
{ "event": { "id": "5f3c4232c712de665632a2a3" } }Identity Signals
Chameleon attaches each event to a user profile using the identity fields in the payload. At least one of these must be present:
| Signal field | Chameleon field | Notes |
|---|---|---|
user_id | uid | Your backend user id. Should match the uid passed to chmln.identify(). Required by the default preset. |
email (trait) | email | Used to resolve a profile when no uid is available. |
Chameleon stores raw first-party identifiers, so Signal does not hash uid or email for this integration. There is no advertising consent field on the Observe API — this is first-party product-adoption data — so no consent mapping is applied.
Event Mapping
The event name is sent in the required name field. All other mapped properties are delivered as flat custom event properties; Chameleon normalises property names to lower_snake_case on ingest and stores up to 768 bytes per scalar value.
| Signal event | Chameleon name |
|---|---|
page | Page Viewed |
Signed Up | Signed Up |
Logged In | Logged In |
Feature Used | Feature Used |
Trial Started | Trial Started |
Order Completed | Order Completed |
Example
A Feature Used event sent from Datafly.js:
datafly.track("Feature Used", {
feature_name: "csv_export",
feature_area: "reports"
});Resulting payload delivered to Chameleon:
{
"uid": "user_8821",
"email": "leon@example.com",
"name": "Feature Used",
"feature_name": "csv_export",
"feature_area": "reports"
}Testing
- Trigger an event on your site (for example, sign up or use a tracked feature) with a known
uid. - In Chameleon, open the matching User Profile and confirm the event appears in the activity timeline within a few seconds.
- Build an Experience targeted on that event and confirm it triggers for the user.
- In Signal’s Event Debugger, confirm the outbound request returned a
200with anevent.idin the response.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
401 Unauthorized | Using the public account token instead of the Secret API key, or identity verification is enabled. | Generate and use the Secret API key from Settings → Tokens. |
400 Bad Request | Missing name, or neither uid nor email present. | Ensure the event has a name and the pipeline maps user_id or an email trait. |
| Event delivered but no Experience fires | uid does not match the value passed to chmln.identify(). | Align the uid Signal sends with the one used in the in-app snippet. |
| Custom property missing in Chameleon | Property exceeds 768 bytes, or was not mapped. | Shorten the value and confirm the mapping exists in the blueprint. |