Skip to content New SourceLoop MCP: chat with your attribution data in Claude, ChatGPT & Cursor
SourceLoop
API reference

Metrics

Aggregated metrics, breakdowns and timeseries across any dimension, with the attribution model you choose. Endpoints, parameters, and schemas.

Endpoint Method Path Permission
Get metrics Aggregate metrics, breakdowns and timeseries GET /v1/metrics metrics:read

Base URL https://app.sourceloop.ai/api/v1

Get metrics

Aggregate metrics, breakdowns and timeseries

GET /v1/metrics

Requires metrics:read

Omit `group_by` for a single total. Add it for one row per dimension value, which also returns the window totals so the share each row represents is visible. Add `granularity` for a timeseries.

Note that a total and a timeseries are different queries: unique visitors cannot be summed across days without counting returning people twice, so the aggregate is computed once across the whole window.

curl -s -X GET "https://app.sourceloop.ai/api/v1/metrics?website=acme.com&period=last%2030%20days" \
  -H "Authorization: Bearer $SOURCELOOP_API_KEY"
const res = await fetch(
  "https://app.sourceloop.ai/api/v1/metrics?website=acme.com&period=last%2030%20days",
  {
    method: "GET",
    headers: {
      Authorization: `Bearer ${process.env.SOURCELOOP_API_KEY}`,
    },
  },
);

const data = await res.json();
import os, requests

res = requests.get(
    "https://app.sourceloop.ai/api/v1/metrics?website=acme.com&period=last%2030%20days",
    headers={"Authorization": f"Bearer {os.environ['SOURCELOOP_API_KEY']}"},
)
data = res.json()

Query parameters

websitestring

Website domain, e.g. acme.com. Required only when the key covers more than one.

periodstring

Plain-language period: "last 30 days", "yesterday", "July 2026", or "2026-07-01..2026-07-31". Ignored when from/to are given.

Example last 30 days

fromstring (date-time)

tostring (date-time)

metricsstringrequired

Comma-separated.

Allowed values22

  • visitors
  • sessions
  • pageviews
  • events
  • conversions
  • revenue
  • lifetime_value
  • customers
  • avg_ltv
  • repeat_rate
  • avg_orders
  • cohort_mrr
  • revenue_per_customer
  • conversion_rate
  • pageviews_per_session
  • revenue_per_visitor
  • spend
  • impressions
  • clicks
  • roas
  • cac
  • ltv_cac

Example visitors,conversions,conversion_rate

group_bystring

Split by one dimension, or up to four comma-separated for a nested breakdown such as channel,source. Omit for a single total.

Allowed values25

  • channel
  • source
  • medium
  • campaign
  • utm_term
  • utm_content
  • referrer_domain
  • page
  • landing_page
  • hostname
  • page_title
  • country
  • region
  • city
  • device_type
  • browser
  • operating_system
  • resolution
  • platform
  • ad_campaign
  • ad_set
  • ad
  • ad_platform
  • keyword
  • cohort

Three of those are answered by a different store and behave differently:

  • platform and ad_campaign join ad SPEND to the campaign that acquired each customer, which is what makes cac and ltv_cac available. They take one dimension at a time and cannot be crossed with traffic dimensions.
  • resolution splits outcomes by WHY they had no journey (unmatched, predates tracking, imported contact) and is only available alongside credited metrics.
  • cohort returns a retention curve instead of a ranking: rows are (cohort, period_index) and the window chooses which cohorts appear, never which payments count.

filterstring[]

Repeatable, ANDed. Form: dimension:operator:value.

Operators6

  • eq
  • ne
  • in
  • nin
  • contains
  • not_contains

Filterable dimensions32

  • channel
  • source
  • medium
  • campaign
  • utm_term
  • utm_content
  • referrer_domain
  • page
  • landing_page
  • hostname
  • page_title
  • country
  • region
  • city
  • device_type
  • browser
  • operating_system
  • resolution
  • event_name
  • event_type
  • identified
  • platform
  • ad_campaign
  • ad_set
  • ad
  • ad_platform
  • keyword
  • campaign_type
  • match_type
  • company_domain
  • crm_stage
  • crm_account_stage

Example channel:in:paid_search,paid_social

granularitystring

Return a daily time series instead of a single total. Only day is supported: the underlying store buckets by calendar day in the website timezone, so hour, week and month are rejected rather than silently returning days under another label.

Allowed values 1

  • day

attributionstring

Credit conversions to a touchpoint using an attribution model instead of counting the event where the conversion fired. One of first_touch, last_touch, linear, u_shaped, time_decay, or up to five comma-separated to compare them in one response, which guarantees every model saw the same window and filters. Requires group_by, and only conversions and revenue can be attributed: a visitor has one channel at a time. When several models are given, each row nests one object per model; a null metric means that model truncated before reaching this value (see meta.truncated_models), which is not the same as zero.

Example first_touch,last_touch

outcomestring

WHAT is being counted, which is the question "what do you consider a conversion?" made explicit. Defaults to conversions, the tracked events your script recorded. The rest count a different KIND of object: contact_stage counts PEOPLE reaching a CRM stage, deal_status counts DEALS with the money on them, subscription_status counts subscriptions with MRR, payment_revenue counts individual payments, and revenue counts every money movement from the deduplicated ledger. One request counts ONE kind: 2 MQLs is not a slice of 39 conversions, it is a different object, so the two are never blended in one response. GET /v1/schema describes each with where its numbers come from; GET /v1/outcomes lists this workspace own stage keys.

Allowed values 7

  • conversions
  • conversion_type
  • contact_stage
  • deal_status
  • subscription_status
  • payment_revenue
  • revenue

Example contact_stage

outcome_valuesstring

Narrows an outcome to specific stages or types, comma separated, using the keys from GET /v1/outcomes. Omit to count every value of that kind, which is what someone asking for their funnel means. Ignored for outcomes that are not workspace-defined.

Example mql,sql

grainstring

WHO an outcome is counted over. A single B2C signup and a six-person B2B buying committee are the same shape in the data and different questions in the business. Only contact_stage offers companies, and the company view is SMALLER than the contact view rather than a slice of it: a company sits at the stage of its most advanced contact.

Allowed values 2

  • contacts
  • companies

stagesstring

Superseded by outcome and outcome_values, which say the same thing in words a caller can discover: this parameter never appeared in GET /v1/schema, so nobody could learn it existed. Still honoured, and outcome wins when both are sent.

Example deal_won

conjunctionstring

How repeated filters combine. Default and.

Allowed values 2

  • and
  • or

only_paidboolean

Restrict to paid traffic: a paid medium, or the presence of an ad click id.

limitinteger

Default 50

Responses

  • 200 Rows plus meta
  • 400 Something was wrong with the request or the credential.
  • 429 Too many requests for this workspace in the current minute. Wait Retry-After seconds and repeat the request unchanged.

Track every conversion to its true source

Capture and send full attribution data from every signup, lead, booking, and sale to your CRM and ad platforms, so you know exactly what's driving revenue.

Without SourceLoop

Untagged

Kayden Floyd

kayden@abc.com

  • SourceUnknown
  • MediumUnknown
  • CampaignUnknown
  • Landing pageUnknown
Journey
No touchpoints captured

With SourceLoop

Auto-tagged

Kayden Floyd

kayden@abc.com · Acme Co.

  • Channel Paid Social
  • CampaignFree_demo
  • Landing page/pricing
Journey
Synced to HubSpot Google Ads Meta