Get how long visits lasted, step by step over a period
/v1/results/analytics/duration-over-timeReturns how long the average visit lasted in each step of a period, and across the whole of it, for an analytics view or a website.
Duration is engaged time: the seconds the visitor was actively using the pages of a visit, not how long a tab stayed open. Some visits record more engaged time than one person could have spent in them, such as colleagues behind one office network who look like a single visitor, or a computer that slept with the page open. Those are left out of the average and counted in unmeasuredSessions, with their page views in unmeasuredPageViews, so you can tell how much of the traffic the average does not cover. They are still visits, in totalSessions.
total weights each step by its measured visits, so do not average the steps to get it.
The old documentation named the average observedDuration. It is engagedDuration.
Send a period. With the default, all, this answers with an error. How long each step is, and how to choose it, is under Over time. A filters[url] filter matches the page each visit started on. Traffic collected at the Basic consent level records no visits, so it is not counted here.
curl "https://api.eu.silktide.com/v1/results/analytics/duration-over-time?view=all&period=custom&from=2026-10-01&to=2026-10-03" \
-H "Authorization: silktide token=$SILKTIDE_API_KEY"{
"result": {
"series": [
{
"time": "2026-10-01 00:00:00",
"engagedDuration": 54,
"totalSessions": 244,
"measuredSessions": 243,
"unmeasuredSessions": 1,
"sessionPageViews": 546,
"unmeasuredPageViews": 12
},
{
"time": "2026-10-02 00:00:00",
"engagedDuration": 58,
"totalSessions": 254,
"measuredSessions": 254,
"unmeasuredSessions": 0,
"sessionPageViews": 586,
"unmeasuredPageViews": 0
},
{
"time": "2026-10-03 00:00:00",
"engagedDuration": 62,
"totalSessions": 236,
"measuredSessions": 236,
"unmeasuredSessions": 0,
"sessionPageViews": 670,
"unmeasuredPageViews": 0
}
],
"total": 57.96180081855389,
"range": {
"start": "2026-10-01 00:00:00",
"end": "2026-10-04 00:00:00"
}
},
"selector": "/v1/results/analytics/duration-over-time",
"duration": 0.011
}Request
Query parameters
viewstringmatches^(all|[1-9]\d*)$The analytics view to read: its id, the number after
/analytics/in its address in Silktide, orallfor all of the account's analytics. Send this orwebsiteId.websiteIdintegerat least 1Instead of
view, a website whose analytics to read. The website must have Analytics set up.sectionIdintegerWith
websiteId, a section of the website. Defaults to0, the whole website.periodstringThe date range. Defaults to
all. The spaced forms (-7 days,month to date) are older names that keep working.customneedsfromandto.One of
alltodaylast-7-dayslast-30-dayslast-90-daysmonth-to-datelast-monthyear-to-datelast-12-monthscustom-7 days-30 days-90 days-1 monthmonth to dateyear to date-12 monthsfromstringWith
period=custom, the first day, such as2026-10-01.tostringWith
period=custom, the last day.timezonestringThe IANA time zone days are read in, such as
America/New_York. Defaults toUTC.filtersmap of stringsOnly visits matching every filter, keyed by what is filtered:
filters[url]=contains:/blog. Each value is{operator}:{value}, with operatoris,not,contains,starts,gtorlt. Keys includeurl,hostName,entryUrl,exitUrl,event,outgoingUrl,referrer,source,medium,campaign,content,term,countryCode,regionCode,language,deviceType(desktop,tabletormobile),operatingSystemandbrowser.intervalstringWith
period=custom, the length of each step: an hour, a day, a week starting on Monday, a month or a year. Ignored with any other period. Left out, steps are hours for a single day, months for exactly twelve months, and days otherwise.One of
PT1HP1DP7DP1MP1YpreviousPeriodstring1to add the figures of the period before, the same length and ending where this one starts, asprevious…fields. Left out or0, none. Needs aperiodwith a start: withall, nothing is added.One of
01
Response
200JSON.
resultobjectrequiredThe answer.
Show 4 fieldsHide fields
serieslist of objectsrequiredOne step per hour, day, week or month of the period, oldest first. A step with no visits reads
0throughout.Show 13 fieldsHide fields
timestringrequiredmatches^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$When the step starts, as
YYYY-MM-DD HH:MM:SSin the request'stimezone.engagedDurationintegerrequiredThe average seconds a visit in the step was actively used, over its measured visits, rounded to a whole second.
0when it had none.totalSessionsintegerrequiredEvery visit in the step.
measuredSessionsintegerrequiredThe visits the average is over.
unmeasuredSessionsintegerrequiredVisits left out of the average because their engaged time could not be one person's.
sessionPageViewsintegerrequiredPage views in all of the step's visits.
unmeasuredPageViewsintegerrequiredPage views in the visits left out of the average.
previousEngagedDurationintegercan be nullThe average engaged seconds in the matching step of the period before. Only with
previousPeriod=1. Null when that period has no step in the same place, which weekly and monthly steps can cause.previousTotalSessionsintegercan be nullEvery visit in the matching step of the period before. Only with
previousPeriod=1. Null when that period has no step in the same place, which weekly and monthly steps can cause.previousMeasuredSessionsintegercan be nullMeasured visits in the matching step of the period before. Only with
previousPeriod=1. Null when that period has no step in the same place, which weekly and monthly steps can cause.previousUnmeasuredSessionsintegercan be nullVisits left out in the matching step of the period before. Only with
previousPeriod=1. Null when that period has no step in the same place, which weekly and monthly steps can cause.previousSessionPageViewsintegercan be nullPage views in visits in the matching step of the period before. Only with
previousPeriod=1. Null when that period has no step in the same place, which weekly and monthly steps can cause.previousUnmeasuredPageViewsintegercan be nullPage views in visits left out in the matching step of the period before. Only with
previousPeriod=1. Null when that period has no step in the same place, which weekly and monthly steps can cause.
totalnumberrequiredThe average engaged seconds of a visit across the whole period, not rounded: each step's average weighted by its measured visits.
rangeobjectrequiredThe dates the series covers.
Show 2 fieldsHide fields
startstringrequiredmatches^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$When the first step starts, as
YYYY-MM-DD HH:MM:SSin the request'stimezone.endstringrequiredmatches^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$When the range ends, as
YYYY-MM-DD HH:MM:SS: midnight after its last day, so the range runs up to but not including it.
previousTotalnumberThe same average across the period before. Only with
previousPeriod=1.
selectorstringrequiredThe query that answered, as its path:
/v1/results/scores.durationnumberrequiredSeconds Silktide took to answer.
Errors
| Status | Type | When |
|---|---|---|
| 404 | ModelNotFound | No view or website with that id exists in the account, or the API key's user cannot see it. |
| 403 | AccessDenied | The API key's user cannot read that analytics view. |
| 200 | ModelNotFound | The website has no Analytics set up. The body is an error despite the status. |
| 200 | InvalidRequest | Neither view nor websiteId was sent. The error's own status is 400 and properties.field is view. The body is an error despite the status. |
| 200 | InvalidArgument | A filter names a key or operator Analytics does not know. The body is an error despite the status. |
| 200 | Error | period is all or left out, which means all. Over-time queries need a period with a start. The body is an error despite the status. |
| 200 | InvalidArgument | period is not one of its values, or is custom without both from and to. The body is an error despite the status. |
| 200 | Unspecified | interval is not one of its values. The body is an error despite the status. |
| 401 | NotLoggedIn | No API key was sent, or it is not a key for this region.(any operation) |
| 429 | TooManyRequests | Too many requests to this path in five seconds. Retry after the number of seconds in the Retry-After header, which properties.retryAfter repeats.(any operation) |
| 503 | - | Silktide is busy. Retry after the number of seconds in the Retry-After header.(any operation) |
Every error has the same body. See Errors.
Access
- Permission
- View analytics view (View all analytics for `view=all`)
- Plan feature
- None
- Edition
- Silktide 4 and Silktide 5
- Cost
- Free
- Available since
- v1.0.0
Try it
Sends a real request to your account from this browser. Your key stays in this tab and goes only to the Silktide API.