Turn warehouse customer intelligence into operational customer profiles — then activate them to downstream targets. Feed it raw rows from Snowflake (or any SQL store / CSV export), tell it how your columns map to the canonical shape, and it normalizes, segments, and idempotently upserts one profile per customer_key. When you're ready, push a profile to a webhook (or record an activation for your own dispatcher).
Drop this module into any Xano workspace. It ships three tables, a small public function surface, and an HTTP API group. No external credentials are required by the module itself — it operates on the rows you hand it.
Tables
| Table | Purpose |
|---|---|
c360_profile |
One canonical row per customer, keyed by customer_key (unique). Holds email, name, traits, computed segments, ltv, and last_seen. |
c360_sync_run |
One row per sync call. Records rows_in / rows_upserted / rows_failed, a status (running/success/partial/failed), and per-row errors. |
c360_activation |
One row per activation. Records the target, the payload sent, status (pending/sent/failed), attempts, and last_error. |
Public function surface (call from any XanoScript via function.run)
| Function | What it does |
|---|---|
c360_normalize_row |
Pure transform: raw warehouse row + column mapping → canonical profile object, folding extra columns into traits. |
c360_segment |
Pure transform: ltv + recency + traits → segment membership (high_value/mid_value/low_value, vip, at_risk). |
c360_sync |
Normalize + segment + idempotently upsert a batch of rows; logs a c360_sync_run. |
c360_activate |
Build a profile payload, optionally POST it to a webhook, and record a c360_activation. |
HTTP endpoints (API group customer-360-activation)
| Method | Path | Wraps |
|---|---|---|
POST |
/sync |
c360_sync |
GET |
/profiles |
list c360_profile |
GET |
/profiles/{key} |
get c360_profile by customer_key |
POST |
/activate |
c360_activate |
With the Xano MCP enabled, paste:
Install the module at https://github.com/xano-community/customer-360-activation into my Xano workspace.
git clone https://github.com/xano-community/customer-360-activation.git
cd customer-360-activation
xano workspace push backend -w <your-workspace-id>You bring the rows and a column mapping (canonical field → your source column name). The module does the rest.
// After you pull rows from your warehouse (Snowflake SQL API, an external query, a CSV import, ...):
function.run "c360_sync" {
input = {
rows: $warehouse_rows, // array of raw row objects
mapping: {
customer_key: "CUSTOMER_ID",
email: "EMAIL",
name: "FULL_NAME",
ltv: "LIFETIME_VALUE",
last_seen: "LAST_SEEN_AT"
},
trait_columns: ["PLAN", "REGION"], // extra columns folded into profile.traits
source: "snowflake"
}
} as $run
// $run -> { rows_in, rows_upserted, rows_failed, status, errors, ... }
// Later, activate a profile to a downstream target:
function.run "c360_activate" {
input = {
customer_key: "c1",
target: "webhook",
endpoint_url: $env.MY_ACTIVATION_WEBHOOK // omit to just record the activation
}
} as $activation| Segment | Rule |
|---|---|
high_value |
ltv >= 1000 |
mid_value |
250 <= ltv < 1000 |
low_value |
ltv < 250 |
vip |
traits.plan == "enterprise" |
at_risk |
inactive longer than at_risk_days (default 30) |
Rules live in c360_segment — fork it to encode your own value tiers, plan names, or recency windows. It's a pure function with unit tests, so it's safe to iterate on.
The module is storage-agnostic — it only needs row objects. A common feeder is the Snowflake SQL API:
api.request {
url = $env.SNOWFLAKE_ACCOUNT_URL ~ "/api/v2/statements"
method = "POST"
headers = ["Authorization: Bearer " ~ $env.SNOWFLAKE_ACCESS_TOKEN, "Content-Type: application/json"]
params = {statement: "SELECT * FROM ANALYTICS.CUSTOMER_360 WHERE SYNCED = FALSE"}
} as $sf
function.run "c360_sync" {
input = {rows: $sf.response.result.data, mapping: $mapping, source: "snowflake"}
} as $runOr query an external Postgres directly and feed the rows the same way.
MIT — see LICENSE.