Skip to content
Menu
SilktideDevelopers

List where visitors came from, one row per source and medium

GET/v1/results/analytics/sources
View as Markdown

Lists 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.

Request
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"
Response: The top sources over the last 30 days
{
  "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, or all for all of the account's analytics. Send this or websiteId.

  • websiteIdintegerat least 1

    Instead of view, a website whose analytics to read. The website must have Analytics set up.

  • sectionIdinteger

    With websiteId, a section of the website. Defaults to 0, the whole website.

  • periodstring

    The date range. Defaults to all. The spaced forms (-7 days, month to date) are older names that keep working. custom needs from and to.

    One ofalltodaylast-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 months

  • fromstring

    With period=custom, the first day, such as 2026-10-01.

  • tostring

    With period=custom, the last day.

  • timezonestring

    The IANA time zone days are read in, such as America/New_York. Defaults to UTC.

  • filtersmap of strings

    Only visits matching every filter, keyed by what is filtered: filters[url]=contains:/blog. Each value is {operator}:{value}, with operator is, not, contains, starts, gt or lt. Keys include url, hostName, entryUrl, exitUrl, event, outgoingUrl, referrer, source, medium, campaign, content, term, countryCode, regionCode, language, deviceType (desktop, tablet or mobile), operatingSystem and browser.

  • columnsstring

    The 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.

  • sortstring

    The column to sort by, then :a for ascending or :d for descending, such as pageViews:d. Left out, the table's own order.

  • searchstring

    Only rows matching this text. What it searches depends on the table, most often the URL or title.

  • pageintegerat least 1

    The page of rows to return, from 1. Defaults to 1.

  • rowsPerPageintegerat least 1

    How many rows a page holds. Defaults to 100.

  • goalIdintegerat least 1

    A goal, by the goalId Get goals gives it. Adds goalCompletions to every row. Left out, no goal.

  • previousPeriodstring

    1 to add the figures of the period before, the same length and ending where this one starts, as previous… fields. Left out or 0, none. Needs a period with a start: with all, nothing is added.

    One of01

Response

200JSON.

  • resultobjectrequired

    The answer.

    Show 6 fields
    • pageintegerrequiredat least 1

      The page returned. Not always the page asked for, when that was out of range.

    • minPageintegerrequiredat least 1

      The first page. Always 1.

    • maxPageintegerrequired

      The last page at this rowsPerPage. With no rows, 0 or 1 depending on the table.

    • numRowsintegerrequired

      How many rows there are across every page.

    • rowsPerPageintegerrequiredat least 1

      How many rows a page holds.

    • rowslist of objectsrequired

      The rows on this page.

      Show 17 fields
      • sourcestringrequired

        The source as recorded: a known name such as Google, a website's host such as chatgpt.com, or the link's utm_source. Empty for direct visits. Filter by it with filters[source].

      • mediumstringrequired

        The medium as recorded, such as search, social, email, ai-assistant, referral, unknown (other websites) or the link's utm_medium. Empty for direct visits. Filter by it with filters[medium].

      • sourceNamestringrequired

        The source's name, as Silktide shows it: the account's label for it where one is set, and Direct for direct visits.

      • mediumNamestringrequired

        The medium's name, as Silktide shows it, such as Search or Other websites.

      • isLabeledbooleanrequired

        Whether sourceName is a label the account gave this source.

      • sampleUrlstringrequiredcan be nulluri

        An address on the source's website. Null when there is none, as for direct visits.

      • visitorsintegerrequired

        Unique visitors who arrived from it.

      • pageViewsintegerrequired

        Pages those visitors viewed.

      • bounceRateintegerrequiredcan be null0 to 100

        The 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 null

        Pages viewed per visit, to one decimal place. Null when none of its visits started in the period.

      • topEntryUrlstringrequired

        The page its visits most often began on. Empty when none of its visits started in the period.

      • syntheticKeystringrequired

        The row's id, made from its source and medium together. The same pair always has the same id, on every request.

      • sourceFilterValuestringrequired

        What to filter by to see only this source, as filters[source]=is:{sourceFilterValue}: its source, or __empty__ for direct visits, whose source is empty.

      • mediumFilterValuestringrequired

        What to filter by to see only this medium, as filters[medium]=is:{mediumFilterValue}: its medium, or __empty__ for direct visits.

      • goalCompletionsinteger

        How many times its visitors completed the goal. Only with goalId.

      • previousVisitorsinteger

        Unique visitors in the period before. Only with previousPeriod=1 and a period other than all. 0 when it had none then.

      • previousPageViewsinteger

        Page views in the period before. Only with previousPeriod=1 and a period other than all. 0 when it had none then.

  • selectorstringrequired

    The query that answered, as its path: /v1/results/scores.

  • durationnumberrequired

    Seconds Silktide took to answer.

Errors

StatusTypeWhen
404ModelNotFoundNo view or website with that id exists in the account, or the API key's user cannot see it.
403AccessDeniedThe API key's user cannot read that analytics view.
200ModelNotFoundThe website has no Analytics set up. The body is an error despite the status.
200InvalidRequestNeither 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.
200InvalidArgumentA filter names a key or operator Analytics does not know. The body is an error despite the status.
200InvalidArgumentperiod is not one of its values, or is custom without both from and to. The body is an error despite the status.
404ModelNotFoundgoalId 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.
401NotLoggedInNo API key was sent, or it is not a key for this region.(any operation)
429TooManyRequestsToo 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.