Piano Analytics
Datafly Signal delivers events to Piano Analytics (formerly AT Internet) server-to-server using the Collection API. This sends page views, on-site search, clicks, and the full Sales Insights ecommerce funnel directly from your infrastructure — no client-side SDK, immune to ad blockers and browser tracking prevention.
Why route Piano Analytics through Datafly Signal
- Your numbers stop depending on what the browser allows. Client-side analytics loses every visit where the tag is blocked or the page unloads early. Signal delivers from the server, so Piano Analytics receives the complete event stream.
- Delivery is batched, rate-limited, and retried. Signal buffers to Kafka, respects the Piano Analytics rate limit, and retries on 429 or transient failure rather than dropping the event.
- Presets for Default and Retail. The mapping starts from a working configuration for your vertical instead of a blank field map.
- One consent decision governs every destination. Piano Analytics is gated by the same consent state as the rest of your stack, so a withdrawal applies everywhere at once.
Prerequisites
Before configuring Piano Analytics in Signal, you need an active Piano Analytics property and two pieces of information.
Step 1: Find your Site ID
- Sign in to Piano Analytics.
- Open the property you want to send data to.
- Note the numeric Site ID (also called
s) from your property settings. It looks like123456789.
Step 2: Find your Collection Domain
Piano assigns each organisation a dedicated collection domain so data is only ingested on hosts you own.
- In Piano Analytics, go to Data Collection > Collection Domains.
- Copy your assigned domain (for example
xxxxxxxx.pa-cd.com). - Use the domain without
https://and without a trailing slash.
The Collection API has no API key or access token. Your account is identified by the dedicated collection domain plus the Site ID — both are required.
Configure in Signal
Configuration Fields
| Field | Required | Description |
|---|---|---|
collection_domain | Yes | Your dedicated Piano collection domain, e.g. xxxxxxxx.pa-cd.com (no scheme, no trailing slash). |
site_id | Yes | Your numeric Piano Analytics Site ID. Sent as the required s query parameter on every event. |
Management UI Setup
Add the integration
Go to Integrations > Add Integration > Piano Analytics.
Choose a preset
- Default — page displays, on-site search, product page, add to cart, transaction confirmation, and sign-up, login, lead and subscription events.
- Retail — the Sales Insights funnel (product display and page display, add and remove, cart display, delivery and payment steps, transaction confirmation) and the rest of the ecommerce spec.
- Insurance — the policy as a Sales Insights product, plus quotes, leads, renewals, cancellations, documents and claims.
Enter your details
Fill in collection_domain and site_id.
Select consent categories
Choose the consent category that governs analytics (typically analytics). Signal maps the visitor’s analytics consent to Piano’s visitor_privacy_mode and visitor_privacy_consent properties.
Save
Click Save. Events begin delivering on the next matching browser event.
API Endpoint
Signal uses the Collection API’s documented GET form, which carries the per-visitor idclient in the query string with the site ID and the events:
GET https://{collection_domain}/event?s={site_id}&idclient={visitor_id}&events=[{"name":"page.display","data":{...}}](events is URL-encoded.) One Signal event per request; a purchase carries transaction.confirmation and a product.purchased whose items_list Piano splits into one event per product, in the same events array. Only what the preset maps is sent.
Identity Signals
| Signal | Where | Description |
|---|---|---|
idclient | Query parameter | Visitor ID: Signal’s anonymous_id (36 characters; Piano accepts 16 or 36). |
user_id | data.user_id | The signed-in user ID. |
No personal data is sent.
Consent
Signal maps the visitor’s analytics consent to Piano’s consent properties on every event:
| Analytics consent | visitor_privacy_mode | visitor_privacy_consent |
|---|---|---|
| Granted | optin | true |
| Denied (delivered under an analytics exemption) | exempt | false |
exempt requires Piano’s ePrivacy exemption to be enabled on your account. Adjust the value map on the installed integration if your organisation uses other modes.
Event Mapping
Every event carries user_id, device_timestamp_utc (event time, Unix seconds), src_medium and src_campaign (from the UTM medium and campaign) and the two consent properties.
| Signal event | Piano event | Data |
|---|---|---|
page | page.display | page (title), page_chapter1 (page_type) |
search, view_search_results | internal_search_result.display | ise_keyword |
select_item | product.display | product_* from the first item |
view_item | product.page_display | product_id (mandatory), product, product_brand, product_variant, product_category1, product_pricetaxincluded, product_quantity, product_currency |
add_to_cart, remove_from_cart | product.add_to_cart, product.remove_from_cart | as above |
view_cart | cart.display | cart_id, cart_currency, cart_turnovertaxincluded, cart_quantity, cart_nbdistinctproduct |
begin_checkout, add_payment_info | cart.delivery, cart.payment | as cart.display |
purchase | transaction.confirmation | transaction_id (mandatory), cart totals, transaction_promocode (array), shipping_costtaxincluded |
purchase (items) | product.purchased | items_list of product_id (mandatory), product, product_brand, product_variant, product_category1, product_pricetaxincluded, product_quantity (100 items max); transaction_id, cart_id, transaction_promocode at the root, copied by Piano to each product |
| Everything else | the Signal event name | every documented property |
Custom events and properties must exist in your Piano data model. Currency is upper-cased.
Example: purchase
datafly.track("purchase", {
transaction_id: "TXN-001", value: 129.99, currency: "eur", coupon: "SUMMER10",
items: [{ item_id: "SKU-A", price: 129.99, quantity: 1 }]
});GET https://xxxxxxxx.pa-cd.com/event?s=123456789&idclient=9e8d6d5f-143a-4a21-a7d5-7348b56e130d
&events=[{"name":"transaction.confirmation","data":{"transaction_id":"TXN-001","cart_currency":"EUR",
"cart_turnovertaxincluded":129.99,"cart_quantity":1,"cart_nbdistinctproduct":1,"transaction_promocode":["SUMMER10"],
"user_id":"user-123","device_timestamp_utc":1717628400,"visitor_privacy_mode":"optin","visitor_privacy_consent":true}},
{"name":"product.purchased","data":{"transaction_id":"TXN-001","transaction_promocode":["SUMMER10"],
"items_list":[{"product_id":"SKU-A","product_pricetaxincluded":129.99,"product_quantity":1}],
"user_id":"user-123","device_timestamp_utc":1717628400,"visitor_privacy_mode":"optin","visitor_privacy_consent":true}}]Testing
Trigger an event
Browse your site (or run a datafly.track() call) so an event flows through Signal.
Watch it in Signal
Open the Event Debugger in the Management UI and confirm the outgoing Piano request shows the correct name, data properties, and a 200 response.
Confirm in Piano Analytics
In Piano Analytics, open Data Flow (real-time) or run a Data Query for the last few minutes. Your page.display / transaction.confirmation events should appear, attributed to the visitor’s idclient.
Troubleshooting
| Problem | Solution |
|---|---|
| No events in Piano | Verify the collection_domain is your dedicated domain (from Data Collection > Collection Domains) and site_id is correct. A wrong domain returns 404. |
| Visitors not stitching together | Confirm idclient is present on the request URL. It is Signal’s anonymous_id. |
400 errors | A property name exceeds 40 characters or uses unsupported characters. Piano property keys must be lowercase, alphanumeric plus underscore, max 40 chars. |
| Consent treatment looks wrong | Check that the visitor_privacy_mode value map matches the consent mode names configured in your Piano privacy settings. |
| Ecommerce analyses empty | Product events require product_id (from items[0].item_id), cart events cart_id, and transaction.confirmation requires transaction_id. |