curl --request GET \
--url https://api.datalyr.com/v1/funnel \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.datalyr.com/v1/funnel"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.datalyr.com/v1/funnel', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.datalyr.com/v1/funnel",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.datalyr.com/v1/funnel"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.datalyr.com/v1/funnel")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.datalyr.com/v1/funnel")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"steps": [
{
"step_index": 123,
"step_name": "<string>",
"visitors": 123,
"conversion_rate_from_first": 123,
"conversion_rate_from_previous": 123
}
],
"date_range": {
"start": "<string>",
"end": "<string>"
},
"complete": true,
"meta": {
"grain": "<string>",
"window_hours": 123,
"step_names": [
"<string>"
],
"step_count": 123,
"from_clamped": true,
"start_date_requested": "<string>",
"max_lookback_days": 123,
"limitation": "<string>"
}
}{
"error": "<string>"
}{
"error": "<string>"
}Get a conversion funnel
Ordered conversion funnel over 2 to 5 event names. Each returned step carries the visitors who completed every step up to and including it, in order, with all of them inside window_hours of the first step. Rates are given against step 1 and against the previous step.
Two limits are inherent to the source and are reported, not hidden. The funnel is VISITOR-grain: the source carries no person id, so one person on two devices counts as two visitors and cannot complete a single funnel. And the source retains 90 days: an earlier start_date is pulled forward to that floor and meta.from_clamped is true, while a range entirely behind the floor is a 400 rather than a funnel of zeros. A step taken after end_date is not counted even when it falls inside window_hours, so widen end_date to close that edge.
curl --request GET \
--url https://api.datalyr.com/v1/funnel \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.datalyr.com/v1/funnel"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.datalyr.com/v1/funnel', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.datalyr.com/v1/funnel",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.datalyr.com/v1/funnel"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.datalyr.com/v1/funnel")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.datalyr.com/v1/funnel")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"steps": [
{
"step_index": 123,
"step_name": "<string>",
"visitors": 123,
"conversion_rate_from_first": 123,
"conversion_rate_from_previous": 123
}
],
"date_range": {
"start": "<string>",
"end": "<string>"
},
"complete": true,
"meta": {
"grain": "<string>",
"window_hours": 123,
"step_names": [
"<string>"
],
"step_count": 123,
"from_clamped": true,
"start_date_requested": "<string>",
"max_lookback_days": 123,
"limitation": "<string>"
}
}{
"error": "<string>"
}{
"error": "<string>"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query Parameters
Comma-separated event names in funnel order, 2 to 5 of them. Empty names are rejected rather than dropped. Use /event-names to get the names this workspace tracks; an untracked name yields zero visitors, not an error.
Conversion window: every step must occur within this many hours of the first step. The maximum equals the source's 90-day retention.
1 <= x <= 2160Inclusive first event date, as YYYY-MM-DD or an ISO 8601 instant. Supply with end_date; omit both for the last 30 days. Clamped to 90 days ago.
Inclusive last event date, as YYYY-MM-DD or an ISO 8601 instant.
Response
Successful response. Visitor-grain, last 90 days only: a person on two devices is two visitors, and an earlier start is clamped with meta.from_clamped.
One entry per requested step, ascending by step_index. Always as many entries as steps named — a step nobody reached is 0, not absent.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Always true on a 200. A failed read is a 503, never a funnel of zeros.
Show child attributes
Show child attributes
Was this page helpful?