Building a custom pipeline¶
This guide walks through creating a pipeline definition from scratch: choosing event filters, counting distinct visitors per step, referencing value sets, and adding metrics and dimensions.
Prerequisites: a valid API token and your organization_id.
Base URL: https://api.giosg.com/api/objectives/v1/orgs/<organization_id>/pipeline
Step 1 — Discover your event data¶
Before writing filters, look up the vendor, category, and action combinations that exist in your data. That is the event type catalog, not a pipeline query:
1 2 3 4 5 6 7 8 | |
Use the returned triples in your steps. To inspect individual rows instead, see Listing generic events.
Step 2 — Create a pipeline definition¶
A definition needs a name and at least one step. Each step needs a name and at least one event filter.
Minimal two-step example — unique visitors who started vs clicked the widget:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
The response includes the created definition. Copy the id — you need it to run counts.
1 2 3 4 5 6 | |
count_field defaults to visitor_id (distinct visitors). You can also use session_id (distinct visits), event_id (total event occurrences), or dim1–dim5 (e.g. case number in dim3 for funnel-synced pipelines).
Naming and tagging pipelines¶
Two optional fields help you organize pipelines as you create more of them:
slug— a stable, unique-per-organization identifier (lowercase letters, digits, hyphens, underscores) you can use to fetch the pipeline later without keeping track of its UUID. Cannot collide with the predefined slugsimpressionsorshopping-cart.tags— a list of free-form labels you can filter on when listing pipelines.
1 2 3 4 5 6 | |
Look the pipeline up later by slug instead of UUID:
1 | |
Or filter the list endpoint by tag (repeat tag for multiple tags; matching is AND):
1 | |
Step 3 — Get counts¶
1 2 3 4 5 6 7 8 9 | |
Response:
1 2 3 4 5 6 7 8 | |
Each count is the number of distinct values of the step's count_field that matched that step's filters in the period. Steps are independent — there is no funnel requirement.
Reporting current state instead of totals¶
Counts answer "how many matched each step". If you instead need "where is each thing now", use last-state: each entity occupies at most one step, decided by its newest matching event.
This requires an identity_field on every event of every step — the field holding the thing you are tracking (a case number in dim3, a visitor, a session, and so on). label on case-management step events is the funnel stage UUID, not the stage name:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Retrieve the definition and check supports_last_state: true before querying. Then:
1 2 3 4 5 6 7 8 9 | |
A case that went Open → Closed appears under Closed only, so the step counts add up to the number of entities rather than overlapping.
- To also include entities that didn't move during the window, add
"include_inactive": trueand"lookback_start"(on or beforestart, at most 365 days back fromend). - To list which entities occupy a step, call
POST .../pipeline/last-state-detailwith the same window plusstep_index. That response is currently unpaginated; pagination is coming soon. - Dimension
filtersare not supported;base_filtersare.
Case-funnel sync produces a ready-made occupancy pipeline — the Case status snapshot variant. See Counts vs last-state and the last-state reference.
Value sets¶
Value sets let you store named lists of IDs (e.g. interaction IDs, goal IDs) and reference them in event filters as $name. When the pipeline runs, the reference is replaced by the list for your organization. This means you can update which IDs are tracked without modifying the pipeline definition.
Create a value set¶
1 2 3 4 5 6 7 8 | |
Repeat for any other lists you need (e.g. goal-ids). To update values later, use PATCH on the value set's URL — the pipeline definition stays unchanged.
Use a value set in a filter¶
Reference the value set by prefixing its name with $:
1 2 3 4 5 6 7 8 9 10 11 | |
At query time, $interaction-ids is resolved to ["int-abc-123", "int-def-456"] for your organization, and the step only counts events whose label matches one of those IDs.
Full example — impressions → engagement → goals, filtered by value sets:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Filtering by room¶
Add a room_ids field to any event filter to restrict that step to specific rooms. Room IDs are parsed from properties (room_id=…); a row matches if any of those IDs appear in the filter list.
1 2 3 4 5 6 7 8 9 10 11 | |
You can also use a value set reference ("room_ids": "$my-room-ids") to manage the list externally.
Filtering by event properties¶
The properties field matches entries in an event's properties array. All entries you specify must be present (AND logic). Unlike other fields, properties does not support value set references.
1 2 3 4 5 6 7 8 9 10 11 12 | |
Adding metrics to a step¶
A metric is an optional aggregation on a step that returns a grouped breakdown. Metrics are returned by the step-detail endpoint only — the counts endpoint ignores them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Translating IDs to names with mapping_functions¶
If the group_by field contains opaque IDs (goal IDs, interaction IDs), add mapping_functions to have the step-detail endpoint translate them to human-readable names:
1 2 3 4 5 6 | |
"f$goals" translates goal IDs to goal names; "f$interactions" translates interaction IDs to interaction names. Unknown IDs are kept as-is.
Marking a metric as single-period¶
Some metrics — a duration or count aggregated over a whole case, for example — aren't meaningful as a period-over-period comparison, because the events involved fall within one short timespan. Set "single_period": true so clients render a single value instead of a comparison table:
1 2 3 4 5 6 | |
You can add display hints alongside it: units and display_names (aligned with aggregations) and group_by_display_names (aligned with group_by).
Empty results
If a step has no matching events in the requested range, every metric in the step-detail response is [] — including ungrouped metrics such as a plain sum or avg with no group_by.
Defining dimensions¶
Dimensions let you slice all step counts at query time by a shared property (e.g. country, city) without modifying the definition. You declare how each step maps to the filterable property, and then pass filter values at request time.
Direct field mapping¶
Each step filters directly on the named event field. Use this when the field carries the values you want on every step. For a two-step widget pipeline where label holds the interaction ID on both steps:
1 2 3 4 5 6 7 8 9 | |
pageview_cohort_from_step is optional — it tells the API which step to use when filtering pageview counts by this dimension.
Cohort mapping¶
When a step's events don't carry the field you want to filter by, use cohort_from_step to inherit sessions from a step that does. In a three-step pipeline — Impressions (widget), Engaged (widget), Goals reached (goal) — widget events use label for interaction IDs, but goal events use label for goal IDs. The goal step can't be filtered directly by interaction ID, so it inherits sessions from step 0:
1 2 3 4 5 6 7 8 9 10 | |
Step 2 doesn't filter directly on label; instead, it only counts sessions whose session_id matched the interaction filter on step 0.
Full create request with dimensions¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
Full dimensions must have exactly one step_mapping per pipeline step (indexes 0, 1, ..., N-1). For dimensions that only apply to some steps, see partial dimensions in the reference.
Syncing a pipeline from a case funnel¶
If you already have a giosg case funnel, you can create (or refresh) five matching pipeline definitions without building steps by hand:
1 2 3 4 5 6 7 | |
mode: "update"(default) — updates the newest pipeline per variant (funnel:<funnel_id>+pipeline-variant:*), or creates that variant if none exists. Returns 200 when all were updated, 201 if any was created.mode: "create"— always creates five new pipeline definitions. Returns 201.
An empty body {} is the same as {"mode": "update"}.
What you get back — a JSON array of five pipeline definitions, one per variant:
| Name | Variant tag | Typical use |
|---|---|---|
| Case step entered | pipeline-variant:enter |
Activity volume (every entry) |
| Case step exited | pipeline-variant:movements |
Throughput + duration |
| Case step entered (1×) | pipeline-variant:enter-unique |
Reach / conversion |
| Case status snapshot | pipeline-variant:enter-last-state |
Current occupancy (/last-state) |
| Case step exited (1×) | pipeline-variant:unique |
Unique throughput + total duration |
All five get one step per funnel stage, plus case and chat dimensions on every step. Only Case status snapshot supports last-state.
Which variant answers which question: Choosing a funnel variant. Exact fields each variant receives: Sync from a case funnel.
Find synced pipelines later with:
1 | |
Or narrow to one variant:
1 | |
Then use the returned id with the counts, last-state, or step-detail endpoints as usual. Last-state requires the status-snapshot variant (or any definition with identity_field on every event).
Next steps¶
- Choosing a funnel variant — which synced pipeline answers which question
- Retrieving events — list generic or chat message rows
- Filtering counts and step detail — use the dimensions you've defined to slice counts at query time
- Pipeline API concepts — deeper explanation of every concept
- Object reference — full field tables for event filters, metrics, dimensions, and filters
- Managing definitions — full reference for slugs, tags, and syncing from a case funnel