Skip to content
Browse documentation

Ad costs & ROAS

Import media spend from Google Ads, Meta, TikTok, Microsoft Advertising or a CSV, and read media cost, ROAS and net profit per campaign.

Last updated 6 min read

On this page

Integrations → Ad costs & ROAS (/app/integrations?tab=costs) imports what you spend on ads and puts it next to the revenue and payout TrackCrown tracked for the same campaigns. Importing and mapping need the Admin role.

Formulas#

MetricFormula
Media costSum of imported cost in the date range, in the workspace currency.
Revenue, PayoutApproved, non-duplicate conversions in the range whose click carried the campaign's ID, in the workspace currency.
Net profitRevenue − Payout − Media cost
ROASRevenue ÷ Media cost, shown as a percentage (250% = 2.5× return). — when cost is 0.

Pick the period with the date range in the page header. Costs are counted by cost date, conversions by conversion time.

Currencies#

Every amount on the tab is in the workspace currency. Costs (and the revenue and payout they are compared with) recorded in another currency are converted at the ECB reference rate of their day — the cost date, or the conversion date — using the latest rate published on or before that day and at most 7 days old, the same rule as conversions (Currencies & exchange rates). A converted cost shows its original currency under the amount (for example "from EUR"). Amounts without a usable rate are left out, and the alert "Amounts in … are not included" names their currencies.

Sources#

SourceHow costs arriveYou provide
Google Adsthe Google Ads API connection with Import campaign costs onnothing more
Metaad account (Graph API insights, per campaign and day)Ad account ID (act_ prefix optional), Access token (ads_read) — a system-user token of your Business Manager with ads_read on the account
TikTokad account (Marketing API report)Advertiser ID, Marketing API access token with Reporting scope
Microsoft Advertisingad account (Reporting API)Account ID, optional Customer ID, OAuth refresh token for the platform's Microsoft Advertising app (scope msads.manage)
Anything elseData supplement (CSV)a CSV file or pasted rows

Connected platforms import yesterday and today (in the workspace time zone) every 3 hours, per campaign and day, with impressions and clicks, in the ad account's currency. Older days are not back-filled automatically — import them by CSV.

Add an ad account#

  1. Under Ad accounts, choose the platform and fill in the fields above. Name is optional.
  2. Save. The token is stored encrypted and only used to read campaign spend.
  3. The account row shows its status (active, paused, error), the token hint and the last sync. The Google Ads row reads connected when the API connection imports costs.

Account menu: Edit, Pause / Resume, and delete (Remove this ad account? — imports stop and the token is deleted; costs already imported stay).

Import a CSV (data supplement)#

Use it for native, push, pop, DSPs or any source without an API.

  1. Under Data supplement (CSV) enter a Source (e.g. taboola) — used when the file has no source column.
  2. Choose a CSV file, or paste rows into …or paste rows.
  3. Click Import costs.
CSV
date,campaign_id,campaign,cost,currency,impressions,clicks
2026-10-11,4512,Native US,128.40,USD,90210,812
2026-10-11,4513,Native CA,64.10,USD,40112,355
ColumnAccepted header namesNotes
datedate, dayRequired. YYYY-MM-DD or M/D/YYYY.
costcost, spend, amountRequired. Up to 4 decimals; $ € £ and thousands separators are removed.
campaign IDcampaign_id, campaignidMatched against conversions. Without it the campaign name is used as the ID.
campaign namecampaign, campaign_nameDisplay name.
sourcesource, network, platformOverrides the Source field per row.
accountaccount, account_idOptional.
currencycurrency3-letter code; default the workspace currency.
impressions, clicksimpressions, clicksOptional.

Header names ignore case, spaces, _ and -. Fields may be separated by commas, semicolons or tabs. Up to 50,000 rows per import; invalid lines are skipped and listed (n line(s) skipped). Several lines of one file for the same date, source, account and campaign (for example one per ad) are added up into one row; such a line in a different currency than the first is skipped with an error. Importing the same date, source, account and campaign again replaces that row, so corrected files can be re-imported.

Delete imported costs#

Delete imported costs (Admin) removes the cost rows of one Source between two dates (From and To, both included) — for example a wrong CSV import. The form shows how many rows each source has and their date span. Click Delete costs… and confirm: the rows disappear from this tab, from Ad cost, ROAS and Net profit in reports and from the API. Importing the same days again brings them back; connected ad accounts re-import yesterday and today on their next sync.

How revenue is matched to a campaign#

A cost row and a conversion belong together when:

  • the conversion's click carried the same campaign ID — ValueTrack campaignid (Google), CampaignId (Microsoft), campaign_id / utm_campaign (Meta, TikTok), or any accepted alias (cid, cmp); and
  • the click's traffic source equals the cost source: google, meta, microsoft and tiktok are detected from gclid, fbclid, msclkid and ttclid. For a CSV source such as taboola, add ts=taboola to that source's tracking links so the clicks carry it.

Put the campaign ID in your links, for example for Meta:

URL
https://trackcrown.com/r/OFFER/AFF?campaign_id={{campaign.id}}&adset_id={{adset.id}}&ad_id={{ad.id}}

Campaigns table#

The Campaigns table lists every campaign with cost in the period: Campaign, Source, Cost, Ad clicks, Conversions, Revenue, Payout, Net profit, ROAS and Offer / partner. It has totals and a CSV export (media-costs). The Cost vs revenue chart shows cost, revenue and net profit per day.

Offer / partner — map a campaign to an offer (Map to offer) and optionally a Partner. The mapping is stored on the campaign's cost rows (including rows imported later) so the cost is attributed to that offer and partner. It does not change how revenue is matched — that is always by campaign ID.

In reports and the API#

The report builder, its CSV export and GET /api/v1/reports offer the metrics Ad cost (ad_cost), ROAS (roas) and Net profit (net_profit) to staff (not to partners or advertisers):

  • Ad cost is converted to the report currency at the ECB rate of the cost date; currencies without a rate are left out (the API lists them in other_currencies).
  • A cost row has a day, a source (= traffic source), a campaign ID and ad group ID, and the offer / partner it is mapped to (advertiser through the offer). Costs therefore split only by Date, Hour (the whole day at 00:00), Week, Month, Offer, Affiliate, Advertiser, Traffic source, Campaign ID and Ad group ID. Grouped by any other dimension, the cost appears on the empty (—) row.
  • An "is" filter on another dimension excludes the cost; "is not" keeps it; event and status filters leave it untouched.
  • Reports read costs from the reporting database: a new import or a deletion shows there within seconds, after the worker has copied it.

See also: Google Ads API connection · Microsoft Advertising.

Something unclear or missing in this article?Tell us