List where visitors came from, one row per source and medium
/v1/results/analytics/sourcesLists where visitors came from: a search engine, a social network, an AI assistant such as ChatGPT, an email, or another website that linked to yours. It is the table on the Sources screen in Analytics, and takes the Analytics arguments and the table arguments.
A row is one source and one medium together, so the same source can appear on more than one row, once for each medium it arrived through. syntheticKey tells the rows apart; source and medium are the values to filter other queries by.
Direct is a fallback, not proof that someone typed the address: a visit whose referrer or campaign was not passed on is counted as direct too. Where a visitor came from is only known for visitors collected at the Cookie-free or Complete consent level.
sourceName is the name to show. Where an analytics administrator gave a source a name of their own, sourceName is that name and isLabeled is true; source stays the value Silktide recorded.
Rows are sorted by visitors, busiest first. bounceRate, pagesPerSession and topEntryUrl cannot be sorted by: a sort naming one of them answers with an error.
Send goalId to see which sources lead to a goal, and previousPeriod=1 to compare each row with the period before.
curl "https://api.eu.silktide.com/v1/results/analytics/sources?view=all&period=last-30-days&rowsPerPage=3" \
-H "Authorization: silktide token=$SILKTIDE_API_KEY"{
"result": {
"page": 1,
"minPage": 1,
"maxPage": 5,
"numRows": 15,
"rowsPerPage": 3,
"rows": [
{
"source": "",
"medium": "",
"sourceName": "Direct",
"mediumName": "Direct",
"isLabeled": false,
"sampleUrl": null,
"visitors": 285,
"pageViews": 742,
"bounceRate": 9,
"pagesPerSession": 2.5,
"topEntryUrl": "https://fakewinebarrel.com/",
"syntheticKey": "336d5ebc5436534e61d16e63ddfca327",
"sourceFilterValue": "__empty__",
"mediumFilterValue": "__empty__"
},
{
"source": "Google",
"medium": "search",
"sourceName": "Google",
"mediumName": "Search",
"isLabeled": false,
"sampleUrl": "https://www.google.com/",
"visitors": 214,
"pageViews": 556,
"bounceRate": 8,
"pagesPerSession": 2.5,
"topEntryUrl": "https://fakewinebarrel.com/",
"syntheticKey": "6b80fd09425cac18badc8834e40a836d",
"sourceFilterValue": "Google",
"mediumFilterValue": "search"
},
{
"source": "chatgpt.com",
"medium": "ai-assistant",
"sourceName": "chatgpt.com",
"mediumName": "AI assistant",
"isLabeled": false,
"sampleUrl": "https://chatgpt.com/",
"visitors": 31,
"pageViews": 78,
"bounceRate": 10,
"pagesPerSession": 2.5,
"topEntryUrl": "https://fakewinebarrel.com/wines/",
"syntheticKey": "5f1c8e0d2a7b4c3e9d6a1b0f8e2c7d4a",
"sourceFilterValue": "chatgpt.com",
"mediumFilterValue": "ai-assistant"
}
]
},
"selector": "/v1/results/analytics/sources",
"duration": 0.11
}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.columnsstringThe columns to return, comma-separated, such as
url,pageViews. Left out, the table's default columns. Send a string even in a JSON body: an array is ignored.sortstringThe column to sort by, then
:afor ascending or:dfor descending, such aspageViews:d. Left out, the table's own order.searchstringOnly rows matching this text. What it searches depends on the table, most often the URL or title.
pageintegerat least 1The page of rows to return, from
1. Defaults to1.rowsPerPageintegerat least 1How many rows a page holds. Defaults to
100.goalIdintegerat least 1A goal, by the
goalIdGet goals gives it. AddsgoalCompletionsto every row. Left out, no goal.previousPeriodstring1to 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 6 fieldsHide fields
pageintegerrequiredat least 1The page returned. Not always the page asked for, when that was out of range.
minPageintegerrequiredat least 1The first page. Always
1.maxPageintegerrequiredThe last page at this
rowsPerPage. With no rows,0or1depending on the table.numRowsintegerrequiredHow many rows there are across every page.
rowsPerPageintegerrequiredat least 1How many rows a page holds.
rowslist of objectsrequiredThe rows on this page.
Show 17 fieldsHide fields
sourcestringrequiredThe source as recorded: a known name such as
Google, a website's host such aschatgpt.com, or the link'sutm_source. Empty for direct visits. Filter by it withfilters[source].mediumstringrequiredThe medium as recorded, such as
search,social,email,ai-assistant,referral,unknown(other websites) or the link'sutm_medium. Empty for direct visits. Filter by it withfilters[medium].sourceNamestringrequiredThe source's name, as Silktide shows it: the account's label for it where one is set, and
Directfor direct visits.mediumNamestringrequiredThe medium's name, as Silktide shows it, such as
SearchorOther websites.isLabeledbooleanrequiredWhether
sourceNameis a label the account gave this source.sampleUrlstringrequiredcan be nulluriAn address on the source's website. Null when there is none, as for direct visits.
visitorsintegerrequiredUnique visitors who arrived from it.
pageViewsintegerrequiredPages those visitors viewed.
bounceRateintegerrequiredcan be null0 to 100The share of its visits that viewed one page and left, as a whole percentage. Null when none of its visits started in the period.
pagesPerSessionnumberrequiredcan be nullPages viewed per visit, to one decimal place. Null when none of its visits started in the period.
topEntryUrlstringrequiredThe page its visits most often began on. Empty when none of its visits started in the period.
syntheticKeystringrequiredThe row's id, made from its
sourceandmediumtogether. The same pair always has the same id, on every request.sourceFilterValuestringrequiredWhat to filter by to see only this source, as
filters[source]=is:{sourceFilterValue}: itssource, or__empty__for direct visits, whosesourceis empty.mediumFilterValuestringrequiredWhat to filter by to see only this medium, as
filters[medium]=is:{mediumFilterValue}: itsmedium, or__empty__for direct visits.goalCompletionsintegerHow many times its visitors completed the goal. Only with
goalId.previousVisitorsintegerUnique visitors in the period before. Only with
previousPeriod=1and aperiodother thanall.0when it had none then.previousPageViewsintegerPage views in the period before. Only with
previousPeriod=1and aperiodother thanall.0when it had none then.
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 | InvalidArgument | period is not one of its values, or is custom without both from and to. The body is an error despite the status. |
| 404 | ModelNotFound | goalId names no goal of the view. |
| 200 | - | sort names a column the table cannot sort by. Sort by sourceName, mediumName, sampleUrl, visitors, pageViews or goalCompletions only. 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.