# /integration
Source: https://docs.contentignite.com/api-reference/[in-progress]-integration/integration
/openapi.json get /v1/integration
Fetches a list of integrations that are connected into the logged in organisation
# /integration/:id/stack-schema
Source: https://docs.contentignite.com/api-reference/[in-progress]-integration/integration:idstack-schema
/openapi.json get /v1/integration/{id}/stack-schema
Fetches general itengration info and the ad stack field schema for the given integration, schema is in JSON-schema format
# /integration/:id/validate
Source: https://docs.contentignite.com/api-reference/[in-progress]-integration/integration:idvalidate
/openapi.json post /v1/integration/{id}/stack-schema
Fetches general itengration info and the ad stack field schema for the given integration, schema is in JSON-schema format
# /account/branding
Source: https://docs.contentignite.com/api-reference/[in-progress]-useraccount/accountbranding
/openapi.json get /v1/account/branding
Fetches branding for the refering domain
# /ad-stack
Source: https://docs.contentignite.com/api-reference/ad-stack/ad-stack
/openapi.json get /v1/ad-stack
Fetches a list of ad stacks in use by the provided publisher
# /ad-stack
Source: https://docs.contentignite.com/api-reference/ad-stack/ad-stack-1
/openapi.json post /v1/ad-stack
Creates a new ad stack. Call the `/v1/integration?target=ad_stack` endpoint to find available integrations, and call the `/v1/integration/{id}/stack-schema` endpoint to find the field requirements for each integration.
# /ad-stack/:id
Source: https://docs.contentignite.com/api-reference/ad-stack/ad-stack:id
/openapi.json get /v1/ad-stack/{id}
Gets an individual ad stack and all the integrations connected to it
# /ad-stack/:id
Source: https://docs.contentignite.com/api-reference/ad-stack/ad-stack:id-1
/openapi.json put /v1/ad-stack/{id}
Updates an existing ad stack. Call the `/v1/integration?target=ad_stack` endpoint to find available integrations, and call the `/v1/integration/{id}/stack-schema` endpoint to find the field requirements for each integration.
# /ad-stack/:id
Source: https://docs.contentignite.com/api-reference/ad-stack/ad-stack:id-2
/openapi.json delete /v1/ad-stack/{id}
Deletes the given ad stack
# /ad-stack/integration
Source: https://docs.contentignite.com/api-reference/ad-stackintegration/ad-stackintegration
/openapi.json get /v1/ad-stack/integration
Fetches a list of integrations that could be used to build an ad stack under the given publisher
# /ad-stack/integration/:type/:id
Source: https://docs.contentignite.com/api-reference/ad-stackintegration/ad-stackintegration:type:id
/openapi.json get /v1/ad-stack/integration/{type}/{id}
Fetches an individual integration, The response includes everything needed to configure that integration within an ad stack, such as the schema for any config fields
# /ad-stack/integration/:type/:id
Source: https://docs.contentignite.com/api-reference/ad-stackintegration/ad-stackintegration:type:id-1
/openapi.json post /v1/ad-stack/integration/{type}/{id}
Validate the configuration of a given integration. Each integrations requirements vary, so use this endpoint to check all requirements have been met
# /billing/invoice
Source: https://docs.contentignite.com/api-reference/billinginvoice/billinginvoice
/openapi.json get /v1/billing/invoice
Fetches a list of invoices for the logged in organisation
# /billing/invoice/:id
Source: https://docs.contentignite.com/api-reference/billinginvoice/billinginvoice:id
/openapi.json get /v1/billing/invoice/{id}
Fetches a specific invoice
# /organisation
Source: https://docs.contentignite.com/api-reference/organisation/organisation
/openapi.json get /v1/organisation
Returns a list containing the active organisation, and any child organisations
# /organisation
Source: https://docs.contentignite.com/api-reference/organisation/organisation-1
/openapi.json post /v1/organisation
Creates a new child organisation under the currently logged in organisation
# /organisation/:id
Source: https://docs.contentignite.com/api-reference/organisation/organisation:id
/openapi.json get /v1/organisation/{id}
Fetches a single organisation
# /organisation/:id
Source: https://docs.contentignite.com/api-reference/organisation/organisation:id-1
/openapi.json put /v1/organisation/{id}
Updates an existing organisation
# /organisation/:id
Source: https://docs.contentignite.com/api-reference/organisation/organisation:id-2
/openapi.json delete /v1/organisation/{id}
Deletes a child organisation
# /organisation/:id/mapping
Source: https://docs.contentignite.com/api-reference/organisationorganisation-meta/organisation:idmapping
/openapi.json get /v1/organisation/{id}/mapping
Fetches all integrations that suport organisation mapping, the schemas and the data for each
# /organisation/:id/roles
Source: https://docs.contentignite.com/api-reference/organisationorganisation-meta/organisation:idroles
/openapi.json get /v1/organisation/{id}/roles
Returns a list of users that have access to the given organisation
# /organisation/:id/pricing
Source: https://docs.contentignite.com/api-reference/organisationpricing/organisation:idpricing
/openapi.json get /v1/organisation/{id}/pricing
Returns a list of pricing rules; data based periods of pricing settings made up of tech/saas fees, demand revenue shares and fixed fees
# /organisation/:id/pricing
Source: https://docs.contentignite.com/api-reference/organisationpricing/organisation:idpricing-1
/openapi.json post /v1/organisation/{id}/pricing
Create a new pricing period. New period must be in the future to be valid
# /organisation/:id/pricing/:pid
Source: https://docs.contentignite.com/api-reference/organisationpricing/organisation:idpricing:pid
/openapi.json put /v1/organisation/{id}/pricing/{pid}
Updates a pricing period. Period must be in the future as historic or active periods can not be modified (create a new period if needed)
# /organisation/:id/pricing/:pid
Source: https://docs.contentignite.com/api-reference/organisationpricing/organisation:idpricing:pid-1
/openapi.json delete /v1/organisation/{id}/pricing/{pid}
Deletes a pricing period, Period must be in the future as historic or active periods can not be modified
# /publisher
Source: https://docs.contentignite.com/api-reference/publisher/publisher
/openapi.json get /v1/publisher
List all publishers under the loggedin organisation, and some top level configuration
# /publisher
Source: https://docs.contentignite.com/api-reference/publisher/publisher-1
/openapi.json post /v1/publisher
Creates a new publisher from the given domain
# /publisher/:uid
Source: https://docs.contentignite.com/api-reference/publisher/publisher:uid
/openapi.json get /v1/publisher/{uid}
Fetches all the publisher level settings for the given publisher
# /publisher/:uid
Source: https://docs.contentignite.com/api-reference/publisher/publisher:uid-1
/openapi.json put /v1/publisher/{uid}
Sets the publisher level configuration for the given publisher
# /publisher/:uid
Source: https://docs.contentignite.com/api-reference/publisher/publisher:uid-2
/openapi.json delete /v1/publisher/{uid}
Permenantly archives the given publisher, this will stop the tag from serving ads
# /tag/:uid/placement
Source: https://docs.contentignite.com/api-reference/publisherapp-placement/tag:uidplacement
/openapi.json get /v1/tag/{uid}/placement
Fetch a list of all app placements under the given publisher
# /tag/:uid/placement
Source: https://docs.contentignite.com/api-reference/publisherapp-placement/tag:uidplacement-1
/openapi.json post /v1/tag/{uid}/placement
Creates a new app placement
# /tag/:uid/placement/:id
Source: https://docs.contentignite.com/api-reference/publisherapp-placement/tag:uidplacement:id
/openapi.json get /v1/tag/{uid}/placement/{id}
Fetch the app placement from the given placement ID
# /tag/:uid/placement/:id
Source: https://docs.contentignite.com/api-reference/publisherapp-placement/tag:uidplacement:id-1
/openapi.json put /v1/tag/{uid}/placement/{id}
Updates an existing app placement
# /tag/:uid/placement/:id
Source: https://docs.contentignite.com/api-reference/publisherapp-placement/tag:uidplacement:id-2
/openapi.json delete /v1/tag/{uid}/placement/{id}
Deletes the given app placement.
# /tag/:uid/config
Source: https://docs.contentignite.com/api-reference/publisherconfig-ad-unit/tag:uidconfig
/openapi.json get /v1/tag/{uid}/config
Fetches the list of configs under the given publisher
# /tag/:uid/config
Source: https://docs.contentignite.com/api-reference/publisherconfig-ad-unit/tag:uidconfig-1
/openapi.json post /v1/tag/{uid}/config
Creates a new config under the given publisher
# /tag/:uid/config/:id
Source: https://docs.contentignite.com/api-reference/publisherconfig-ad-unit/tag:uidconfig:id
/openapi.json get /v1/tag/{uid}/config/{id}
Fetches a single publisher config (ad unit)
# /tag/:uid/config/:id
Source: https://docs.contentignite.com/api-reference/publisherconfig-ad-unit/tag:uidconfig:id-1
/openapi.json put /v1/tag/{uid}/config/{id}
Updates and existing config
# /tag/:uid/config/:id
Source: https://docs.contentignite.com/api-reference/publisherconfig-ad-unit/tag:uidconfig:id-2
/openapi.json delete /v1/tag/{uid}/config/{id}
Deletes a config
# /tag/:uid/experiment
Source: https://docs.contentignite.com/api-reference/publisherexperiment/tag:uidexperiment
/openapi.json get /v1/tag/{uid}/experiment
Returns a list of experiments for a given publisher
# /tag/:uid/experiment
Source: https://docs.contentignite.com/api-reference/publisherexperiment/tag:uidexperiment-1
/openapi.json post /v1/tag/{uid}/experiment
Creates an experiment, where 2 or more configs are run against one another
# /tag/:uid/experiment/:id
Source: https://docs.contentignite.com/api-reference/publisherexperiment/tag:uidexperiment:id
/openapi.json get /v1/tag/{uid}/experiment/{id}
Get the configuration for a given experiment
# /tag/:uid/experiment/:id
Source: https://docs.contentignite.com/api-reference/publisherexperiment/tag:uidexperiment:id-1
/openapi.json put /v1/tag/{uid}/experiment/{id}
Updates an existing config. Actions are restricted for live experiments, to just modifying dates and the title & description
# /tag/:uid/experiment/:id
Source: https://docs.contentignite.com/api-reference/publisherexperiment/tag:uidexperiment:id-2
/openapi.json delete /v1/tag/{uid}/experiment/{id}
Terminates an experiment immediately
# /tag/:uid/experiment/:id/activate-winner
Source: https://docs.contentignite.com/api-reference/publisherexperiment/tag:uidexperiment:idactivate-winner
/openapi.json put /v1/tag/{uid}/experiment/{id}/activate-winner
Activates the winnning config of an experiment. This can be run upon completion, or during an experiment, where the experiment will be immmediately terminated
# /tag/:uid/experiment/compare
Source: https://docs.contentignite.com/api-reference/publisherexperiment/tag:uidexperimentcompare
/openapi.json get /v1/tag/{uid}/experiment/compare
Takes a list of configs, and returns the differences between them. Used before creating an experiment to confirm the bahavioural subject(s) that the experiment will be testing
# /publisher/:uid/overview
Source: https://docs.contentignite.com/api-reference/publisherpublisher-meta/publisher:uidoverview
/openapi.json get /v1/publisher/{uid}/overview
Returns the top level configuration for the given publisher
# /publisher/:uid/owners
Source: https://docs.contentignite.com/api-reference/publisherpublisher-meta/publisher:uidowners
/openapi.json get /v1/publisher/{uid}/owners
Fetch a list of organisations that are in the owner hierachy of the given publisher, useful for populating the O&O (Owned & Operated) field on the publisher
# /publisher/:uid/stats
Source: https://docs.contentignite.com/api-reference/publisherpublisher-meta/publisher:uidstats
/openapi.json get /v1/publisher/{uid}/stats
Provides some top line stats for the given publisher, useful for giving a quick visual insight into common metrics
# /publisher/:uid/status
Source: https://docs.contentignite.com/api-reference/publisherpublisher-meta/publisher:uidstatus
/openapi.json get /v1/publisher/{uid}/status
Provides the onboarding tasks for the given publisher, and their status
# /pub-stack/:uid/integration
Source: https://docs.contentignite.com/api-reference/publisherpublisher-stack/pub-stack:uidintegration
/openapi.json get /v1/pub-stack/{uid}/integration
Fetches a list of publisher level integrations that could be connected to the given publisher
# /pub-stack/:uid/integration
Source: https://docs.contentignite.com/api-reference/publisherpublisher-stack/pub-stack:uidintegration-1
/openapi.json post /v1/pub-stack/{uid}/integration
Creates an association between a publisher and a publisher level integration (adding it to the "Pub stack")
# /pub-stack/:uid/integration/:id
Source: https://docs.contentignite.com/api-reference/publisherpublisher-stack/pub-stack:uidintegration:id
/openapi.json get /v1/pub-stack/{uid}/integration/{id}
Fetches the field schema and data for a single connected integration
# /pub-stack/:uid/integration/:id
Source: https://docs.contentignite.com/api-reference/publisherpublisher-stack/pub-stack:uidintegration:id-1
/openapi.json put /v1/pub-stack/{uid}/integration/{id}
Updates an existing integration association
# /pub-stack/:uid/integration/:id
Source: https://docs.contentignite.com/api-reference/publisherpublisher-stack/pub-stack:uidintegration:id-2
/openapi.json delete /v1/pub-stack/{uid}/integration/{id}
Deletes the assosication between the publisher and an integration
# /tag/:uid/email/preview
Source: https://docs.contentignite.com/api-reference/publisherpublisher-tag/tag:uidemailpreview
/openapi.json get /v1/tag/{uid}/email/preview
Provides an email template for onboarding a publisher. It contains the tag that needs to be deployed and the ads.txt requirents
# /tag/:uid/status
Source: https://docs.contentignite.com/api-reference/publisherpublisher-tag/tag:uidstatus
/openapi.json get /v1/tag/{uid}/status
Fetches the status of the publisher tag and the app sdk for the given publisher
# /report/stats
Source: https://docs.contentignite.com/api-reference/reporting/reportstats
/openapi.json get /v1/dash/stats
Quick network wide stats, ideal for a landing dashboard usage
# /report/adstxt
Source: https://docs.contentignite.com/api-reference/reportingadstxt/reportadstxt
/openapi.json get /v1/report/adstxt
Fetches a simple overview of every publisher in the given networks ads.txt file
# /report/adstxt/:uid
Source: https://docs.contentignite.com/api-reference/reportingadstxt/reportadstxt:uid
/openapi.json get /v1/report/adstxt/{uid}
Fetches the ads.txt requirements for the given publisher
# /report/app-adstxt/:uid
Source: https://docs.contentignite.com/api-reference/reportingadstxt/reportapp-adstxt:uid
/openapi.json get /v1/report/app-adstxt/{uid}
Fetches the app-ads.txt requirements for the given publisher
# /report/campaign
Source: https://docs.contentignite.com/api-reference/reportingcampaign-reports/reportcampaign
/openapi.json get /v1/report/campaign
Fetches a list of campaign reports, including details such as campaign ID, campaign name, start and end dates, publisher, and status. Use this endpoint to obtain an overview of all campaigns and their current states.
# /report/campaign/:id
Source: https://docs.contentignite.com/api-reference/reportingcampaign-reports/reportcampaign:id
/openapi.json get /v1/report/campaign/{id}
# /report/experiment
Source: https://docs.contentignite.com/api-reference/reportingexperiment-reporting/reportexperiment
/openapi.json get /v1/report/experiment
Fetch a list of experiments with their status and top line configuration
# /report/experiment/:id
Source: https://docs.contentignite.com/api-reference/reportingexperiment-reporting/reportexperiment:id
/openapi.json get /v1/report/experiment/{id}
Fetches a full report for the given experiment
# /report/health-check
Source: https://docs.contentignite.com/api-reference/reportinghealth-check/reporthealth-check
/openapi.json get /v1/report/health-check
Retrieves a list of publisher health check reports
# /report/health-check/:uid/:id
Source: https://docs.contentignite.com/api-reference/reportinghealth-check/reporthealth-check:uid:id
/openapi.json get /v2/report/health-check/{uid}/{id}
Returns a single health check report
# /report/insight/ads-txt
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubadstxt-insights/reportinsightads-txt
/openapi.json get /v1/report/insight/ads-txt
Singular endpoint returning Ads.txt insight data
# /report/insight/benchmarking/ad-delivery
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingad-delivery
/openapi.json get /v1/report/insight/benchmarking/ad-delivery
Returns Ad delivery benchmarking data for load rates, CTR, fill rate, and viewability metrics
# /report/insight/benchmarking/ad-density
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingad-density
/openapi.json get /v1/report/insight/benchmarking/ad-density
Returns Ad Density benchmarking data for mobile ad density and heavy ad intervention metrics
# /report/insight/benchmarking/ads-txt
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingads-txt
/openapi.json get /v1/report/insight/benchmarking/ads-txt
Returns Ads.txt benchmarking data for relationship weighting and exchanges
# /report/insight/benchmarking/cmp
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingcmp
/openapi.json get /v1/report/insight/benchmarking/cmp
Returns Consent Management Platform (CMP) benchmarking data
# /report/insight/benchmarking/cwv
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingcwv
/openapi.json get /v1/report/insight/benchmarking/cwv
Returns Core Web Vital (CWV) benchmarking data
# /report/insight/benchmarking/latency
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkinglatency
/openapi.json get /v1/report/insight/benchmarking/latency
Returns latency benchmarking data
# /report/insight/benchmarking/publisher-info
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingpublisher-info
/openapi.json get /v1/report/insight/benchmarking/publisher-info
Returns information about how the given publisher has been auto-classified into IAB categories
# /report/insight/benchmarking/revenue
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingrevenue
/openapi.json get /v1/report/insight/benchmarking/revenue
Returns top level revenue benchmarking data
# /report/insight/benchmarking/revenue-dimension
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingrevenue-dimension
/openapi.json get /v1/report/insight/benchmarking/revenue-dimension
Return detailed revenue benchmarking data for a selected dimension; ad_unit_type, geo, region, device, channel, partner, creative_size
# /report/insight/benchmarking/ssp-overview
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingssp-overview
/openapi.json get /v1/report/insight/benchmarking/ssp-overview
Returns top level SSP benchmarking bid data
# /report/insight/benchmarking/ssps
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubbenchmarking/reportinsightbenchmarkingssps
/openapi.json get /v1/report/insight/benchmarking/ssps
Returns a detailed breakdown of each SSP bid data for benchmarking
# /report/insight/cwv
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubcore-web-vitals/reportinsightcwv
/openapi.json get /v1/report/insight/cwv
Singular endpoint returning Core Web Vitals (CWV) data
# /report/insight/demand-mix
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubdemand-mix/reportinsightdemand-mix
/openapi.json get /v1/report/insight/demand-mix
Returns data for all revenue source combinations, including (publisher, Content Ignite) and (direct, programmatic, fallback)
# /report/insight/demand-mix/campaign
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubdemand-mix/reportinsightdemand-mixcampaign
/openapi.json get /v1/report/insight/demand-mix/campaign
Returns a list of campaigns and their associated data for the given time frame
# /report/insight/demand-mix/dimension
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubdemand-mix/reportinsightdemand-mixdimension
/openapi.json get /v1/report/insight/demand-mix/dimension
Returns demand mix data for a specified dimension, including partner, channel, advertiser, or platform
# /report/insight/demand-mix/dimension-filter
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubdemand-mix/reportinsightdemand-mixdimension-filter
/openapi.json get /v1/report/insight/demand-mix/dimension-filter
Returns available filter values for a specified dimension, including partner, channel, advertiser, or platform
# /report/insight/diagnostics
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubdiagnostics/reportinsightdiagnostics
/openapi.json get /v1/report/insight/diagnostics
Returns CMP data for monitoring performance and identifying drops that may impact monetisation
# /report/insight/diagnostics/:uid
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubdiagnostics/reportinsightdiagnostics:uid
/openapi.json get /v1/report/insight/diagnostics/{uid}
Returns a list of live checks and up-to-date metrics, to give insight for the here and now
# /report/insight/diagnostics/traffic/:uid
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubdiagnostics/reportinsightdiagnosticstraffic:uid
/openapi.json get /v1/report/insight/diagnostics/traffic/{uid}
Returns traffic data, including analytics metrics if an analytics integration has been connected
# /report/insight/live
Source: https://docs.contentignite.com/api-reference/reportinginsights-hublive-insights/reportinsightlive
/openapi.json get /v1/report/insight/live
Singular endpoint that returns live report data for ad, bid and latency metrics
# /report/insight/metrics
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubmetrics/reportinsightmetrics
/openapi.json get /v1/report/insight/metrics
Returns top level metrics such as page and ad impressions for the network, or for a given publisher
# /report/insight/metrics/latency
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubmetrics/reportinsightmetricslatency
/openapi.json get /v1/report/insight/metrics/latency
Returns latency data. Where every millisecond counts in advertising, spotting slowdowns can be vital to improving revenue.
# /report/insight/metrics/live-revenue
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubmetrics/reportinsightmetricslive-revenue
/openapi.json get /v1/report/insight/metrics/live-revenue
Returns live revenue data. Note that this does not include all revenue sources (due to limitations in those 3rd party platforms), also data is typically 3 hours behind real-time. Data is useful for tracking how today is trending.
# /report/insight/metrics/revenue
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubmetrics/reportinsightmetricsrevenue
/openapi.json get /v1/report/insight/metrics/revenue
View revenue over time, including the previous period and a 7 day offset, helping to spot trends
# /report/insight/revenue-analytics
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubrevenue-analytics/reportinsightrevenue-analytics
/openapi.json get /v1/report/insight/revenue-analytics
Initial check to determine whether the publisher has an analytics integration connected
# /report/insight/revenue-analytics/metric
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubrevenue-analytics/reportinsightrevenue-analyticsmetric
/openapi.json get /v1/report/insight/revenue-analytics/metric
Returns in-depth revenue analytics for a single metric (page views, sessions, total users, ad requests, unit loads), including dimension data for country, device, and browser (analytics only).
# /report/insight/revenue-analytics/overview
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubrevenue-analytics/reportinsightrevenue-analyticsoverview
/openapi.json get /v1/report/insight/revenue-analytics/overview
Returns revenue analytics date based series data for charts and data tables
# /report/insight/revenue-analytics/totals
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubrevenue-analytics/reportinsightrevenue-analyticstotals
/openapi.json get /v1/report/insight/revenue-analytics/totals
Returns top-level grouped totals and lookback periods from real time analytics data
# /report/insight/revenue
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubrevenue-insights/reportinsightrevenue
/openapi.json get /v1/report/insight/revenue
Returns top level revenue totals and time series data
# /report/insight/revenue/dimension
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubrevenue-insights/reportinsightrevenuedimension
/openapi.json get /v1/report/insight/revenue/dimension
Returns revenue data for a specified dimension, including publisher, ad_unit_type, config, geo, region, device, channel, partner, or creative_size
# /report/insight/revenue/totals
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubrevenue-insights/reportinsightrevenuetotals
/openapi.json get /v1/report/insight/revenue/totals
Returns top level revenue stats for fixed date periods
# /report/insight/ssp
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubssp-insights/reportinsightssp
/openapi.json get /v1/report/insight/ssp
Returns SSP insights data for the given filters
# /report/insight/ssp/ssp-filter
Source: https://docs.contentignite.com/api-reference/reportinginsights-hubssp-insights/reportinsightsspssp-filter
/openapi.json get /v1/report/insight/ssp/ssp-filter
Returns a list of active SSPs for the given filters, allowing you to filter the data returned from `/report/insights/ssp`
# /report
Source: https://docs.contentignite.com/api-reference/reportingrevenue-reports/report
/openapi.json get /v1/report
Fetch a list of user generated reports
# /report
Source: https://docs.contentignite.com/api-reference/reportingrevenue-reports/report-1
/openapi.json post /v1/report
Creates a user defined report with the given fields and filters. Call /report/filters for possible filter values
# /report/:id
Source: https://docs.contentignite.com/api-reference/reportingrevenue-reports/report:id
/openapi.json get /v1/report/{id}
Fetch a reports configuration details
# /report/:id
Source: https://docs.contentignite.com/api-reference/reportingrevenue-reports/report:id-1
/openapi.json put /v1/report/{id}
Update a reports config
# /report/:id
Source: https://docs.contentignite.com/api-reference/reportingrevenue-reports/report:id-2
/openapi.json delete /v1/report/{id}
Delete a report
# /report/:id/data
Source: https://docs.contentignite.com/api-reference/reportingrevenue-reports/report:iddata
/openapi.json get /v1/report/{id}/data
Fetch the data for a given report ID
# /report/filters
Source: https://docs.contentignite.com/api-reference/reportingrevenue-reports/reportfilters
/openapi.json get /v1/report/filters
Fetch options available for report filtering
# /report/date-range
Source: https://docs.contentignite.com/api-reference/reportingutility/reportdate-range
/openapi.json get /v1/report/date-range
Converts a date range preset into a start and end date. Helpful for clearly showing in the UI what a selected date range will map to when pulling a report
# Agent Skills
Source: https://docs.contentignite.com/app/agent-skills
Let an AI coding agent integrate the Content Ignite Mobile SDK for you
If you use an AI coding assistant, you can have it integrate the Content Ignite Mobile
SDK for you. We publish a set of **Agent Skills** — packaged instructions that teach a
coding agent exactly how to install, initialise and add ads with our SDK, following the
same guidance as these docs.
## What are Agent Skills?
Agent Skills are a lightweight, open format for giving AI agents new, task-specific
expertise. Each skill is a small bundle of instructions (and links to our reference
implementations) that an agent loads on demand when you ask it to do the related task —
for example, *"add a Content Ignite banner to my home screen."*
Because the format is an open standard, the same skills work across any
skills-compatible assistant, including **Claude Code, Cursor, OpenAI Codex, Gemini CLI,
GitHub Copilot** and others.
Agent Skills are optional and complement these docs — they don't replace them. This
documentation remains the source of truth; the skills simply let an agent apply it for
you. If you prefer to integrate by hand, follow the platform guides directly.
## Install
The skills live in our public repository and install with the
[`skills`](https://github.com/vercel-labs/skills) CLI (via `npx`, so no global install
is needed):
```bash theme={null}
npx skills add https://gitlab.com/content-ignite/skills
```
Select the skills you want from the interactive list, or install one directly:
```bash theme={null}
npx skills add https://gitlab.com/content-ignite/skills --skill ci-mobile-ads-get-started
```
Then ask your agent in natural language — e.g. *"Get started with the Content Ignite
Mobile SDK"* or *"Add a Content Ignite interstitial"* — and it will load the relevant
skill and apply it to your project.
### Project vs global install
By default the skills install at **project scope** — into your app's `.claude/skills`
directory (or the equivalent for your assistant) — so run the command from your app's
root directory. This is what you want when integrating a specific app, and it keeps the
skills versioned alongside that project.
To make the skills available across all of your projects instead, add the `-g` (global)
flag:
```bash theme={null}
npx skills add https://gitlab.com/content-ignite/skills -g
```
You need Node.js installed (which provides `npx`). The skills work with **native
Android and iOS** integrations today (Jetpack Compose, View-based, SwiftUI and UIKit);
React Native is documented on this site and planned for a future skills release.
## Available skills
Install, configure and initialise the SDK on Android or iOS. Start here.
Add an inline banner ad (Compose/View-based, SwiftUI/UIKit).
Add a full-screen interstitial ad shown at natural transitions.
Add App Open ads for cold start and resume-from-background.
Migrate an app already using the Google Mobile Ads SDK onto Content Ignite.
## Already running Google Mobile Ads?
The Content Ignite Mobile SDK embeds and orchestrates the Google Mobile Ads SDK, so you
should not run a separate Google Mobile Ads integration alongside it. If your app
already uses the Google Mobile Ads SDK, the **`ci-mobile-ads-migrate-from-google`** skill
detects the existing integration, removes it, installs Content Ignite in its place, and
can wire your existing ad views into our `publisher` fallback for a gradual rollout.
## How the skills stay current
The skills never hard-code an SDK version — they resolve the latest release from our
repositories at integration time, and the iOS `SKAdNetworkItems` list is pulled from
Google's official quick-start when needed. Each skill also links to a complete, working
demo app so your agent can reference a full example in context.
## Need help?
If a skill produces something unexpected, or you'd like a skill for a scenario we don't
yet cover, reach out to your Content Ignite account manager, or follow the relevant
platform guide on this site:
# App Open - Compose
Source: https://docs.contentignite.com/app/android/android_app_open_compose
Setting up App Open Ads - Compose
App Open Ads have two possible flows designed to be used together: Cold start and Resuming from background.
## Cold start (Splash screen)
The first approach allows you to monetise the loading screen of your app. When the user opens the app, the splash screen is displayed. While your app is loading, our SDK will load an Ad. If the ad is loaded in time you can control whether the ad is displayed before the home screen of your app is displayed. The example below is taken from our demo app:
```kotlin theme={null}
class SplashViewModel(
private val adManager: CIAppOpenAdManager
) : ViewModel() {
...
init {
viewModelScope.launch {
adManager.state.first { it == AppOpenState.DISMISSED }
_state.update { SplashState.NavigateToHome }
}
viewModelScope.launch {
val adLoaded = withTimeoutOrNull(AD_LOAD_TIMEOUT_MS) {
adManager.state.first { event ->
event == AppOpenState.LOADED || event == AppOpenState.LOAD_FAILED
} == AppOpenState.LOADED
}
_state.update {
if (adLoaded == true) {
SplashState.AdReady
} else {
SplashState.NavigateToHome
}
}
}
}
fun load(context: Context) {
val configuration = CIMobileAdsConfiguration.Builder(publisherId = "")
.enableAppOpen("") // Enable App Open ads
.setDebugFeature(true)
.build()
backgroundScope.launch {
// Initialise the ContentIgniteMobile SDK on a background thread.
val status = CIMobileAds.initialise(
context = context,
configuration = configuration
)
when (status) {
CIInitialisationStatus.Succeeded -> {
println("CIMobileAds Initialised Successfully")
// Load the app open ad
loadAd(context)
}
CIInitialisationStatus.Failed -> {
println("CIMobileAds Initialisation Failed")
_state.update { SplashState.NavigateToHome }
}
}
}
}
private fun loadAd(context: Context) {
adManager.loadAd(context)
}
fun showAd(activity: Activity) {
adManager.show(activity = activity)
}
...
}
```
You will notice that in this example the SDK initialisation is now performed on Splash Screen and to enable App Open Ads you must use `enableAppOpen(placementID: String)` in the SDK configuration builder. Passing in the placement ID which will be supplied to you by [Content Ignite](https://www.contentignite.com/).
From the UI we can control when the ad is shown by responding to the state updates:
```kotlin theme={null}
@Composable
fun SplashScreen(
viewModel: SplashViewModel,
onNavigateToHome: () -> Unit
) {
val activity = LocalActivity.current
val context = LocalContext.current
val state by viewModel.state.collectAsStateWithLifecycle()
// Trigger ad show when ad is ready; navigate when done
LaunchedEffect(state) {
viewModel.load(context)
}
when (state) {
is SplashState.AdReady -> {
activity?.let { viewModel.showAd(activity) }
}
is SplashState.NavigateToHome -> onNavigateToHome()
else -> Unit
}
...
```
## Resuming from background
For this approach we need to listen to application lifecycle callbacks. The recommended approach is to create a class which inherits Application. Then implement both the [DefaultLifecycleObserver](https://developer.android.com/reference/androidx/lifecycle/DefaultLifecycleObserver) and [Application.ActivityLifecycleCallbacks](https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks) interfaces.
```kotlin theme={null}
class App: Application(), Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver { ... }
```
Inside the `App` class implement `onCreate()` and register the Activity Lifecycle Callbacks:
```kotlin theme={null}
private lateinit var adManager: CIAppOpenAdManager
override fun onCreate() {
super.onCreate()
adManager = CIAppOpenAdManager
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
registerActivityLifecycleCallbacks(this)
}
```
To keep track of the current Activity, we use the ActivityLifecycleCallbacks:
```kotlin theme={null}
private var currentActivity: Activity? = null
override fun onActivityStarted(activity: Activity) {
if (!CIAppOpenAdManager.isShowingAd()) {
currentActivity = activity
}
}
override fun onActivityResumed(activity: Activity) { currentActivity = activity }
override fun onActivityPaused(activity: Activity) { currentActivity = null }
```
Finally we implement `onStart()` which gets called when the app resumes from the background, and we use the `CIAppOpenAdManager` to show the ad if one is available and otherwise load the ad for the next opportunity.
```kotlin theme={null}
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
currentActivity?.let {
if (adManager.isAdAvailable()) {
adManager.show(it)
} else {
adManager.loadAd(this@App)
}
}
}
```
Full example code [here](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-android/-/tree/main/samples/Compose/app-open-compose-sample?ref_type=heads).
# App Open - View-Based
Source: https://docs.contentignite.com/app/android/android_app_open_view_based
Setting up App Open Ads - View Based
App Open Ads have two possible flows designed to be used together: Cold start and Resuming from background.
## Cold start (Splash screen)
The first approach allows you to monetise the loading screen of your app. When the user opens the app, the splash screen is displayed. While your app is loading, our SDK will load an Ad. If the ad is loaded in time you can control whether the ad is displayed before the home screen of your app is displayed. The example below is taken from our demo app:
```kotlin theme={null}
class SplashViewModel(
private val adManager: CIAppOpenAdManager
) : ViewModel() {
...
fun load(context: Context) {
val configuration = CIMobileAdsConfiguration.Builder(publisherId = "")
.enableAppOpen(placementID = "") // Enable App Open Ads
.setDebugFeature(true)
.build()
backgroundScope.launch {
// Initialise the ContentIgniteMobile SDK on a background thread.
val status = CIMobileAds.initialise(
context = context,
configuration = configuration
)
when (status) {
CIInitialisationStatus.Succeeded -> {
println("CIMobileAds Initialised Successfully")
loadAd(context)
}
CIInitialisationStatus.Failed -> {
println("CIMobileAds Initialisation Failed")
_state.update { SplashState.NavigateToHome }
}
}
}
}
private fun loadAd(context: Context) {
adManager.loadAd(context)
viewModelScope.launch {
val adLoaded = withTimeout(AD_LOAD_TIMEOUT_MS) {
adManager.state.first { event ->
event == AppOpenState.LOADED || event == AppOpenState.LOAD_FAILED
} == AppOpenState.LOADED
}
_state.value = if (adLoaded) SplashState.AdReady else SplashState.NavigateToHome
}
}
fun showAd(activity: Activity) {
adManager.show(activity = activity)
viewModelScope.launch {
adManager.state.first { it == AppOpenState.DISMISSED || it == AppOpenState.LOAD_FAILED }
_state.update { SplashState.NavigateToHome }
}
}
...
}
```
You will notice that in this example the SDK initialisation is now performed on Splash Screen and to enable App Open Ads you must use `enableAppOpen(placementID: String)` in the SDK configuration builder. Passing in the placement ID which will be supplied to you by [Content Ignite](https://www.contentignite.com/).
From the UI we can control when the ad is shown by responding to the state updates:
```kotlin theme={null}
class SplashFragment: Fragment(R.layout.fragment_splash) {
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentSplashBinding.bind(view)
val navController = findNavController()
router = AppRouter(navController)
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.state.collect { state ->
when (state) {
is SplashState.Loading -> {
binding.progressIndicator.isVisible = true
viewModel.load(requireContext())
}
is SplashState.AdReady -> {
binding.progressIndicator.isVisible = false
viewModel.showAd(requireActivity())
}
is SplashState.NavigateToHome -> {
router.navigateToHome()
}
}
}
}
}
}
...
```
## Resuming from background
For this approach we need to listen to application lifecycle callbacks. The recommended approach is to create a class which inherits Application. Then implement both the [DefaultLifecycleObserver](https://developer.android.com/reference/androidx/lifecycle/DefaultLifecycleObserver) and [Application.ActivityLifecycleCallbacks](https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks) interfaces.
```kotlin theme={null}
class App: Application(), Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver { ... }
```
Inside the `App` class implement `onCreate()` and register the Activity Lifecycle Callbacks:
```kotlin theme={null}
private lateinit var adManager: CIAppOpenAdManager
override fun onCreate() {
super.onCreate()
adManager = CIAppOpenAdManager
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
registerActivityLifecycleCallbacks(this)
}
```
To keep track of the current Activity, we use the ActivityLifecycleCallbacks:
```kotlin theme={null}
private var currentActivity: Activity? = null
override fun onActivityStarted(activity: Activity) {
if (!CIAppOpenAdManager.isShowingAd()) {
currentActivity = activity
}
}
override fun onActivityResumed(activity: Activity) { currentActivity = activity }
override fun onActivityPaused(activity: Activity) { currentActivity = null }
```
Finally we implement `onStart()` which gets called when the app resumes from the background, and we use the `CIAppOpenAdManager` to show the ad if one is available and otherwise load the ad for the next opportunity.
```kotlin theme={null}
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
currentActivity?.let {
if (adManager.isAdAvailable()) {
adManager.show(it)
} else {
adManager.loadAd(this@App)
}
}
}
```
Full example code [here](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-android/-/tree/main/samples/View-Based/app-open-view-based-sample?ref_type=heads).
# Banner Ads - Compose
Source: https://docs.contentignite.com/app/android/android_banner_compose
Setting up Banner Ads
The SDK supports Banner Ads, via the `CIBannerView` Composable function. This takes up to three parameters:
#### Required
* `placementID: String`: Unique ID for this Ad Placement provided by Content Ignite.
* `pageUrl: String?`: This is used for targeting for example if the ad is displayed inline within an article or section of the app which has an equivalent URL on the web.
#### Optional
* `eventListener: CIBannerEventListener`: Interface which enables you to respond to events related to the banner ad.
* `targeting: Map>`: Pass custom key-value pairs to ad requests.
* `modifier`: [Modifier](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier) used to set the size of the ad placement.
* `publisher`: Composable function to allow you to provide a fallback to your existing Ad implementation for this particular placement. This gives publishers full control over the use of the SDK and the rate at which this fallback is used can be controlled directly through the [Fusion](https://www.contentignite.com/fusion) platform.
#### Example
```kotlin theme={null}
import com.contentignite.mobilesdk.CIViews.CIBannerView
val eventListener = object : CIBannerEventListener {
override fun bannerLoaded() {
println("Banner ad loaded.")
}
override fun bannerLoadFailed(error: CIBannerLoadError) {
println("Banner ad failed to load: $error")
}
override fun bannerClicked() {
println("Banner ad clicked.")
}
override fun bannerImpression() {
println("Banner ad impression.")
}
}
CIBannerView(
placementID = "",
pageUrl = "https://publisher.com/sport",
eventListener = eventListener,
targeting = mapOf("segment" to listOf("health", "fitness")),
modifier =
Modifier
.fillMaxSize()
.height(50.dp),
publisher = {
// Publisher fallback implementation
}
)
```
# Banner Ads - View-Based
Source: https://docs.contentignite.com/app/android/android_banner_view_based
Setting up Banner Ads
The SDK supports Banner Ads using the `CIBannerView` view and the `setPlacement` API.
Below is an example of how to set up a fixed CIBannerView in an XML layout:
```xml theme={null}
```
The `setPlacement` API has the following parameters:
#### Required
* `placementID: String`: Unique ID for this Ad Placement provided by Content Ignite.
* `pageUrl: String?`: This is used for targeting for example if the ad is displayed inline within an article or section of the app which has an equivalent URL on the web.
#### Optional
* `eventListener: CIBannerEventListener`: Interface which enables you to respond to events related to the banner ad.
* `targeting: Map>`: Pass custom key-value pairs to ad requests.
* `publisher: (() -> View)?`: This function parameter is used to return a fallback view, It allows you to fall back to your existing Ad implementation for this particular placement. This gives publishers full control over the use of the SDK and the rate at which this fallback is used can be controlled directly through the [Fusion](https://www.contentignite.com/fusion) platform.
#### Example
```kotlin theme={null}
import com.contentignite.mobilesdk.ui.CIBannerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
val banner = findViewById(R.id.banner)
banner.setPlacement(
placementID = "",
eventListener = eventListener,
targeting = mapOf("segment" to listOf("health", "fitness")),
pageUrl = "https://publisher.com/sport",
publisher = {
val imageView = ImageView(application)
imageView.setLayoutParams(
LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT
)
)
imageView.adjustViewBounds = true
imageView.setImageResource(R.drawable.fallback)
imageView
})
}
}
```
## Handling ad events
To listen and respond to events from a Banner ad, use the `CIBannerEventListener` interface:
```kotlin theme={null}
private val eventListener = object : CIBannerEventListener {
override fun bannerLoaded() {
println("Banner ad loaded.")
}
override fun bannerLoadFailed(error: CIBannerLoadError) {
println("Banner ad failed to load: $error")
}
override fun bannerClicked() {
println("Banner ad clicked.")
}
override fun bannerImpression() {
println("Banner ad impression.")
}
}
```
# Interstitial Ads
Source: https://docs.contentignite.com/app/android/android_interstitial
Setting up Interstitial Ads
Interstitial ads are full-screen ads that cover the interface of the app. They're typically displayed at natural transition points in the flow of the app.
## Initialising an ad
Start by initialising an instance of a `CIInterstitialAd` with the following parameters:
### Required:
* `placementID: String`: Unique ID for this Ad Placement provided by Content Ignite.
* `eventListener: CIInterstitialEventListener`: This interface allows you to respond to events related to the interstitial ad.
* `targeting: Map>`: Pass custom key-value pairs to ad requests.
* `pageUrl: String?`: URL used for targeting for example if the ad is displayed in a section of the app which has an equivalent URL on the web.
### Optional:
* `publisher`: Optional lambda to provide a fallback to your existing Ad implementation for this particular interstitial. This gives publishers full control over the use of the SDK and the rate at which this fallback is used can be controlled directly through the [Fusion](https://www.contentignite.com/fusion) platform.
```kotlin theme={null}
val eventListener = object : CIInterstitialEventListener {
override fun interstitialDismissed() {
_state.update { UIState.Default }
}
override fun interstitialLoadFailed() {
_state.update { UIState.Failed }
}
override fun interstitialLoaded() {
_state.update { UIState.Loaded }
}
}
val interstitial = CIInterstitialAd(
placementID = "",
targeting = mapOf("segment" to listOf("health", "fitness")),
eventListener = eventListener,
pageUrl = "https://example.com/sport"
)
```
## Show the ad
When you are ready to display, such as after a transition in the app flow, use the `show` method to display the ad providing the current `Activity`:
```kotlin theme={null}
when (val ad = interstitial) {
null -> _state.update { UIState.Failed }
else -> ad.show(activity)
}
```
See the full examples: [Compose](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-android/-/tree/main/samples/Compose/kotlin-compose-sample?ref_type=heads) | [View-based](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-android/-/tree/main/samples/View-Based/kotlin-views-sample?ref_type=heads).
# Introduction
Source: https://docs.contentignite.com/app/android/android_intro
Get started with your Android integration
### Prerequisites
* Minimum SDK version of `24` or higher
* Compile SDK version of `36` or higher
### Migrate from v1 to v2
To migrate from version 1.5.1 to version 2.0.0, see this [guide](/app/android/android_migrate_v1_to_v2).
### Installation
To install the SDK into your project, first add the repository to your project level Android gradle build file or settings gradle file.
```kotlin theme={null}
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
maven(url = "https://gitlab.com/api/v4/projects/73367547/packages/maven")
}
}
```
```groovy theme={null}
// settings.gradle
dependencyResolutionManagement {
repositories {
maven {
url 'https://gitlab.com/api/v4/projects/73367547/packages/maven'
}
}
}
```
### Adding the library dependency
Add the latest version of the SDK to your relevant module build.gradle.
```toml theme={null}
# libs.versions.toml
[versions]
contentIgnite = "2.5.0"
[libraries]
content-ignite-mobile = { group = "com.contentignite", name = "ci-mobile-sdk-android", version.ref = "contentIgnite" }
```
```kotlin theme={null}
// build.gradle.kts(:module)
dependencies {
implementation(libs.content.ignite.mobile)
}
```
```groovy theme={null}
// build.gradle(:module)
dependencies {
implementation libs.content.ignite.mobile
}
```
First we will create an instance of `CIMobileAdsConfiguration`. This is achieved using `CIMobileAdsConfiguration.Builder`.
The builder takes two required parameter and two optional parameters:
* `publisherId: String`: A unique identifier to identify the publisher in the Fusion platform.
* `googleId: String`: Your Google Ad Manager application ID (`ca-app-pub-...`). Plug-and-play customers use the ID provided by Content Ignite; SaaS customers use their own Google Ad Manager account app ID — contact Content Ignite if you are unsure which applies.
Then call the build API to create the instance.
When creating an instance of `CIMobileAdsConfiguration` it is possible to enable optional features on the SDK, such as debugging via the `setDebugFeature` API (since version 1.2.0 the debug feature is enabled by default). This is discussed further in the [Debug Features](/app/android/debugging) section.
```kotlin theme={null}
val configuration = CIMobileAdsConfiguration.Builder(
publisherId = "",
googleId = "ca-app-pub-3940256099942544~3347511713"
)
.setDebugFeature(enabled = true)
.setTestAds(enabled = true)
.build()
```
* `setTestAds(enabled: Boolean)` was added to `CIMobileAdsConfiguration.Builder` in `2.3.0` to control whether test ads are enabled, this was previously only possible from the debug menu. If this is set the Debug Menu option will be hidden and if not set the Debug Menu option will be used.
The initialisation step uses a singleton instance `CIMobileAds`. The `initialise` API is a [suspending](https://kotlinlang.org/docs/coroutines-basics.html) function and should be called from a background thread.
It takes two required parameters:
* `context`: The application context.
* `configuration`: An instance of `CIMobileAdsConfiguration`.
The call to initialise the SDK should be made as early as possible in the application lifecycle.
If you are currently using Google Mobile Ads SDK, it is not required to initialise this separately, and this code should be removed. You should also remove the dependency in your build.gradle file. If you are migrating from the Google Mobile Ads SDK, do not assume your existing app ID is the one to pass as `googleId` — contact Content Ignite to confirm which `ca-app-pub-...` ID applies to your setup (plug-and-play accounts use Content Ignite's app ID; SaaS accounts use their own).
The example below is taken from the demo application:
```kotlin theme={null}
import com.contentignite.mobilesdk.CIMobileAds
import com.contentignite.mobilesdk.CIInitialisationStatus
class App: Application() {
override fun onCreate() {
super.onCreate()
val backgroundScope = CoroutineScope(Dispatchers.IO)
backgroundScope.launch {
val status = CIMobileAds.initialise(
context = this@App,
configuration = configuration
)
when (status) {
CIInitialisationStatus.Succeeded -> println("CIMobileAds Initialised Successfully")
CIInitialisationStatus.Failed -> println("CIMobileAds Initialisation Failed")
}
}
}
}
```
### Select an ad format
Content Ignite Mobile SDK is now imported and you're ready to implement an ad. We support both Jetpack Compose and View-Based UI. We offer a number of different formats:
Ads that appear when a user opens or switches back to your app.
Ads that appear when a user opens or switches back to your app.
Flexibly sized format for placing ads anywhere in your app.
Flexibly sized format for placing ads anywhere in your app.
Full-screen ads that are designed to appear between content transitions.
# Migrate v1 to v2
Source: https://docs.contentignite.com/app/android/android_migrate_v1_to_v2
Migration guide - v1 to v2
Version 2.0.0 introduced some breaking changes which warranted this short guide.
### 1. Update AndroidManifest.xml
Before version 2.0.0 it was required to have the following metadata inside the application tag in the `AndroidManifest.xml`:
```xml theme={null}
```
This can now be removed. This ID will be moved in the next step.
### 2. Update SDK Initialisation
Update to the new SDK configuration API which now requires the Google application ID as a parameter:
```kotlin theme={null}
val configuration = CIMobileAdsConfiguration.Builder(
publisherId = "",
googleId = "ca-app-pub-3940256099942544~3347511713" // New required parameter
)
.setDebugFeature(true)
.enableAppOpen("") // only required if using App Open ads
.build()
```
### 3. Interstitial ads
If your application uses Interstitial ads, the `CIInterstitialAd` API no longer requires the `context` parameter, so this can be removed:
```kotlin theme={null}
val interstitial = CIInterstitialAd(
placementID = "",
eventListener = eventListener,
pageUrl = "https://example.com/sport"
)
```
# Debug features
Source: https://docs.contentignite.com/app/android/debugging
Using the Debugging features
## Using the Debug and test features
The SDK gives developers the option of enabling a debugging gesture when running the application by enabling this as part of the `CIMobileAdsConfiguration`, since version 1.2.0, the debug gesture is enabled by default.

When enabled and the user performs the gesture, this will open a debug menu, which gives the following options:
### Clear ads configs cache
When updating configs in the Fusion platform, these are stored by the SDK and refreshed periodically. Pressing this button will force the SDK to download the new configs from the server.
### Clear floors cache
When updating floors data within fusion, this data is stored by the SDK and refreshed periodically. Pressing this button will force the SDK to download the new floors data from the server.
### Start a new debug session
Opens a dialog where the user is required to enter a PIN which is provided within the [Fusion](https://www.contentignite.com/fusion) dashboard.
When this PIN is entered correctly, the SDK will start sending detailed logs for a fixed period of time to the Content Ignite team to allow them to diagnose issues more effectively.
### Enabling / Disabling Test ads
During development to prevent invalid traffic in Google Ad Manager, we recommend you enable test ads. This guarantees an ad will always be served, either from GAM or Prebid depending on your setup, helping for use during demos.
## Using the Debug overlay (Compose only)
As a shortcut to the gesture based access to the debug menu, you also have the option of using the `CIDebugOverlay` during development, which opens up the debug menu, simply add the `CIDebugOverlay` to your Compose UI. See the demo app. This feature will be added to the View-Based API in a future version.
# app-ads.txt
Source: https://docs.contentignite.com/app/app-ads-txt
Authorising sellers of your app's ad inventory with app-ads.txt
`app-ads.txt` is the app equivalent of [`ads.txt`](/guide/glossary) — an IAB *Authorised Digital Sellers* file that lists the companies authorised to sell your app's ad inventory. SSPs and buyers crawl it to confirm that demand on your inventory is legitimate, which reduces fraud and protects the value of your inventory. Without it, demand partners may be unable to verify your inventory and will bid less (or not at all), directly reducing your revenue.
Unlike `ads.txt`, an `app-ads.txt` file does not live with the app itself. Crawlers find it via the **developer/marketing website URL** declared in your App Store and Google Play listings, and expect the file at the **root of that domain** (for example, `https://example.com/app-ads.txt`).
Setting it up is straightforward:
1. **Host an `app-ads.txt` file on the root domain of your developer website** — the same website URL listed on your app's App Store and Google Play store listings. The file must be served over HTTPS as `text/plain` from the root (not a subdomain or subfolder).
2. **Provide that website domain to Content Ignite.**
3. **Content Ignite will share the required lines** for you to add to your `app-ads.txt` file. Add them exactly as provided.
Make sure the developer website URL in your App Store and Google Play listings points to the domain that hosts your `app-ads.txt` — if the listing URL and the file's domain don't match, crawlers won't find the file.
Once your file is live, Fusion can validate it and surface any missing or untracked lines through the [Ads.txt Insights Hub](/reporting/insights/ads-txt).
# Introduction
Source: https://docs.contentignite.com/app/index
The power of Fusion as you know, brought to app...
The Content Ignite Mobile SDK enables monetisation of your Android or iOS mobile app.
## Key capabilities
### Ad formats
| Format | Android | iOS | React Native |
| ------------ | ------- | --- | ------------ |
| Banner | ✅ | ✅ | ✅ |
| Interstitial | ✅ | ✅ | ✅ |
| App Open | ✅ | ✅ | ✅ |
### Integrations
| Integration | Description |
| ----------------------- | ---------------------------------------------------------- |
| Google Ad Manager (GAM) | Seamless connection with GAM for ad serving and management |
| Prebid | Header bidding capabilities for maximum yield |
| Supply-Side Platforms | Add new demand sources without app updates |
### Targeting
| Capability | Description |
| -------------------------- | ------------------------------------------------------------------------------------- |
| Geo-targeting | Location-based ad delivery |
| Device-targeting | Specific targeting based on device characteristics |
| Viewport targeting | Ad delivery based on viewability parameters |
| Audience targeting | Demographic and behavioural targeting options |
| URL-based targeting | Content-aware ad targeting |
| Custom key-value targeting | Flexible custom targeting parameters |
| Contextual targeting | In-app contextual audience support via canonical URLs and web page equivalent mapping |
### Placement & Stack Management
| Capability | Description |
| -------------------------------- | -------------------------------------------------------- |
| Drag-and-drop ad stacks | Visually build your ad stack |
| Flexible placement configuration | Customisable ad placement options |
| Dynamic multi-size support | Adaptable ad sizes based on screen and context |
| Static fallback creatives | Backup creatives when primary ad delivery fails |
| Activation percentage control | Gradual rollout capabilities |
| Remote configuration updates | Real-time unit behaviour adjustments without app updates |
### Performance & Control
| Capability | Description |
| --------------------------- | ------------------------------------------------- |
| SSP reporting | Create custom revenue reports for SSPs |
| SSP insights | Visualise the bid funnel for all SSP integrations |
| Dynamic floor pricing | Automated price floor optimisation |
| Refresh control | Managed ad refresh timing and frequency |
| In-view detection | Accurate viewability measurement |
| Non-personalised ad options | Privacy-compliant advertising options |
| Scheduling capabilities | Timed ad delivery control |
### Developer Tools
| Capability | Description |
| ---------------------------- | ------------------------------------------------- |
| Debug mode | Enhanced testing and troubleshooting capabilities |
| Demo ad support | Test ad functionality without live campaigns |
| Detailed logging & analytics | Comprehensive performance and error tracking |
### Privacy, Security & Quality Control
| Capability | Description |
| -------------------------- | -------------------------------------------------- |
| GDPR & CCPA compliance | Full European and US privacy regulation support |
| TCF consent integration | Industry-standard consent framework implementation |
| App-ads.txt validation | Authorised digital sellers verification |
| Remote kill switch | Emergency ad delivery control |
| Experimentation support | A/B testing capabilities |
| Gradual traffic allocation | Controlled feature rollout |
| Performance monitoring | Real-time ad delivery analytics |
| Split logging by app | Segmented performance tracking |
## How does it work?
Whether your app is already live or you are still in development, you will follow a straightforward process:
**1. Onboarding** - Discussion with our team about your app, what formats you intend to use and where they will be placed.
**2. SDK Integration** - Support will be provided to you during the integration and setup Ad placements with Fusion.
**3. Testing** - Checks to ensure ads are serving and make any adjustments to targeting for your specific needs.
**4. Release** - The rollout of ad delivery will be controlled and monitored by our operations team.
**5. Maintenance** - You will be notified of new updates and improvements to our SDK.
# Debug features
Source: https://docs.contentignite.com/app/ios_swiftui/debugging
Using the Debugging features
The SDK gives developers the option of enabling the debugging features when running the application by using the `setDebugFeature(enabled:)` when using CIMobileAdsConfiguration.Builder and setting the `enabled` parameter to `true` as seen in the [Initialising the SDK](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-swiftui#initialising-the-sdk) section.
When enabled it allows a user to perform the gesture demonstrated below.

When the user performs the gesture, this will open a debug menu, which gives the following options:
### Clear ads configs cache
When updating configs in the Fusion platform, these are stored by the SDK and refreshed periodically. Pressing this button will force the SDK to download the new configs from the server.
### Clear floors cache
When updating floors data within fusion, this data is stored by the SDK and refreshed periodically. Pressing this button will force the SDK to download the new floors data from the server.
### Start a new debug session
Opens a dialog where the user is required to enter a PIN which is provided within the [Fusion](https://www.contentignite.com/fusion) dashboard.
When this PIN is entered correctly, the SDK will start sending detailed logs for a fixed period of time to the Content Ignite team to allow them to diagnose issues more effectively.
### Enabling / Disabling Test ads
During development to prevent invalid traffic in Google Ad Manager, we recommend you enable test ads. This guarantees an ad will always be served, either from GAM or Prebid depending on your setup, helping for use during demos.
This can also be controlled using `setTestAds(enabled: Boolean)` on `CIMobileAdsConfiguration.Builder`.
### Using the Debug Overlay
As a shortcut to the gesture based access to the debug menu, you also have the option of using the `CIDebugOverlay` during development, which opens up the debug menu, simply add the `CIDebugOverlay` to your SwiftUI view hierarchy. See the demo app.
# App Open
Source: https://docs.contentignite.com/app/ios_swiftui/ios_swiftui_app_open
Setting up App Open ads
App Open Ads have two possible flows designed to be used together: Cold start and Resuming from background.
## Cold start (Splash screen)
The first approach allows you to monetise the loading screen of your app. When the user opens the app, the splash screen is displayed. While your app is loading, our SDK will load an Ad. If the ad is loaded in time you can control whether the ad is displayed before the home screen of your app is displayed. The example below is taken from our demo app:
```swift theme={null}
import SwiftUI
import Combine
import CIMobileSDK
enum SplashState {
case loading
case adReady
case navigateToHome
}
@MainActor
final class SplashViewModel: ObservableObject {
// 1. Monitor state changes in the UI
@Published private(set) var state: SplashState = .loading
private let adLoadTimeout: Duration = .seconds(5)
private var loadContinuation: CheckedContinuation?
// 2. Store an instance of CIAppOpenAdManager
private let adManager: CIAppOpenAdManager
init(adManager: CIAppOpenAdManager) {
self.adManager = adManager
}
func load() {
// 3. Initialise the SDK
let configuration = CIMobileAdsConfiguration.Builder(publisherId: "")
.setDebugFeature(enabled: true)
.enableAppOpen(placementID: "")
.build()
Task {
let status = try await CIMobileAds.shared.initialise(
configuration: configuration
)
switch status {
case .succeeded:
print("CIMobileSDK initialization succeeded")
let adLoaded = await loadAdWithTimeout()
Task { @MainActor in
state = adLoaded ? .adReady : .navigateToHome
}
case .failed:
print("CIMobileSDK initialization failed")
navigateToHome()
}
}
Task {
for await event in adManager.state {
if event == .dismissed {
navigateToHome()
}
}
}
}
private func navigateToHome() {
Task { @MainActor in
self.state = .navigateToHome
}
}
private func loadAdWithTimeout() async -> Bool {
// 4. Call loadAd() on the CIAppOpenManager instance
adManager.loadAd()
let adManager = self.adManager
return await withTaskGroup(of: Bool?.self) { group in
group.addTask {
for await state in adManager.state {
switch state {
case .loaded: return true
case .loadFailed: return false
default:
continue
}
}
return false
}
group.addTask {
try? await Task.sleep(for: self.adLoadTimeout)
return nil
}
for await result in group {
group.cancelAll()
return result ?? false
}
return false
}
}
func showAd() {
// 5. Call the CIAppOpenAdManager to show the Ad.
adManager.show()
}
}
```
Let's break down this code:
1. In this simple example, we use a `SplashState` enumeration to communicate our state changes back to the UI, here this is done using a callback.
2. In our ViewModel we store an instance of `CIAppOpenAdManager`.
3. Enabling App Open ads is achieved by using `enableAppOpen(placementID: String)` in the SDK configuration builder. Passing in the placement ID which will be supplied to you by [Content Ignite](https://www.contentignite.com/).
4. In this example we use a simple timeout to simulate the loading of the app and attempt to load an ad before the timeout is reached.
5. Calling the `show()` method on `CIAppOpenManager` to show the ad.
From the UI we can control when the ad is shown by responding to the state updates. We make use of a `AppRouter`, an `ObservableObject` which in this example holds a variable to track if the splash screen has been completed, which is updated by calling `navigateToHome()`:
```swift theme={null}
import SwiftUI
import CIMobileSDK
@MainActor
final class AppRouter: ObservableObject {
@Published var splashCompleted = false
func navigateToHome() {
splashCompleted = true
}
}
struct SplashView: View {
@StateObject private var viewModel: SplashViewModel
@EnvironmentObject private var router: AppRouter
init(adManager: CIAppOpenAdManager) {
_viewModel = StateObject(wrappedValue: SplashViewModel(adManager: adManager))
}
var body: some View {
ZStack {
...
}
.onChange(of: viewModel.state, initial: true) { oldState, newState in
switch newState {
case .adReady:
viewModel.showAd()
case .navigateToHome:
router.navigateToHome()
case .loading:
viewModel.load()
}
}
}
}
```
## Resuming from background
For this approach we need to listen to the application [ScenePhase](https://developer.apple.com/documentation/SwiftUI/ScenePhase). To achieve this, we use a property wrapper inside the `App` class. Additionally we use the `AppRouter` we saw earlier to update the view hierarchy:
```swift theme={null}
import SwiftUI
import CIMobileSDK
@main
struct AppOpenSwiftUIApp: App {
@StateObject private var router = AppRouter()
@Environment(\.scenePhase) private var scenePhase
private let adManager = CIAppOpenAdManager.shared
var body: some Scene {
WindowGroup {
Group {
if router.splashCompleted {
HomeView()
} else {
SplashView(adManager: adManager)
}
}
.environmentObject(router)
.onChange(of: scenePhase) {
guard scenePhase == .active, router.splashCompleted else { return }
if adManager.isAdAvailable() {
adManager.show()
} else {
adManager.loadAd()
}
}
}
}
}
```
See the full examples: [SPM](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-swiftui/-/tree/main/Demos/AppOpenSwiftUI-SPM?ref_type=heads) | [CocoaPods](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-swiftui/-/tree/main/Demos/AppOpenSwiftUI-CocoaPods?ref_type=heads).
# Banner Ads
Source: https://docs.contentignite.com/app/ios_swiftui/ios_swiftui_banner
Setting up Banner ads
The SDK supports Banner Ads via the `CIBannerView` SwiftUI View. With the following parameters:
### Required
* `placementID: String`: Unique ID for this Ad Placement provided by Content Ignite.
* `pageUrl: String?`: This is used for targeting for example if the ad is displayed inline within an article or section of the app which has an equivalent URL on the web.
### Optional
* `delegate: CIBannerViewDelegate`: This protocol allows you to respond to events related to the banner ad.
* `targeting: [String: [String]]`: Pass custom key-value pairs to ad requests.
* `publisher`: [ViewBuilder](https://developer.apple.com/documentation/swiftui/viewbuilder) closure to allow you to provide a fallback to your existing Ad implementation for this particular placement. This gives publishers full control over the use of the SDK and the rate at which this fallback is used can be controlled directly through the Fusion platform.
```swift theme={null}
import CIMobileSDKSwiftUI
let coordinator = BannerCoordinator()
let targeting = ["segment" : ["health","fitness"]]
CIBannerView(
placementID: "",
pageUrl: "https://publisher.com/sport",
delegate: coordinator,
targeting: targeting,
publisher: {
// Publisher fallback implementation
}
)
.frame(width: 300.0, height: 250.0)
```
## Handling ad events
To listen and respond to events from a Banner ad, use the `CIBannerViewDelegate` protocol:
```swift theme={null}
extension BannerCoordinator: CIBannerViewDelegate {
func bannerLoaded() {
print("Banner ad loaded.")
}
func bannerLoadFailed(error: Error) {
print("Banner ad failed to load: \(error.localizedDescription)")
}
func bannerClicked() {
print("Banner ad clicked.")
}
func bannerImpression() {
print("Banner ad impression")
}
}
```
See the full examples: [**SPM**](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-swiftui/-/tree/main/Demos/CIMobileSDK-SwiftUI-SPM?ref_type=heads) | [**CocoaPods**](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-swiftui/-/tree/main/Demos/CIMobileSDK-SwiftUI-CocoaPods?ref_type=heads).
# Interstitial Ads
Source: https://docs.contentignite.com/app/ios_swiftui/ios_swiftui_interstitial
Setting up Interstitial ads
Interstitial ads are full-screen ads that cover the interface of the app. They're typically displayed at natural transition points in the flow of the app.
## Initialising an ad
Start by initialising an instance of a `CIInterstitial` with the following parameters:
### Required:
* `placementID: String`: Unique ID for this Ad Placement provided by Content Ignite.
* `pageUrl: String?`: URL used for targeting for example if the ad is displayed in a section of the app which has an equivalent URL on the web.
* `eventListener: CIInterstitialEventListener`: This protocol allows you to respond to events related to the interstitial ad.
### Optional:
* `targeting: [String: [String]]`: Pass custom key-value pairs to ad requests.
* `publisher`: Optional lambda to provide a fallback to your existing Ad implementation for this particular interstitial. This gives publishers full control over the use of the SDK and the rate at which this fallback is used can be controlled directly through the [Fusion](https://www.contentignite.com/fusion) platform.
```swift theme={null}
@MainActor
class InterstitialViewModel: ObservableObject {
...
private var interstitial: CIInterstitial?
func loadAd() {
...
interstitial = CIInterstitial(
placementID: "",
pageUrl: "https://publisher.com/sport",
targeting: ["segment" : ["health","fitness"]],
eventListener: self
)
}
```
## Load the ad
When you are ready to load the ad, call `load()` on the ad instance:
```swift theme={null}
do {
try await interstitial?.load()
} catch {
print("Failed to load interstitial ad with error: \(error.localizedDescription)")
...
}
```
## Handling ad events
To listen and respond to events from an Interstitial ad, use the `CIInterstitialEventListener` protocol:
```swift theme={null}
extension InterstitialViewModel: @MainActor CIInterstitialEventListener {
func interstitialDismissed() {
Task { @MainActor in
uiState = .initial
}
}
func interstitialLoadFailed() {
Task { @MainActor in
uiState = .failed
}
}
func interstitialLoaded() {
Task { @MainActor in
uiState = .loaded
}
}
}
```
## Show the ad
When you are ready to display the ad, such as after a transition in the app flow, use the `show` method to display the ad:
```swift theme={null}
interstitial?.show()
```
See the full examples: [SPM](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-swiftui/-/tree/main/Demos/CIMobileSDK-SwiftUI-SPM?ref_type=heads) | [CocoaPods](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-swiftui/-/tree/main/Demos/CIMobileSDK-SwiftUI-CocoaPods?ref_type=heads).
# Introduction
Source: https://docs.contentignite.com/app/ios_swiftui/ios_swiftui_intro
Get started with your iOS (SwiftUI) integration
## Prerequisites
### Requirements
* Use Xcode 16.0 or higher.
* Target iOS 17.2 or higher.
### Updating your Info.plist
1. Before installing, update the application `Info.plist` to add a GADApplicationIdentifier key with a string value of your Google Ad Manager app ID, of the form `ca-app-pub-################~##########`.
Which app ID to use depends on your Content Ignite setup. **Plug-and-play** customers (using Content Ignite's Google Ad Manager account) use the app ID **provided by Content Ignite**. **SaaS** customers use **their own** Google Ad Manager account's app ID. If you are migrating from the Google Mobile Ads SDK, do not assume your existing app ID is the correct one — **contact the Content Ignite team to confirm which app ID to use**.
2. Next add a `SKAdNetworkItems` key to your `Info.plist` with SKAdNetworkIdentifier values for Google (`cstr6suwn9.skadnetwork`) and [select third-party buyers](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/3p-skadnetworks) who have provided these values to Google.
```xml theme={null}
GADApplicationIdentifierSAMPLE_APP_IDSKAdNetworkItemsSKAdNetworkIdentifiercstr6suwn9.skadnetworkSKAdNetworkIdentifier4fzdc2evr5.skadnetworkSKAdNetworkIdentifier2fnua5tdw4.skadnetworkSKAdNetworkIdentifierydx93a7ass.skadnetworkSKAdNetworkIdentifierp78axxw29g.skadnetworkSKAdNetworkIdentifierv72qych5uu.skadnetworkSKAdNetworkIdentifierludvb6z3bs.skadnetworkSKAdNetworkIdentifiercp8zw746q7.skadnetworkSKAdNetworkIdentifier3sh42y64q3.skadnetworkSKAdNetworkIdentifierc6k4g5qg8m.skadnetworkSKAdNetworkIdentifiers39g8k73mm.skadnetworkSKAdNetworkIdentifierwg4vff78zm.skadnetworkSKAdNetworkIdentifier3qy4746246.skadnetworkSKAdNetworkIdentifierf38h382jlk.skadnetworkSKAdNetworkIdentifierhs6bdukanm.skadnetworkSKAdNetworkIdentifiermlmmfzh3r3.skadnetworkSKAdNetworkIdentifierv4nxqhlyqp.skadnetworkSKAdNetworkIdentifierwzmmz9fp6w.skadnetworkSKAdNetworkIdentifiersu67r6k2v3.skadnetworkSKAdNetworkIdentifieryclnxrl5pm.skadnetworkSKAdNetworkIdentifiert38b2kh725.skadnetworkSKAdNetworkIdentifier7ug5zh24hu.skadnetworkSKAdNetworkIdentifiergta9lk7p23.skadnetworkSKAdNetworkIdentifiervutu7akeur.skadnetworkSKAdNetworkIdentifiery5ghdn5j9k.skadnetworkSKAdNetworkIdentifierv9wttpbfk9.skadnetworkSKAdNetworkIdentifiern38lu8286q.skadnetworkSKAdNetworkIdentifier47vhws6wlr.skadnetworkSKAdNetworkIdentifierkbd757ywx3.skadnetworkSKAdNetworkIdentifier9t245vhmpl.skadnetworkSKAdNetworkIdentifiera2p9lx4jpn.skadnetworkSKAdNetworkIdentifier22mmun2rn5.skadnetworkSKAdNetworkIdentifier44jx6755aq.skadnetworkSKAdNetworkIdentifierk674qkevps.skadnetworkSKAdNetworkIdentifier4468km3ulz.skadnetworkSKAdNetworkIdentifier2u9pt9hc89.skadnetworkSKAdNetworkIdentifier8s468mfl3y.skadnetworkSKAdNetworkIdentifierklf5c3l5u5.skadnetworkSKAdNetworkIdentifierppxm28t8ap.skadnetworkSKAdNetworkIdentifierkbmxgpxpgc.skadnetworkSKAdNetworkIdentifieruw77j35x4d.skadnetworkSKAdNetworkIdentifier578prtvx9j.skadnetworkSKAdNetworkIdentifier4dzt52r2t5.skadnetworkSKAdNetworkIdentifiertl55sbb4fm.skadnetworkSKAdNetworkIdentifierc3frkrj4fj.skadnetworkSKAdNetworkIdentifiere5fvkxwrpn.skadnetworkSKAdNetworkIdentifier8c4e2ghe7u.skadnetworkSKAdNetworkIdentifier3rd42ekr43.skadnetworkSKAdNetworkIdentifier97r2b46745.skadnetworkSKAdNetworkIdentifier3qcr597p9d.skadnetwork
```
## Installation
Use of the following methods to install the Content Ignite Mobile SDK.
### Swift Package Manager
To install the SDK into your project using [Swift Package Manager](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app#Add-a-package-dependency):
1. In Xcode, install the Content Ignite Mobile SDK SwiftUI Package using File > Add Package Dependencies...
2. When the prompt appears, search for the following URL for the SwiftUI version of the SDK:
```
https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-swiftui
```
3. Select the version of the Content Ignite Mobile SDK SwiftUI Package you want to use. For new projects, we recommend using the Up to Next Major Version.
### CocoaPods
Before you continue, review [Using CocoaPods](https://guides.cocoapods.org/using/using-cocoapods) for information on creating and using Podfiles.
To install the SDK into your project using [CocoaPods](https://guides.cocoapods.org/using/getting-started):
1. Open your project's Podfile and add this line to your app's target build configuration:
```
pod 'Content-Ignite-Mobile-SwiftUI'
```
2. In a terminal, run:
```bash theme={null}
pod install --repo-update
```
3. In your project's build settings:
* Add the `-ObjC` linker flag to Other linker flags.
## Initialising the SDK
First we will create an instance of `CIMobileAdsConfiguration`. This is achieved using `CIMobileAdsConfiguration.Builder`.
The builder takes one required parameter:
* `publisherId`: String: A unique identifier to identify the publisher in the Fusion platform.
Then call the `build` API to create the instance.
When creating an instance of `CIMobileAdsConfiguration` it is possible to enable optional features on the SDK including debugging and test ads.
```swift theme={null}
let configuration = CIMobileAdsConfiguration.Builder(
publisherId: ""
)
.setDebugFeature(enabled: true)
.setTestAds(enabled: true)
.build()
```
* `setTestAds(enabled: Bool)` was added to `CIMobileAdsConfiguration.Builder` in `1.7.0` to control whether test ads are enabled, this was previously only possible from the debug menu. If this is set the Debug Menu option will be hidden and if not set the Debug Menu option will be used.
Next we pass this configuration into the singleton instance `CIMobileAds` initialise API. This is an async-await function.
It takes one required parameter:
* `configuration`: An instance of `CIMobileAdsConfiguration`.
The call to initialise the SDK should be made as early as possible in the application lifecycle.
If you are currently using Google Mobile Ads SDK, it is no longer necessary to initialise this separately, and this code should be removed.
An example is shown below:
```swift theme={null}
import CIMobileSDK
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -> Bool {
let configuration = CIMobileAdsConfiguration.Builder(
publisherId: ""
)
.setDebugFeature(enabled: true)
.setTestAds(enabled: true)
.build()
Task {
let status = try await CIMobileAds.shared.initialise(
configuration: configuration
)
switch status {
case .succeeded:
print("CIMobileSDK initialisation succeeded")
case .failed:
print("CIMobileSDK initialisation failed")
}
}
return true
}
}
```
### Select an ad format
Content Ignite Mobile SDK is now imported and you're ready to implement an ad. We offer a number of different formats:
Ads that appear when a user opens or switches back to your app.
Flexibly sized format for placing ads anywhere in your app.
Full-screen ads that are designed to appear between content transitions.
# Debug features
Source: https://docs.contentignite.com/app/ios_uikit/debugging
Using the Debugging features
The SDK gives developers the option of enabling the debugging features when running the application by using the `setDebugFeature(enabled:)` when using `CIMobileAdsConfiguration.Builder` and setting the `enabled` parameter to `true` as seen in the [Initialising the SDK](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-uikit#initialising-the-sdk) section.
When enabled it allows a user to perform the gesture demonstrated below.

When the user performs the gesture, this will open a debug menu, which gives the following options:
### Clear ads configs cache
When updating configs in the Fusion platform, these are stored by the SDK and refreshed periodically. Pressing this button will force the SDK to download the new configs from the server.
### Clear floors cache
When updating floors data within fusion, this data is stored by the SDK and refreshed periodically. Pressing this button will force the SDK to download the new floors data from the server.
### Start a new debug session
Opens a dialog where the user is required to enter a PIN which is provided within the [Fusion](https://www.contentignite.com/fusion) dashboard.
When this PIN is entered correctly, the SDK will start sending detailed logs for a fixed period of time to the Content Ignite team to allow them to diagnose issues more effectively.
### Enabling / Disabling Test ads
During development to prevent invalid traffic in Google Ad Manager, we recommend you enable test ads. This guarantees an ad will always be served, either from GAM or Prebid depending on your setup, helping for use during demos.
This can also be controlled using `setTestAds(enabled: Boolean)` on `CIMobileAdsConfiguration.Builder`.
# App Open
Source: https://docs.contentignite.com/app/ios_uikit/ios_uikit_app_open
Setting up App Open ads
App Open Ads have two possible flows designed to be used together: Cold start and Resuming from background.
For both use cases, we use the `CIAppOpenAdManager` API, which has `loadAd()` and `show()` methods to handle the App Open ad lifecycle. This is a singleton object which can be accessed via `CIAppOpenAdManager.shared`.
## Cold start (Splash screen)
The first approach allows you to monetise the loading screen of your app. When the user opens the app, the splash screen is displayed. While your app is loading, our SDK will load an Ad. If the ad is loaded in time you can control whether the ad is displayed before the home screen of your app is displayed. The example below is taken from our demo app:
```swift theme={null}
import UIKit
import CIMobileSDK
enum SplashState {
case loading
case adReady
case navigateToHome
}
@MainActor
final class SplashViewModel {
private let adLoadTimeout: Duration = .seconds(5)
private let adManager: CIAppOpenAdManager
// 1. Monitor state changes in the UI
var onStateChanged: ((SplashState) -> Void)?
private var state: SplashState = .loading {
didSet { onStateChanged?(state) }
}
init(adManager: CIAppOpenAdManager) {
// 2. Store an instance of CIAppOpenAdManager
self.adManager = adManager
}
func load() {
// 3. Initialise the SDK
let configuration = CIMobileAdsConfiguration.Builder(publisherId: "")
.setDebugFeature(enabled: true)
.enableAppOpen(placementID: "")
.build()
Task {
let status = try await CIMobileAds.shared.initialise(
configuration: configuration
)
switch status {
case .succeeded:
print("CIMobileSDK initialization succeeded")
let adLoaded = await loadAdWithTimeout()
Task { @MainActor in
state = adLoaded ? .adReady : .navigateToHome
}
case .failed:
print("CIMobileSDK initialization failed")
navigateToHome()
}
}
Task {
for await event in adManager.state {
if event == .dismissed {
navigateToHome()
}
}
}
}
private func loadAdWithTimeout() async -> Bool {
// 4. Call loadAd() on the CIAppOpenManager instance
adManager.loadAd()
let adManager = self.adManager
return await withTaskGroup(of: Bool?.self) { group in
group.addTask {
for await state in adManager.state {
switch state {
case .loaded: return true
case .loadFailed: return false
default:
continue
}
}
return false
}
group.addTask {
try? await Task.sleep(for: self.adLoadTimeout)
return nil
}
for await result in group {
group.cancelAll()
return result ?? false
}
return false
}
}
private func navigateToHome() {
Task { @MainActor [weak self] in
self?.state = .navigateToHome
}
}
func showAd() {
// 5. Call the CIAppOpenAdManager to show the Ad.
adManager.show()
}
}
```
Let's break down this code:
1. In this simple example, we use a `SplashState` enumeration to communicate our state changes back to the UI, here this is done using a callback.
2. In our ViewModel we store an instance of `CIAppOpenAdManager`.
3. Enabling App Open ads is achieved by using `enableAppOpen(placementID: String)` in the SDK configuration builder. Passing in the placement ID which will be supplied to you by [Content Ignite](https://www.contentignite.com/).
4. In this example we use a simple timeout to simulate the loading of the app and attempt to load an ad before the timeout is reached.
5. Calling the `show()` method on `CIAppOpenManager` to show the ad.
From the UI we can control when the ad is shown by responding to the state updates. We make use of a `AppRouter`, which in this example holds a variable to track if the splash screen has been completed, which is updated by calling `navigateToHome()`:
```swift theme={null}
import UIKit
final class SplashViewController: UIViewController {
private let viewModel: SplashViewModel
private let router: AppRouter
...
private func bindViewModel() {
viewModel.onStateChanged = { [weak self] state in
guard let self else { return }
switch state {
case .loading:
...
case .adReady:
...
self.viewModel.showAd()
case .navigateToHome:
self.router.navigateToHome()
}
}
}
}
```
## Resuming from background
For this approach we listen to the `sceneWillEnterForeground` from `UISceneDelegate`. Additionally we use `AppRouter` which handles the navigation and holds a `splashCompleted` Boolean value.
```swift theme={null}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
private var router: AppRouter?
private let adManager = CIAppOpenAdManager.shared
...
func sceneWillEnterForeground(_ scene: UIScene) {
guard let router, router.splashCompleted else { return }
Task { @MainActor in
adManager.show()
}
}
}
```
See the full examples: [**SPM**](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-uikit/-/tree/main/Demos/AppOpenUIKit-SPM?ref_type=heads) | [**CocoaPods**](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-uikit/-/tree/main/Demos/AppOpenUIKit-CocoaPods?ref_type=heads).
# Banner Ads
Source: https://docs.contentignite.com/app/ios_uikit/ios_uikit_banner
Setting up Banner ads
The SDK supports Banner Ads via the `CIBannerView` `UIView`. With the following parameters:
### Required
* `placementID: String`: Unique ID for this Ad Placement provided by Content Ignite.
* `pageUrl: String?`: This is used for targeting for example if the ad is displayed inline within an article or section of the app which has an equivalent URL on the web.
### Optional
* `delegate: CIBannerViewDelegate`: This protocol allows you to respond to events related to the banner ad.
* `targeting: [String: [String]]`: Pass custom key-value pairs to ad requests.
* `publisher: (() -> UIView)?`: Closure to allow you to provide a fallback to your existing Ad implementation for this particular placement. This gives publishers full control over the use of the SDK and the rate at which this fallback is used can be controlled directly through the Fusion platform.
An example is shown below:
```swift theme={null}
import CIMobileSDKUIKit
let targeting = ["segment" : ["health","fitness"]]
let banner = CIBannerView(
placementID: "",
pageUrl: "https://publisher.com/sport",
targeting: targeting,
delegate: self
) {
// Publisher fallback implementation
}
view.addSubview(banner)
banner.translatesAutoresizingMaskIntoConstraints = false
let margins = view.layoutMarginsGuide
NSLayoutConstraint.activate([
banner.centerXAnchor.constraint(equalTo: view.centerXAnchor),
banner.bottomAnchor.constraint(equalTo: margins.bottomAnchor)
])
Task { await banner.load() }
```
## Handling ad events
To listen and respond to events from a Banner ad, use the `CIBannerViewDelegate` protocol:
```swift theme={null}
extension BannerViewController: CIBannerViewDelegate {
public func bannerLoaded() {
print("Banner ad loaded.")
}
public func bannerLoadFailed(error: Error) {
print("Banner ad failed to load: \(error.localizedDescription)")
}
public func bannerClicked() {
print("Banner ad clicked.")
}
public func bannerImpression() {
print("Banner ad impression.")
}
}
```
See the full examples: [SPM](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-uikit/-/tree/main/Demos/CIMobileSDK-UIKit-SPM?ref_type=heads) | [CocoaPods](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-uikit/-/tree/main/Demos/CIMobileSDK-UIKit-CocoaPods?ref_type=heads).
# Interstitial Ads
Source: https://docs.contentignite.com/app/ios_uikit/ios_uikit_interstitial
Setting up Interstitial ads
Interstitial ads are full-screen ads that cover the interface of the app. They're typically displayed at natural transition points in the flow of the app.
## Initialising an ad
Start by initialising an instance of a `CIInterstitial` with the following parameters:
### Required:
* `placementID: String`: Unique ID for this Ad Placement provided by Content Ignite.
* `pageUrl: String?`: URL used for targeting for example if the ad is displayed in a section of the app which has an equivalent URL on the web.
* `eventListener: CIInterstitialEventListener`: This protocol allows you to respond to events related to the interstitial ad.
### Optional:
* `publisher`: Optional lambda to provide a fallback to your existing Ad implementation for this particular interstitial. This gives publishers full control over the use of the SDK and the rate at which this fallback is used can be controlled directly through the [Fusion](https://www.contentignite.com/fusion) platform.
```swift theme={null}
// Replace with your real placement ID
import UIKit
import CIMobileSDK
final class InterstitialDemoViewController: UIViewController {
@MainActor
private func loadAd() async {
...
interstitial = CIInterstitial(
placementID: "",
pageUrl: "https://publisher.com/sport",
eventListener: self
)
...
}
}
```
## Load the ad
When you are ready to load the ad, call `load()` on the ad instance:
```swift theme={null}
do {
try await interstitial?.load()
} catch {
print("Failed to load interstitial ad with error: \(error.localizedDescription)")
...
}
```
## Handling ad events
To listen and respond to events from an Interstitial ad, use the `CIInterstitialEventListener` protocol:
```swift theme={null}
extension InterstitialDemoViewController: CIInterstitialEventListener {
func interstitialLoaded() {
DispatchQueue.main.async { [weak self] in
self?.uiState = .loaded
}
}
func interstitialLoadFailed() {
DispatchQueue.main.async { [weak self] in
self?.uiState = .failed
}
}
func interstitialDismissed() {
DispatchQueue.main.async { [weak self] in
self?.uiState = .initial
}
}
}
```
## Show the ad
When you are ready to display the ad, such as after a transition in the app flow, use the `show` method to display the ad:
```swift theme={null}
interstitial?.show()
```
See the full examples: [SPM](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-uikit/-/tree/main/Demos/CIMobileSDK-UIKit-SPM?ref_type=heads) | [CocoaPods](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-uikit/-/tree/main/Demos/CIMobileSDK-UIKit-CocoaPods?ref_type=heads).
# Introduction
Source: https://docs.contentignite.com/app/ios_uikit/ios_uikit_intro
Get started with your iOS (UIKit) integration
## Prerequisites
### Requirements
* Use Xcode 16.0 or higher.
* Target iOS 17.2 or higher.
### Updating your Info.plist
1. Before installing, update the application `Info.plist` to add a GADApplicationIdentifier key with a string value of your Google Ad Manager app ID, of the form `ca-app-pub-################~##########`.
Which app ID to use depends on your Content Ignite setup. **Plug-and-play** customers (using Content Ignite's Google Ad Manager account) use the app ID **provided by Content Ignite**. **SaaS** customers use **their own** Google Ad Manager account's app ID. If you are migrating from the Google Mobile Ads SDK, do not assume your existing app ID is the correct one — **contact the Content Ignite team to confirm which app ID to use**.
2. Next add a `SKAdNetworkItems` key to your `Info.plist` with SKAdNetworkIdentifier values for Google (`cstr6suwn9.skadnetwork`) and [select third-party buyers](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/3p-skadnetworks) who have provided these values to Google.
```xml theme={null}
GADApplicationIdentifierSAMPLE_APP_IDSKAdNetworkItemsSKAdNetworkIdentifiercstr6suwn9.skadnetworkSKAdNetworkIdentifier4fzdc2evr5.skadnetworkSKAdNetworkIdentifier2fnua5tdw4.skadnetworkSKAdNetworkIdentifierydx93a7ass.skadnetworkSKAdNetworkIdentifierp78axxw29g.skadnetworkSKAdNetworkIdentifierv72qych5uu.skadnetworkSKAdNetworkIdentifierludvb6z3bs.skadnetworkSKAdNetworkIdentifiercp8zw746q7.skadnetworkSKAdNetworkIdentifier3sh42y64q3.skadnetworkSKAdNetworkIdentifierc6k4g5qg8m.skadnetworkSKAdNetworkIdentifiers39g8k73mm.skadnetworkSKAdNetworkIdentifierwg4vff78zm.skadnetworkSKAdNetworkIdentifier3qy4746246.skadnetworkSKAdNetworkIdentifierf38h382jlk.skadnetworkSKAdNetworkIdentifierhs6bdukanm.skadnetworkSKAdNetworkIdentifiermlmmfzh3r3.skadnetworkSKAdNetworkIdentifierv4nxqhlyqp.skadnetworkSKAdNetworkIdentifierwzmmz9fp6w.skadnetworkSKAdNetworkIdentifiersu67r6k2v3.skadnetworkSKAdNetworkIdentifieryclnxrl5pm.skadnetworkSKAdNetworkIdentifiert38b2kh725.skadnetworkSKAdNetworkIdentifier7ug5zh24hu.skadnetworkSKAdNetworkIdentifiergta9lk7p23.skadnetworkSKAdNetworkIdentifiervutu7akeur.skadnetworkSKAdNetworkIdentifiery5ghdn5j9k.skadnetworkSKAdNetworkIdentifierv9wttpbfk9.skadnetworkSKAdNetworkIdentifiern38lu8286q.skadnetworkSKAdNetworkIdentifier47vhws6wlr.skadnetworkSKAdNetworkIdentifierkbd757ywx3.skadnetworkSKAdNetworkIdentifier9t245vhmpl.skadnetworkSKAdNetworkIdentifiera2p9lx4jpn.skadnetworkSKAdNetworkIdentifier22mmun2rn5.skadnetworkSKAdNetworkIdentifier44jx6755aq.skadnetworkSKAdNetworkIdentifierk674qkevps.skadnetworkSKAdNetworkIdentifier4468km3ulz.skadnetworkSKAdNetworkIdentifier2u9pt9hc89.skadnetworkSKAdNetworkIdentifier8s468mfl3y.skadnetworkSKAdNetworkIdentifierklf5c3l5u5.skadnetworkSKAdNetworkIdentifierppxm28t8ap.skadnetworkSKAdNetworkIdentifierkbmxgpxpgc.skadnetworkSKAdNetworkIdentifieruw77j35x4d.skadnetworkSKAdNetworkIdentifier578prtvx9j.skadnetworkSKAdNetworkIdentifier4dzt52r2t5.skadnetworkSKAdNetworkIdentifiertl55sbb4fm.skadnetworkSKAdNetworkIdentifierc3frkrj4fj.skadnetworkSKAdNetworkIdentifiere5fvkxwrpn.skadnetworkSKAdNetworkIdentifier8c4e2ghe7u.skadnetworkSKAdNetworkIdentifier3rd42ekr43.skadnetworkSKAdNetworkIdentifier97r2b46745.skadnetworkSKAdNetworkIdentifier3qcr597p9d.skadnetwork
```
## Installation
Use of the following methods to install the Content Ignite Mobile SDK.
### Swift Package Manager
To install the SDK into your project using [Swift Package Manager](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app#Add-a-package-dependency):
1. In Xcode, install the Content Ignite Mobile SDK UIKit Package using File > Add Package Dependencies...
2. When the prompt appears, search for the following URL for the UIKit version of the SDK:
```
https://gitlab.com/content-ignite/content-ignite-mobile-sdk-ios-uikit
```
3. Select the version of the Content Ignite Mobile SDK UIKit Package you want to use. For new projects, we recommend using the Up to Next Major Version.
### CocoaPods
Before you continue, review [Using CocoaPods](https://guides.cocoapods.org/using/using-cocoapods) for information on creating and using Podfiles.
To install the SDK into your project using [CocoaPods](https://guides.cocoapods.org/using/getting-started):
1. Open your project's Podfile and add this line to your app's target build configuration:
```
pod 'Content-Ignite-Mobile-UIKit'
```
2. In a terminal, run:
```bash theme={null}
pod install --repo-update
```
3. In your project's build settings:
* Add the `-ObjC` linker flag to Other linker flags.
## Initialising the SDK
First we will create an instance of `CIMobileAdsConfiguration`. This is achieved using `CIMobileAdsConfiguration.Builder`.
The builder takes one required parameter:
* `publisherId`: String: A unique identifier to identify the publisher in the Fusion platform.
Then call the `build` API to create the instance.
When creating an instance of `CIMobileAdsConfiguration` it is possible to enable optional features on the SDK including debugging and test ads.
```swift theme={null}
let configuration = CIMobileAdsConfiguration.Builder(
publisherId: ""
)
.setDebugFeature(enabled: true)
.setTestAds(enabled: true)
.build()
```
* `setTestAds(enabled: Bool)` was added to `CIMobileAdsConfiguration.Builder` in `1.7.0` to control whether test ads are enabled, this was previously only possible from the debug menu. If this is set the Debug Menu option will be hidden and if not set the Debug Menu option will be used.
Next we pass this configuration into the singleton instance `CIMobileAds` initialise API. This is an async-await function.
It takes one required parameter:
* `configuration`: An instance of `CIMobileAdsConfiguration`.
The call to initialise the SDK should be made as early as possible in the application lifecycle.
If you are currently using Google Mobile Ads SDK, it is no longer necessary to initialise this separately, and this code should be removed.
An example is shown below:
```swift theme={null}
import CIMobileSDK
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -> Bool {
let configuration = CIMobileAdsConfiguration.Builder(
publisherId: ""
)
.setDebugFeature(enabled: true)
.setTestAds(enabled: true)
.build()
Task {
let status = try await CIMobileAds.shared.initialise(
configuration: configuration
)
switch status {
case .succeeded:
print("CIMobileSDK initialisation succeeded")
case .failed:
print("CIMobileSDK initialisation failed")
}
}
return true
}
}
```
### Select an ad format
Content Ignite Mobile SDK is now imported and you're ready to implement an ad. We offer a number of different formats:
Ads that appear when a user opens or switches back to your app.
Flexibly sized format for placing ads anywhere in your app.
Full-screen ads that are designed to appear between content transitions.
# Privacy & Consent (CMPs)
Source: https://docs.contentignite.com/app/privacy
Why a TCF-certified Consent Management Platform is required for your mobile app integration
Privacy is at the forefront of everything we do at Content Ignite, and we believe you, the publisher, should own and control your users' privacy. For that reason we do not ship a "default" consent experience inside the Mobile SDK. Instead, we require you to integrate a certified **Consent Management Platform (CMP)** in your app.
A correctly implemented CMP is not just a legal safeguard — it has a direct impact on your ad revenue. When valid consent is present, ads can be served as **personalised**, which typically monetises significantly better than the **non-personalised** ads that are served when consent is missing or cannot be read.
## What is a CMP?
A CMP's job is to collect consent from your users in regions where consent is legally required for the sharing of personal data (such as the EEA and UK), and to make that consent readable, in a standardised format, by every party in your ad stack.
CMPs first appeared as a response to the European Union's GDPR, which requires users to opt in to data sharing up front. To make consent readable by any third party in a uniform way, the IAB introduced the **Transparency & Consent Framework (TCF)** — a single framework that all CMPs adhere to, so that any downstream partner knows how to read user consent regardless of which CMP a publisher chooses.
For a deeper, framework-level explanation of CMPs, TCF, GPP and consent generally, see the full [CMP Guide](/getting-started/cmp-guide). This page focuses on what a CMP means specifically for your **Mobile SDK** integration.
## Why we require a TCF-certified CMP
A TCF-compliant CMP is responsible for:
* Presenting users with the IAB TCF consent experience, including the standardised purposes, special purposes, features and legal bases defined by the framework.
* Presenting the Global Vendor List (GVL), allowing users to grant or deny consent for participating advertising vendors.
* Generating and storing a standardised **TC String** containing the user's consent choices.
* Making that TC String available to downstream advertising partners (SSPs, exchanges, mediation platforms, demand partners, etc.) via the recognised TCF APIs so that consent signals can be read and honoured throughout the ad serving chain.
Without a certified CMP, SSPs and buyers are generally unable to reliably determine user consent status in the standardised format expected by the ecosystem, which can result in **reduced demand, restricted personalised advertising, or non-compliance with partner requirements**.
For that reason, we require a **TCF-certified CMP** implementation rather than a custom consent flow. Suitable providers include, for example:
* [InMobi Choice](https://www.inmobi.com/choice)
* [Sourcepoint](https://www.sourcepoint.com/)
* [OneTrust](https://www.onetrust.com/)
* [Didomi](https://www.didomi.io/)
* [Usercentrics](https://usercentrics.com/)
**Key Takeaway**
Choose a CMP that is clearly listed as **TCF** (and, where you operate globally, **GPP**) certified, and that provides a native **mobile SDK** for Android and iOS. A custom or web-only consent flow will not produce a consent signal that our SDK and downstream partners can read.
## How consent reaches the SDK on mobile
On the web, consent is passed via the `__tcfapi` JavaScript API and the ordering of page scripts matters (this is why web integrations rely on a CMP "stub"). **In a mobile app there is no stub and no script ordering** — the mechanism is simpler and is defined by the IAB's *Mobile In-App CMP API* specification:
1. Your chosen CMP's mobile SDK presents the consent experience to the user.
2. The CMP writes the resulting **TC String** (and related TCF keys, all prefixed with `IABTCF_`) into the standard platform storage:
* **Android** — the app's default `SharedPreferences`.
* **iOS** — `UserDefaults` (`NSUserDefaults`).
3. The Content Ignite Mobile SDK, the Google Mobile Ads SDK, Prebid and the other partners in your ad stack read those values from platform storage and honour them automatically when requesting ads.
Because consent is read from shared platform storage, **you do not pass the TC String to us manually** — once the CMP has written it, the signal is available to the whole ad serving chain.
### Initialise the CMP before requesting ads
The one ordering rule that does matter on mobile is timing. Initialise and gather consent through your CMP **before** you initialise the Content Ignite Mobile SDK and request your first ad, so that a valid TC String is already present in platform storage when the ad request is made.
If the SDK is initialised and ads are requested before the CMP has written a TC String, those early requests can only be served as **non-personalised**, reducing the revenue from that session. Gather consent first, then initialise the SDK as described in the relevant platform guide ([Android](/app/android/android_intro), [iOS SwiftUI](/app/ios_swiftui/ios_swiftui_intro), [iOS UIKit](/app/ios_uikit/ios_uikit_intro), [React Native](/app/react_native/react_native_intro)).
### Vendor list
As part of configuring your CMP, ensure Content Ignite and the ad partners we integrate with are enabled in your vendor list (the GVL). If we, or our demand partners, are not consented in the vendor list, our consent signal will read as missing and ad serving will default to non-personalised. Most CMPs enable all vendors by default, but it is always worth confirming — especially if you trim the vendor list.
## Need help choosing or implementing a CMP?
We do not provide a pre-configured CMP, as privacy control should remain with you. However, we can advise on suitable third-party CMPs based on our extensive experience in this field — simply reach out to your account manager, who will be happy to assist. You can also read more about the CMP options we work with in our [Ad Tech integrations](/integrations/ad-tech#cmps) documentation.
# App Open
Source: https://docs.contentignite.com/app/react_native/app-open
Setting up App Open ads
App Open Ads have two possible flows designed to be used together: Cold start and Resuming from background.
App Open ads must be enabled when you initialise the SDK by passing `appOpenPlacementId` to
`ContentIgniteSDK.initialise` (see the [Introduction](/app/react_native/react_native_intro)).
Once enabled, use the `CIAppOpenAd` singleton to load and show ads.
## Cold start (Splash screen)
The first approach allows you to monetise the loading screen of your app. When the user opens the app, the splash screen is displayed. While your app is loading, the SDK will load an ad. If the ad loads in time you can display it before the home screen of your app is shown.
Race the load against a short timeout so a slow load never blocks the user from reaching your app:
```tsx theme={null}
import ContentIgniteSDK, { CIAppOpenAd } from '@content-ignite/mobile-sdk-react-native';
const AD_LOAD_TIMEOUT_MS = 5000;
// Resolves false after the timeout so a slow load never blocks the app.
const timeout = (ms: number) =>
new Promise((resolve) => setTimeout(() => resolve(false), ms));
async function bootstrap() {
const initialised = await ContentIgniteSDK.initialise({
publisherId: '',
googleId: 'ca-app-pub-3940256099942544~3347511713',
debugFeature: true,
appOpenPlacementId: '',
});
if (initialised) {
const loaded = await Promise.race([CIAppOpenAd.load(), timeout(AD_LOAD_TIMEOUT_MS)]);
if (loaded) {
await CIAppOpenAd.show(); // resolves once the ad is dismissed
}
}
// Reveal the home screen.
}
```
## Resuming from background
To monetise the app returning to the foreground, listen to React Native's
[`AppState`](https://reactnative.dev/docs/appstate). When the app becomes `active`, show a ready ad,
otherwise load one for the next foreground:
```tsx theme={null}
import { useEffect } from 'react';
import { AppState, AppStateStatus } from 'react-native';
import { CIAppOpenAd } from '@content-ignite/mobile-sdk-react-native';
function useAppOpenResume(splashCompleted: React.MutableRefObject) {
useEffect(() => {
const onChange = async (state: AppStateStatus) => {
// Only run once the cold-start splash flow has completed.
if (state !== 'active' || !splashCompleted.current) return;
try {
if (await CIAppOpenAd.isAvailable()) {
await CIAppOpenAd.show();
} else {
// No ad ready — load one for the next foreground.
CIAppOpenAd.load();
}
} catch (error) {
console.warn('App Open resume flow failed:', error);
}
};
const subscription = AppState.addEventListener('change', onChange);
return () => subscription.remove();
}, [splashCompleted]);
}
```
Guard the resume flow with a flag (e.g. a `splashCompleted` ref set once the cold-start flow
finishes) so an ad isn't shown twice on the very first launch.
See the full example: [App Open sample app](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-react-native/-/tree/main/examples/example-app-open).
# Banner Ads
Source: https://docs.contentignite.com/app/react_native/banner
Setting up Banner ads
The SDK supports Banner Ads via the `CIBannerView` component. It accepts all standard React Native
[`ViewProps`](https://reactnative.dev/docs/view#props) (so you control the ad size through `style`)
plus the following parameters:
### Required
* `placementId: string`: Unique ID for this Ad Placement provided by Content Ignite.
* `pageUrl: string`: URL used for targeting, for example if the ad is displayed inline within an article or section of the app which has an equivalent URL on the web.
* `targeting: Record`: Pass custom key-value pairs to ad requests.
### Optional
* `style`: Standard React Native style used to size the banner (e.g. `{ width: 300, height: 250 }`).
* `onBannerLoaded: () => void`: Called when the ad has loaded successfully.
* `onBannerLoadFailed: (event) => void`: Called when the ad fails to load. The reason is available on `event.nativeEvent.error`.
* `onBannerClicked: () => void`: Called when the user taps the ad.
* `onBannerImpression: () => void`: Called when an impression is recorded.
```tsx theme={null}
import { CIBannerView } from '@content-ignite/mobile-sdk-react-native';
import { View, StyleSheet } from 'react-native';
function BannerScreen({ isSDKInitialised }: { isSDKInitialised: boolean }) {
if (!isSDKInitialised) {
return ;
}
return (
console.log('Banner loaded')}
onBannerLoadFailed={(e) => console.warn('Banner failed:', e.nativeEvent.error)}
onBannerClicked={() => console.log('Banner clicked')}
onBannerImpression={() => console.log('Banner impression')}
style={styles.banner}
/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
banner: {
width: 300,
height: 250,
},
});
```
The banner is rendered natively, so make sure the SDK has been initialised
(see the [Introduction](/app/react_native/react_native_intro)) before mounting `CIBannerView`.
## Handling ad events
To listen and respond to events from a Banner ad, pass the `onBanner*` callbacks:
```tsx theme={null}
console.log('Banner ad loaded.')}
onBannerLoadFailed={(e) => console.warn('Banner ad failed to load:', e.nativeEvent.error)}
onBannerClicked={() => console.log('Banner ad clicked.')}
onBannerImpression={() => console.log('Banner ad impression.')}
style={{ width: 300, height: 250 }}
/>
```
See the full example: [Banner sample app](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-react-native/-/tree/main/examples/example).
# Debug features
Source: https://docs.contentignite.com/app/react_native/debugging
Using the Debugging features
## Using the Debug and test features
The SDK gives developers the option of enabling a debugging gesture when running the application by enabling this as part of the `CIMobileAdsConfiguration`, since version 1.2.0, the debug gesture is enabled by default.

When enabled and the user performs the gesture, this will open a debug menu, which gives the following options:
### Clear ads configs cache
When updating configs in the Fusion platform, these are stored by the SDK and refreshed periodically. Pressing this button will force the SDK to download the new configs from the server.
### Clear floors cache
When updating floors data within fusion, this data is stored by the SDK and refreshed periodically. Pressing this button will force the SDK to download the new floors data from the server.
### Start a new debug session
Opens a dialog where the user is required to enter a PIN which is provided within the [Fusion](https://www.contentignite.com/fusion) dashboard.
When this PIN is entered correctly, the SDK will start sending detailed logs for a fixed period of time to the Content Ignite team to allow them to diagnose issues more effectively.
### Enabling / Disabling Test ads
During development to prevent invalid traffic in Google Ad Manager, we recommend you enable test ads. This guarantees an ad will always be served, either from GAM or Prebid depending on your setup, helping for use during demos.
This can also be controlled using the `testAds: Boolean` parameter on `ContentIgniteSDK.initialise`.
# Interstitial Ads
Source: https://docs.contentignite.com/app/react_native/interstitial
Setting up Interstitial ads
Interstitial ads are full-screen ads that cover the interface of the app. They're typically displayed at natural transition points in the flow of the app.
## Initialising an ad
Start by creating an instance of `CIInterstitialAd` with the following parameters. Create one instance per ad you intend to show.
### Required
* `placementId: string`: Unique ID for this Ad Placement provided by Content Ignite.
### Optional
* `pageUrl: string`: URL used for targeting, for example if the ad is displayed in a section of the app which has an equivalent URL on the web.
* `targeting: Record`: Pass custom key-value pairs to ad requests.
* `eventListener: CIInterstitialEventListener`: Respond to load and dismiss events. See [Handling ad events](#handling-ad-events).
```tsx theme={null}
import { CIInterstitialAd } from '@content-ignite/mobile-sdk-react-native';
const ad = new CIInterstitialAd({
placementId: '',
pageUrl: 'https://example.com/sport',
targeting: { segment: ['health', 'fitness'] },
});
```
## Load the ad
When you are ready to load the ad, call `load()`. It resolves to `true` when an ad is ready and `false` if loading failed:
```tsx theme={null}
const loaded = await ad.load();
if (!loaded) {
console.warn('Interstitial failed to load');
}
```
## Show the ad
When you are ready to display the ad, such as after a transition in the app flow, call `show()`. Like `load()`, it resolves to a boolean: `true` once the ad has been shown and dismissed, or `false` immediately if no ad was loaded:
```tsx theme={null}
const shown = await ad.show(); // resolves to true once the ad is dismissed
if (!shown) {
console.warn('No interstitial was ready to show');
}
```
To show another ad after one is dismissed, call `load()` again to prepare a fresh ad.
## Handling ad events
To listen and respond to events from an Interstitial ad, pass a `CIInterstitialEventListener` when creating the ad. All callbacks are optional, so provide only the ones you need:
```tsx theme={null}
const ad = new CIInterstitialAd({
placementId: '',
pageUrl: 'https://example.com/sport',
eventListener: {
interstitialLoaded: () => console.log('Interstitial ad loaded.'),
interstitialLoadFailed: () => console.warn('Interstitial ad failed to load.'),
interstitialDismissed: () => console.log('Interstitial ad dismissed.'),
},
});
```
The listener is complementary to the promises returned by `load()` and `show()` — use whichever style suits your app. The events map to the same signals:
| Callback | Also surfaced by |
| ------------------------ | ------------------------- |
| `interstitialLoaded` | `load()` resolves `true` |
| `interstitialLoadFailed` | `load()` resolves `false` |
| `interstitialDismissed` | `show()` resolves `true` |
## Releasing the ad
Call `destroy()` to release the native ad, stop listening for events, and free resources — for example when the component that owns the ad unmounts:
```tsx theme={null}
import { useEffect, useRef } from 'react';
import { CIInterstitialAd } from '@content-ignite/mobile-sdk-react-native';
function InterstitialScreen() {
const adRef = useRef(null);
useEffect(() => {
return () => {
adRef.current?.destroy();
};
}, []);
const showAd = async () => {
const ad = new CIInterstitialAd({
placementId: '',
pageUrl: 'https://example.com/sport',
targeting: { segment: ['health', 'fitness'] },
});
adRef.current = ad;
if (await ad.load()) {
await ad.show(); // resolves once the ad is dismissed
}
};
// ...render a button that calls showAd()
}
```
See the full example: [Interstitial sample app](https://gitlab.com/content-ignite/content-ignite-mobile-sdk-react-native/-/tree/main/examples/example).
# Introduction
Source: https://docs.contentignite.com/app/react_native/react_native_intro
Get started with your React Native integration
## Installation
Install using the [npm](https://www.npmjs.com/) package manager:
```sh theme={null}
npm install @content-ignite/mobile-sdk-react-native
```
## Android Prerequisites
### Requirements
* Minimum SDK version of `24` or higher
* Compile SDK version of `36` or higher
## iOS Prerequisites
### Requirements
* Use Xcode 16.0 or higher.
* Target iOS 17.2 or higher.
### Updating your Info.plist
1. Before installing, update the application `Info.plist` to add a GADApplicationIdentifier key with a string value of your Google Ad Manager app ID, of the form `ca-app-pub-################~##########`.
Which app ID to use depends on your Content Ignite setup. **Plug-and-play** customers (using Content Ignite's Google Ad Manager account) use the app ID **provided by Content Ignite**. **SaaS** customers use **their own** Google Ad Manager account's app ID. If you are migrating from the Google Mobile Ads SDK, do not assume your existing app ID is the correct one — **contact the Content Ignite team to confirm which app ID to use**.
2. Next add a `SKAdNetworkItems` key to your `Info.plist` with SKAdNetworkIdentifier values for Google (`cstr6suwn9.skadnetwork`) and [select third-party buyers](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/3p-skadnetworks) who have provided these values to Google.
Complete snippet
```xml theme={null}
GADApplicationIdentifierSAMPLE_APP_IDSKAdNetworkItemsSKAdNetworkIdentifiercstr6suwn9.skadnetworkSKAdNetworkIdentifier4fzdc2evr5.skadnetworkSKAdNetworkIdentifier2fnua5tdw4.skadnetworkSKAdNetworkIdentifierydx93a7ass.skadnetworkSKAdNetworkIdentifierp78axxw29g.skadnetworkSKAdNetworkIdentifierv72qych5uu.skadnetworkSKAdNetworkIdentifierludvb6z3bs.skadnetworkSKAdNetworkIdentifiercp8zw746q7.skadnetworkSKAdNetworkIdentifier3sh42y64q3.skadnetworkSKAdNetworkIdentifierc6k4g5qg8m.skadnetworkSKAdNetworkIdentifiers39g8k73mm.skadnetworkSKAdNetworkIdentifierwg4vff78zm.skadnetworkSKAdNetworkIdentifier3qy4746246.skadnetworkSKAdNetworkIdentifierf38h382jlk.skadnetworkSKAdNetworkIdentifierhs6bdukanm.skadnetworkSKAdNetworkIdentifiermlmmfzh3r3.skadnetworkSKAdNetworkIdentifierv4nxqhlyqp.skadnetworkSKAdNetworkIdentifierwzmmz9fp6w.skadnetworkSKAdNetworkIdentifiersu67r6k2v3.skadnetworkSKAdNetworkIdentifieryclnxrl5pm.skadnetworkSKAdNetworkIdentifiert38b2kh725.skadnetworkSKAdNetworkIdentifier7ug5zh24hu.skadnetworkSKAdNetworkIdentifiergta9lk7p23.skadnetworkSKAdNetworkIdentifiervutu7akeur.skadnetworkSKAdNetworkIdentifiery5ghdn5j9k.skadnetworkSKAdNetworkIdentifierv9wttpbfk9.skadnetworkSKAdNetworkIdentifiern38lu8286q.skadnetworkSKAdNetworkIdentifier47vhws6wlr.skadnetworkSKAdNetworkIdentifierkbd757ywx3.skadnetworkSKAdNetworkIdentifier9t245vhmpl.skadnetworkSKAdNetworkIdentifiera2p9lx4jpn.skadnetworkSKAdNetworkIdentifier22mmun2rn5.skadnetworkSKAdNetworkIdentifier44jx6755aq.skadnetworkSKAdNetworkIdentifierk674qkevps.skadnetworkSKAdNetworkIdentifier4468km3ulz.skadnetworkSKAdNetworkIdentifier2u9pt9hc89.skadnetworkSKAdNetworkIdentifier8s468mfl3y.skadnetworkSKAdNetworkIdentifierklf5c3l5u5.skadnetworkSKAdNetworkIdentifierppxm28t8ap.skadnetworkSKAdNetworkIdentifierkbmxgpxpgc.skadnetworkSKAdNetworkIdentifieruw77j35x4d.skadnetworkSKAdNetworkIdentifier578prtvx9j.skadnetworkSKAdNetworkIdentifier4dzt52r2t5.skadnetworkSKAdNetworkIdentifiertl55sbb4fm.skadnetworkSKAdNetworkIdentifierc3frkrj4fj.skadnetworkSKAdNetworkIdentifiere5fvkxwrpn.skadnetworkSKAdNetworkIdentifier8c4e2ghe7u.skadnetworkSKAdNetworkIdentifier3rd42ekr43.skadnetworkSKAdNetworkIdentifier97r2b46745.skadnetworkSKAdNetworkIdentifier3qcr597p9d.skadnetwork
```
## Initialisation
Initialise the SDK once, early in your app's lifecycle (for example in a top-level `useEffect`) and before rendering any ads. `ContentIgniteSDK.initialise` takes a configuration object and returns a promise that resolves to `true` once the SDK is ready.
### Required
* `publisherId: string`: A unique identifier for the publisher in the Fusion platform, provided by Content Ignite.
* `googleId: string`: Your Google Ad Manager app ID, of the form `ca-app-pub-################~##########`. Plug-and-play customers use the ID provided by Content Ignite; SaaS customers use their own Google Ad Manager account app ID — contact Content Ignite if you are unsure which applies.
* `debugFeature: boolean`: Enables the in-app debug menu — see [Using the Debug features](#using-the-debug-features).
### Optional
* `testAds: boolean`: Serve test creatives instead of live ads during development. Defaults to `false`.
* `appOpenPlacementId: string`: Enables App Open ads via the `CIAppOpenAd` API — see [App Open](/app/react_native/app-open).
```js theme={null}
import ContentIgniteSDK from '@content-ignite/mobile-sdk-react-native';
export default function App() {
const [isSDKInitialised, setIsSDKInitialized] = useState(false);
useEffect(() => {
initializeSDK();
}, []);
const initializeSDK = async () => {
try {
await ContentIgniteSDK.initialise({
publisherId: '',
googleId: "ca-app-pub-3940256099942544~3347511713",
appOpenPlacementId: "",
testAds: true,
debugFeature: true,
}).then(() => {
console.log('SDK initialized');
setIsSDKInitialized(true);
});
} catch (error) {
console.error('Failed to initialize SDK:', error);
setIsSDKInitialized(false);
}
}
...
```
### Select an ad format
Content Ignite Mobile SDK is now imported and you're ready to implement an ad. We offer a number of different formats:
Ads that appear when a user opens or switches back to your app.
Flexibly sized format for placing ads anywhere in your app.
Full-screen ads that are designed to appear between content transitions.
# Contextual
Source: https://docs.contentignite.com/audiences/contextual
Allow our tech to categorise your pages ready for building audiences
Our contextual features use a natural language AI to crawl and process your publisher pages, build an entity list and via our audience builder, push that information into the ad server for targeting.
This can be enabled on a per publisher basis by reaching out to your account manager.
This is a powerful feature that does not rely on cookies or user tracking of any form. With most major browsers implementing some form of automatic tracking prevention, this is a solution that produces targetable pools based on your site's content without impacting user privacy.
***Note: For contextual page crawling to work, your publisher domain in our system must match the domain the ad request comes from. Only then will your site be processed.***
## Cost
Contextual is priced based on pages crawled. Once we have crawled a page and its data is saved, usage of that data is free for life.
When contextual is enabled for the first time, every page that is visited on your site, will be detected as "un-crawled", and therefore will trigger a new page crawl. This means you will see a high page crawl rate at first, and therefore higher costs. However, this will soon drop down to a much lower crawl rate simply based on any new pages you publish.
## Flow and performance
We process pages that our tag is loaded on. This means that the first time someone visits a page, a page crawl is triggered in the background. So the next time someone visits that same page, the data is available for use.
## Data Usage
Once we've crawled a page and have its contextual data stored, you can use that data to build audiences and push those audiences into the ad server for advertisers to buy on. All without additional charge!
See our [Audiences & Segments](/audiences) page for more information on how you can use your contextual data.
# Audiences & Segments
Source: https://docs.contentignite.com/audiences/index
Build audiences right from within Fusion
Audiences & segments allow you to filter your contextual data along with other publisher filters such as IAB category, to build a targetable pool of users that an advertiser can then buy against.
This is an incredibly powerful feature, allowing you to dice up your publisher in a way that can make it highly attractive to an advertiser, opening up high CPMs and all from simply having our single Publisher Tag on the page!
## Concepts
### Segments
A segment is simply a group of filters that you've defined. This could be a segment for "Volvo Cars", where you have selected filters for a contextual category of "Automotive" and contextual terms of "Volvo v70", "Volvo v60" etc.
A segment can include another segment. How you structure things is completely down to you and your requirements.
You could, for example, build a segment for General Motors and include all Cadillac and Chevrolet related terms. Alternatively, if you could see yourself selling to Cadillac and Chevrolet separately in addition to General Motors, build a separate segment for Cadillac and Chevrolet, and then build a third segment for General Motors that includes both the Cadillac and Chevrolet segments within it. In this example, the outcome of the "General Motors" segment is identical, but both methods use a different structure.
### Audiences
An audience is simply a segment that can be pushed into the ad server to make it available to advertisers.
You will get an overview of an audiences reach, the publishers that are included in it, and the option to enable or disable it at any time.
In the same way as described above, where segments can be structured how you see fit, audiences are the same. You can build your re-usable segments and then as a final step, include them in an audience ready to be enabled. Or you can skip using segments altogether and build in all your fitters directly into an audience. The net result would be the same, but if you see yourself building a lot of similar audiences, then using segments might just save you some time.
## Management
You can create a new audience from the "New Audience" button on the main audience page.
From this page, you can also navigate to segments, and view your list of existing audiences.
When creating a new audience, the title and description fields are the first fields you will see, these are for your own internal reference only, and are also present for segments. The only extra fields you will find in an audience (compared to a segment) are `Key` and `Value`. These fields allow you to control how the audience will be seen inside the ad server.
You will then see a list of available filters. As you select filters the estimated reach figure will update, along with the other filters. This is an interactive way of building an audience and seeing how various filters affect the reach as you get more and more targeted.
When you save an audience, you will be taken to an overview page where you can see that audience's monthly reach, monthly impressions and its impressions over time (this gives you a great insight into how the audience is trending).
You will also see a breakdown by publisher for full transparency on where the filtering falls across your network.
### URL Path Filter
If your site follows a logical nested URL structure like `https://exampleblog.com/category/dogs/best-dog-breeds`, you can segment the URL path to group any pages under `/category/dogs` with the topic of "dogs".
For more information about what you can enter in this field, see our [URL Path Targeting guide](/publishers/tag-targeting#wildcard-matching), the URL path targeting field works in exactly the same way allowing the use of wildcards to match path patterns flexibly and easily.
## Enablement
Enabling an audience is as simple as clicking a button. Once enabled, every time a user visits a page on your publisher's site that matches that audience, the audience will be passed to the ad server as part of our ad request.
New page crawls will be automatically checked for matches against existing audiences, to ensure your audience stays up-to-date.
An Audience becomes a live entity, constantly updated and constantly checked against for page matches before an auction takes place.
# Changelog
Source: https://docs.contentignite.com/change-log
Product updates and announcements
This page will list changes to the platform that happen often. It could be anything from a big new feature to bug fixes and interface tweaks. To view just the key platform announcements, visit our [release page](/releases).
* Platform UI dependency upgrades (MUI v9, improved component stability and performance)
* Charts in report builder! Once you've built a report, you can now visualise the data in a chart using chart controls. You can also export the chart as an image for use in presentations and reports.
* Page impressions and page RPM now available in report builder
* Report builder now shows field compatibility as you make your field selections
* Upgraded Publisher tagging:
* Tag-based filtering added across Insights Hub, Dash, Summaries and Report Builder
* New Tag dimension in Report Builder
* Publisher tag picker auto-deduplicates and suggests existing org tags as you type
* Diagnostics now supports multi-publisher views (including via tags)
* New integrations: PubXAI SSP and PubXAI Analytics Adapter
* CSS fields now fall back to local validation if CSS validation service is unavailable
* Integration settings handling improved for array fields and owner-managed meta fields (bug fix)
* New SSP integrations: AdKernel, CPMStar, Holid, Insticator, OpenWeb and PixFuture
* Prebid Server configuration now handles compatible SSP partners more reliably
* Improved Teads mapping handling for placement-only mappings
* Revenue Analytics connection status now ignores archived Google Analytics integrations
* Client Debugging session times now handle UTC timestamps consistently
* Mixpanel tracking updated to use EU data residency
* Added "Save PDF / Print" button for Invoice downloading
* Added `BufferFieldElement`, a new field type for cleaner buffer input handling
* New integration: Nodals AI RTD
* Integration archival now re-builds affected publisher tags
* New integrations; Converge SSP, Human RTD, InMobi SSP, Missena SSP, Lotame Panorama ID, Magnite (migration), Microsoft (migration)
* Support for custom Prebid key-value prefix
* Support for custom drop alert threshold and ability to turn off per publisher
* Ability to duplicate configs to different publisher
* Grouped rows only export functionality added to DataGrid Tables
* New date led campaign table view added
* New support for slot level targeting via the JS API
* New feature: Refresh Blocking - allowing you to block refreshes based on ad server ad response ID's
* New feature: Refresh Overrides - allowing you to override refresh durations based on ad server ad response ID's
* Support added for key-value macros
* Tag updates:
* Removed deprecated schain module
* Unit refreshes automatically get a refresh=true key-value added
* Slot empty classes now added to the body of the page, to allow for unit dependencies
* New `cipt_disable_tech` flag added to easily disable 3rd party tech
* Notices upgraded to be published at an organisation level for advanced system admins
* Global search updated to include Campaigns
* Pricing rules are now visible to all users in the organisation settings page
* Pricing rules are now visible to all users in the organisation settings page
* Bid throttling options added
* Beta support for Google Anchor and Side-rail units
* New "Header bidding" chart in Live Insights
* New metrics added to experiment reports for ad/unit latency and bid rates
* Key-values are now applied on ad request, not ad unit load
* IAB Curated Audiences are now pushed by default if contextual is enabled at the publisher level
* Ad units now have their min/max width/height set based on creative size selection
* Pixel units now support "Out-of-page" and custom sizes
* Additional URL debug flags added: `cipt_disable_floors=true`, `cipt_grb=true`
* Tag feature added to group publishers with custom entries
* New Organisation level Data Opt Out filter to exclude organisation publisher
data from being included in aggregated data from within Fusion.
* Benchmarking Insights hub updated to adhere to data opt out scope
* New support for Demand Source filter (previously Revenue Source) within
Metric and Live Insight Hubs
* Further optimisations and features to support Fusion's White Label solution,
including new branding options, Fusion logo, in platform documentation
mirroring and more.
* Added support for a hosted AdAgents.json file
* Added ability to copy across config and publisher mapping when duplicating publishers
* Further updates to Revenue Analytics to remove dimension reporting to
improve analytics data accuracy and GA data parity
* Full Fusion mobile optimisations including: 1. Mobile view optimisation and
UX upgrades 2. Migration of all data tables to use upgraded MUI Data Grid 3.
New Mobile "List View" support for all data tables
* Revenue Analytics upgrade to include real-time GA reporting for aggregation
and totalling data points
* New Benchmarking Insights page added to the Insights Hub - surfacing how
your ad tech setup and performance compare to similar publishers and the wider
network.
* New CSS extension for targeting; `:eq(n)`
* SSP Source filtering added and Revenue Insights data table Revenue Source
filtering
* Environment filtering and reporting added to Insights Hubs and Report
Builder
* In-View and Refresh sub-controls are now open for all users
* New reporting fields; Viewable Impressions, Cost, Integration owner, Revenue Source (P\&P orSaaS)
* New target conditional field -- used for advanced targeting
* Re-worked Net revenue calculation -- using impressions for SaaS customers
* New dashboard with greater consistency; UX from Insights Hub, filters
* Alerts have launched to all users! Get alerts via Slack, email or web push
notifications for things such as traffic or revenue drop-offs, tag build
progress, invoicing and tons more!
* New filter switch to toggle off showing third-party lines in Ads.txt full
requirements
* Multi select support for Insights Publisher Filter
* Multi select support for Insights page filters
* Updates to publisher dash UX; tables are now full width, include more
filtering & grouping controls, better consistency and better use of links
where applicable
* New Ad Stack section in the publisher dash, allowing
central updating of ad stacks and the ability to view the configs each is
assigned to
* Experiments list now ordered by live first
* New deep dive
option for Integrations to show specific publisher usage
* Organisation name
now shown in publisher list
* Organisation Mapping added for GA Integrations for improved dynamic domain
matching
- Ability to export charts as an image
* Data pivoting and AI assistant in our data tables!
* Search and export of
integration mapping fields
* Ability to select custom date range for monthly
and quarterly grouping
* New Revenue Insights page added to the Insights Hub - providing in-depth
revenue data across a range of individual views
* New pop-up alert system when editing configs that are running live
experiments
* New optional description field added for experiments
* Launch of "Insights Hub", encapsulating the following reports:
* Ads.txt Insights
* Core Web Vitals
* Demand Mix (New)
* Diagnostics (New)
* Health Score
* Live (New)
* Metrics
* Revenue Analytics (New)
* SSP Insights (New) - Introduced a "system toolbar"
* Moved organisation switcher in, as part of a breadcrumb feature
* Moved account page and log out links in
* New presence widget, showing who's on page
* New "Ask Ai" widget for searching our docs for information
* Link to new Support page, details various resources and how to reach out
* Updated main menu links to include a new "Admin" section, various links moved to system toolbar
* Updated feature announcement modal, will now include all updates since your last login, not just the latest
* Organisation tags have been reworked to be more reliable and more scaleable, now accessible form the organisation list table
* Charts have been unified across Fusion
* Removed old "Publisher hub" links and navigation, as migrated to Insights Hub
* Updated "more" menu in publisher dashboard
* A number of behind the scenes updates to make Fusion more efficient
* Launch of "Policy Centre", manage integration terms in one place
* New ID solutions: UID2 and EUID
* Region filter in tag configs, report builder and experiment; to quickly target continents
* Management UI for publisher level integrations - ID and addressability
signal integration type and management UI within ad stacks - Mapping options
at the organisation, publisher and config level - Floor model selection at the
tag config level - Adjusted revenue (with toggle button) on experiment revenue
charts - Autocomplete element now used for integration mapping tables, to ease
data input - New unit picker UI, highlighting unit types more clearly - Blank
dynamic floors files are now generated to prevent 403 console messages -
Organisation setting page now submits as a single entity (rather than by
section)
* New Revenue Analytics Insights Hub providing in-depth revenue based
analytical data across a range of individual views - New Core Web Vitals
Insights providing analysis of CWV data over periods of time - Updated
Publisher Dashboard with new statistics and Insight page links - Sidebar
navigation offering new sub-level links
- New integration: Mantis- New integration: Ex.Co (Video)- New integration: Project Agora- New integration: Nexxen
* Managed Ads.txt file link and instructions added within Ads.txt Requirements
to allow publishers to direct to a hosted version of the file from their
website domain.
* New integrations added: Epsilon (FKA Conversant), Teads, Media.net and OpenX
* New campaign reporting, providing visual insights, grouped table and raw
data to analyse and track campaign performance and progress
* New Health Check Report (V2) with comprehensive reporting and metrics
gathering
* New 'Load on scroll' behavior for Adhesion
* Option to support guaranteed roadblocks
* New "Auto-activate" setting for experiments, to activate the winner on
completion - New experiment reporting, providing visual insights, raw data and
various actions from one page
* New Exchange Insights feature added to Ads.txt Insights Hub page for more
in-depth exchange analysis - New "Third Party Ads.txt Requirements" available
in publisher settings for including other demand partner inventory to be
tracked in Fusion
* New integrations: The MediaGrid and Opti Digital - New ad unit mapping
ability. Added to: AdYouLike, IndexExchange, Pubmatic, Magnite, Sharethrough,
Sovrn, TripleLift, Xandr
* Introduced new Publisher Hub page for reporting on Ads.Txt Insights
* New integrations: AdHash, NoBid, Seedtag and Sharethrough
* New global search feature accessible from `⌘`+`P`, allowing you to search
across the whole system easily - Table search - search from the foot of most
system tables for quick filtering - More consistent table actions via a
single-action menu - Publisher Integrations: Connect in ad tech such as ad
block recovery or CMPs - System Integrations: Connect analytics providers and
communication tools such as Slack - Drag & drop ad stacks: Build incredibly
powerful and flexible stacks (ad servers, ad demand, fallbacks) including
Prebid and Amazon Publisher Services. Read more here: blog.contentignite.com -
New "Month" reporting dimension, for a handy month-by-month breakdown of stats
* Introduced custom key-value mapping functionality, available through your
account manager
* You can now set the 1x1 pixel unit to be injected at the top or bottom of
the body element
* Live performance report now open to all users
* Introduced new viewport filtering for tag configs and experiments
* New reporting dimension & filter for "Campaign Name" - New reporting metrics
"Campaign CTR" and "Campaign Clicks" - We have changed "Creative size" to a
more true-to-life reporting dimension
* Added new reporting dimension & filter "Channel"
* Introduced "double wildcard" for expanded config URL path matching
* New "All" option for "Rows per page" on tables - Persistent "Rows per page"
selection - Fixed header layout to no longer hide elements
* Implemented new MCM structure, enforcing a direct and unique link between
MCM and platform organisation. This makes MCM manageable from the integrations
section and improves the structure of the supply chain object and our
sellers.json, while also consolidating our contentignite.com ads.txt
requirements - UI tweaks to integration selection - Fixed reporting bug where
selected date ranges shift when saved - Tag configs are now enabled by default
for inactive publisher tags - There is now a handy link to a publishers site
on the publishers dashboard
* IAB 1x1 unit moved to new "Pixel" unit - IAB units now support multi-size -
Adhesion, In-Image and In-Article now support size customisation - Introduced
audience filter to tag configs - Introduced tag config scheduling - New
"Experiments" to pit two or more tag configs against one another - All filters
now show in the tag config lists as icons for quick reference - Tag configs
can now be named to help identify them - New refined design to tag config
fields - Refined design for publisher dashboard - Improved responsive mobile
design - Revenue report has become a report builder, to customise fields and
filters and save for repeated use - Introduced lower level reporting now down
to: config id, device, geo, creative size, yield partner, platform - Added new
health report metrics; "Tag latency" & "CMP not found" - Organisation domain
is a new and required field for better supply chain handling - List searches
can follow the first match with the return key (cmd+p to search, return to
follow)
* Reduced minimum audience character length to 2 - Fixes for custom branding
fields not saving - Fixed issue where SaaS reports were not getting imported
daily - Fixed issue that prevented seller IDs showing as ads.txt requirements
* New platform onboarding guide with walkthrough - New publisher approval
process - New publisher go-live task list UI with more detailed steps -
Performance improvement for publisher stats graph and the performance report
page - New "Incomplete supply chain" metric in health report - Self guided MCM
set up for new publishers - Fix for 'Single-Serve' units where user were told
the target field was required - Revamped dashboard, see page impressions on a
bigger performance graph and see viewability & CTR's at a glance - Better
consistency for statuses; colors and title, across all entities - Better
search matching across all entities - Simplified legal help center, explaining
our use of (or should we say, non-use of) PII - Filter on publisher label in
revenue report - Fix to ensure integration filters are applied to current org
and its children only
* Fixed issue causing some SaaS records to be missing from revenue report -
Added note on setting up SaaS video config inside GAM
* Removal of upfront SaaS vs P\&P choice (read more in our [blog
post](https://blog.contentignite.com/the-launch-of-publisher-cloud-v4-0-flexibility-like-you-wouldnt-believe-eec6ce0a3394))
* Choose your ad server per tag config for super flexible setups - New billing
options to accommodate mixed setups - New integrations section to manage
multiple ad server connections under one organisation - Ability to drop in
your own ad servers ads.txt requirements - Target individual ad servers to
particular child organisations or publishers - Refined user role management
via a new interface - Overhauled docs site with lots more content! (more to
come...) - Ability for white labelled platforms to change the "About our ads"
link on our ad units - Publisher onboarding now correctly skips steps that
don't apply to SaaS customers - Ability to control invoice information (Tax ID
and Country) at any time - Ability to easily set dashboard currency
independent of billing details - Onboarding is now much more streamlined -
SaaS connections now benefit from deeper API integration to select ad units
from a list
* Upgraded revenue report - Summary footer is back after a previous regression
* Change the aggregation function used for the footer summary per column -
Group by any column
* Video v2.0 launched in beta - Auto-generated content - Video uploads and
playlist - New behaviour to "Stick on load" - Ability to mute video by default
* Media library - Revamped revenue report - New video metrics - Ability to pin
columns - Reorder, resize and show/hide columns - Sort and filter by multiple
columns - Table preferences are stored across page views - URL segmentation
moved from publisher settings to audiences - Ability to set your own "Key" for
audiences - New publisher branding and RSS feed fields - Tag build status now
updated without updating page - New "Prefix text" field in certain unit
configs (YMAL removed from publisher settings)
* Changed how fill is calculated in the revenue report; this now matches
Googles calculation of ad responses / ad requests and will no longer exceed
100% when ad refresh is enabled. - Pubmatic stats are now correctly stored
using monetised impressions rather than total impressions, no longer skewing
reporting stats.
* User & Organisation that are archived are now hidden from the UI (bug fix) -
Revenue report will no longer show "-" as unit for some records - Interstitial
units are now full configs (not a toggle under publisher settings) -
Introduced shortcuts for search (⌘+p) and creating new (n) - New table actions
menu for publisher configs - Device icons in publisher configs table -
Onboarding now takes into account child organisations (bug fix) - Improved
consistency when using the word "Impressions", page vs ad now clearly
differentiated - New publisher upload option: Bulk upload & duplicate from
another publisher - Publisher label now correctly used in dashboard stats -
SaaS billing is now handled per ad unit, taking the greatest value from ad
impression vs ad unit impressions for each used ad unit - SaaS reporting now
uses monthly impression totals to give an accurate eCPM and therefore accurate
costings - SaaS reporting now breaks reports down to the ad unit level -
\[Regression] Billing terms removed from billing page, these terms are agreed
with your account manager up front, please reach out if you would like these
resupplied at any point - \[Regression] Channel partner organisations and
referrer users no longer get access to reporting for their target organisation
by default, speak to the organisation directly to get access if needed.
Invoicing summaries continue as normal.
* Upgraded Google sync, this now happens on tag build to ensure that
everything is perfectly in place for the latest tag build - Tag build status
information now shown on hover - MCM id field introduced
- Dark mode made a lot.. Darker...
* New tag build system in place, you will now see the status of this process -
New organisation tag launched
* Introduced "Target Injection" option to inject ads inside and above chosen
target
* Moved all URL based targeting to URL path targeting for consistency and
simplicity - Launched v1 Video unit
* Added ability to duplicate a tag config
* New URL path targeting for tag configs
* New device targeting for tag configs - New 1x1 IAB unit size option
* Big content update to help docs - New Content Recommendation unit - New
dashboard! See insights across your network in one place - Health report
(combines and replaces drop and ads.txt reports) - Yield report has been
merged into revenue report - New publisher page - Guided tour - Onboarding
checklist - Supporting Google MCM - New quick integration option (DFP) -
Ads.txt upgrades to accurately report on requirements
* Introduced segment based audiences - Bulk matching now available in audience
builder - Negative term matching made available - Live reach counter in
audience builder - Live term search - All charts have been replaced with new
design - Fixed "Loading chunk failed" errors
* Rolled out our OpenWrap partner support opening up additional ad demand
* Fixed issue where payments were showing against all "pay parent"
organisations
* Released our Audience Builder in limited availability - Fixed issue with
parent organisation field being uneditable
* Introduced 15 minute browser cache to reflect config changes more quickly
* Removed "High Viewability" publisher toggle; this is now a default feature -
Introduced "Interstitial" publisher toggle - Fixed issue where Google Ad
Manager sync was incorrectly showing as not connected
* Introduced organisation management functionality - Introduced user
management functionality - Introduced "Invoice Parent" toggle - Introduced
auto-invoicing and billing for referrer and channel partner payments -
Introduced billing management for user targeted invoices - Introduced
additional inter-currency payment methods for P\&P organisations and users -
Introduced infinite organisational hierarchy model - Billing status is now
color coded for visual identification, and shows the last updated date
* Introduced two additional IAB sizes: 125x125 (Button), 320x100 (Large Mobile
Banner)
* Invoices and payments are now split out in the billing history table - Added
new logo field for white label to customise favicon - General tweaks to white
labelled assets to better mirror chosen colors
* Introduced our contextual offering in βeta - Additional options in publisher
settings for enabling: - Tag debugging - Contextual (βeta) - High viewability
(βeta) - βeta tag - Publisher field for fixing CSS conflicts
* Launched new Ad Manager integration, allowing for one time authentication
for a more streamlined work flow - On boarding tasks now link to their
relevant sections - Users can now cancel their payment details, and recreate
at will - CSS tweaks can now easily be applied on a per publisher basis, reach
out to your account manager who can apply these tweaks for you - Fixed issue
in Safari where search field and action button would span multiple lines
* Fixed issue where "YMAL" field was uneditable
* Opened up API reporting access, check it out and give us your feedback!
* Introduced branding options for SaaS and white label customer, this
includes: primary color & brand logo, both with light and dark theme options -
Updated legal help centre design; easier to navigate and branded by default
using the new branding options
* Corrected an issue where CPM and RPM columns were showing the wrong way
around - Corrected a decimal place issue with billing estimate inside the SaaS
impressions report
* Upgraded publisher insights graph. We now have the ability to toggle between
various presets - Added ability to archive a publisher from the publisher
settings page - Added ability to close the live chat bubble for when it blocks
an interface element - Added ability for unsupported SaaS payment countries to
skip payment set up
* Fixed bug in the revenue report for P\&P customers where the two impression
columns where the wrong way around - Fixed bug which caused ad unit
impressions to all display the same value for a given day and publisher
* Added support for 25 new currencies for P\&P customers - Added footnotes
wherever currency is used to state the currency code, to clarify the currency
symbol meaning
* Added live chat bubble to help with any integration issues more efficiently
- Official BETA launch. Hello world!
# Ad Stack Examples
Source: https://docs.contentignite.com/getting-started/ad-stack-examples
Your demand sources, ad servers and tech; grouped
Ad stacks may seem overwhelming at first glance, their inherent flexibility leads to a magnitude of configuration options, but we can assure you they are very easy to grasp and use! So let's explore some real-world examples from simple to complex.
## The minimalist
The minimum you need to get up and running with digital ads is an ad server! Ours is available by default, and if you have connected in your own, then that will be available too. You can have a fully working setup with this simple ad stack.
## A sprinkle of client-side demand
Enabling Prebid is as simple as dragging in a Prebid SSP into your stack, if the SSP supports it, you can set it to run server-side via our Fusion Prebid Server. The same goes for Amazon UAM/TAM, just drag it in to enable it!
## The works
The final block in ad stacks is Fallbacks. These serve when nothing else has, and take the form of either simple image creatives (image & link) or advanced script creatives (created and hosted by you). You can create fallbacks from within an ad stack and drag it in to enable it. More than one can be used too, and will be cycled through at random.
## Second-Look Ad Server
It is possible to have a primary ad server in the stack, that passes back to a "second-look" ad server when it fails to fill a request. This is typically used as a hybrid SaaS setup, where your ad server gets first look with all your connections and direct campaigns, and then upon an unfilled impression, passes back to Content Ignite.
Unlike days of the past, there is no need to mess around with passback tags and configuration in your GAM account. The Content Ignite Publisher Tag orchestrates the entire ad request process, so can efficiently trigger the second ad server as needed.
All of that boils down to you simply dragging a second ad server into the ad stack:
### Understanding the flow of events
If you have ad demand partners included in your ad stack, these partners will be called again before sending the ad request to the second ad server.
As you can include a mix of ad-demand relationships, it is important to note that your integrations can remain in the mix even when calling our ad server and vice-versa, if your integration wins, then normal SaaS logic applies for that impression.
Note that both servers need to be set up as applicable to the ad demand you have dragged in. For example, APS and Prebid require certain line-items to be present as a one-time setup task, so if using our Prebid demand and your ad server, this setup will need to be completed, or any bids from those SSP's will always fail at auction.
If your ad server was first-look, and failed to load an ad, the flow may look something like this:
# Ad Units
Source: https://docs.contentignite.com/getting-started/ad-units
Get to know our core ad unit types
## In-Image
This unit is one of our most flexible allowing you to target 1 image per post or multiple images, infinite scroll, and the option to go on or under the image (and even target non-images such as standard containers and video units). A high-performance product that produces exceptional results for both advertisers and publishers.
## Adhesion
Our floating adhesion units sit at the bottom of all your pages, across all devices providing our advertisers with a platform to ensure their ads are viewable, whilst at the same time paying out premium CPM’s. This is a highly engaging performance unit that delivers results.
## In-Article
We understand content is king, so our In-Article unit is seamlessly integrated into our publisher's content to enhance the user experience, not detract from it. Providing a highly engaging format, this unit offers a truly native experience for users.
## Standard IAB
Why not use the power of Native to help monetise your display inventory. We can run our native formats into all standard IAB units and help to either supplement or replace your existing display strategy.
## Video
Our in-stream video unit allows you to monetise your existing video content, or, using our powerful auto-content system, generate video content automatically using your site's articles, unlocking a completely new revenue stream.
## Future
We are always looking to expand our ad portfolio, so rest assured that new developments are always in the pipeline, and when available, will be as simple as a few clicks to roll out!
# CMP Guide
Source: https://docs.contentignite.com/getting-started/cmp-guide
Your guide to Consent Management Platforms
CMPs, or "Consent Management Platforms" are a vital part of a publisher's ad tech setup. CMPs are a component under the publisher's responsibility, and are unfortunately plagued with common pitfalls and easy to miss implementation mistakes.
The result of not getting your CMP setup right? Direct impact on monetisation.
## So what is a CMP?
A CMP's job is to collect consent from your users in regions where consent is legally required for sharing of personal data. This consent is then read by all parties in your ad stack, where consent means that users can be shown "Personalised Advertising".
Personalised advertising refers to ads targeted at specific users based on previous interactions while browsing the web. If someone has been shopping for shoes for example, then showing that user adverts of shoes is more likely to engage that user.
Higher engagement means higher monetisation. This is why consent is so important. Without it, ad serving defaults to "Non-personalised" in order to be compliant with the law, but in this mode, monetisation is often poor.
CMPs first appeared on the scene as a response to the European Union's GDPR law, requiring that users must opt-in to sharing data up front. This meant that every site that serves users in EU countries, would need a way to collect consent.
But how could this be done in a uniform way so that all sites could easily pass on user consent to any third party that needed to read it? Enter "TCF", or the Transparency & Consent Framework, introduced by the IAB (a governing body in the advertising world).
The goal of TCF was to have a single universal framework that all CMPs adhered to, so that any third party would know how to read user consent, regardless of what CMP the publisher chose to use. Luckily this was widely adopted, and is the expected way to collect and read user consent.
All of this behind-the-scenes tech is of little concern to you, the publisher, other then making sure the CMP you pick is TCF-compatible (you'd be hard pressed to find one that isn't).
### The rest of the world
While GDPR triggered the creation of CMPs and the development of TCF, other countries soon began considering their own stance on user data rights.
Countries like Canada and Brazil have their own laws, and states in the US have also brought in their own variations of GDPR.
Suddenly, the straightforward EU landscape, with its single GDPR law, became more complex when looking globally. There are nuances in each region's legal system, so once again, how can global publishers collect consent from individual users, and how can any third party read that consent?
The IAB's answer to this was "GPP", the Global Privacy Platform. Like TCF, the goal of GPP was to establish a single framework that all CMPs could adhere to so that all third parties would know how to read user consent.
However, GPP differs from TCF in that it encompasses the various global implementations of user consent, such as TCF (for Europe), TCF (for Canada), and California's privacy implementation.
**Key Takeaway**
Ensure the CMP you pick is clearly listed as "TCF" or "GPP" compatible
## Whose responsibility is the CMP?
Responsibility for choosing and implementing a CMP is with you, the publisher. It is a legal requirement in several regions to collect consent correctly (with possible fines for non-compliance).
Because CMPs adhere to one of the frameworks mentioned above, as far as we are concerned, it doesn't matter which CMP provider you choose, as long as it is implemented correctly (we'll come to this shortly).
It is important to us that you, the publisher, take full control over your users' data privacy. This is why we do not offer a pre-configured CMP for you to use "as-is".
However, we can help with getting your chosen CMP to page, as we [support a number of third party CMPs](/integrations/ad-tech#cmps) in our Fusion platform. This allows you to skip the implementation headaches, but this will always remain your choice and under your control.
## Implementation
So CMPs ask users for consent, and respond to a third party that asks about user consent. Easy, right?
Unfortunately while all the complexities are taken care of by the CMP itself, there are still several ways to implement a CMP incorrectly. In these cases, everything will appear to be working, which makes these issues so tricky to debug.
The number one issue with CMP implementation is ensuring third parties wait for user consent.
### Waiting for user consent
The first time a user visits your site, they will be shown your CMP of choice (if in a region that requires it). The CMP will ask the user to make a choice, typically "Accept all" of the data use cases (vendors and purposes), or "Reject all".
While the user is making their choice, it is really important that any third parties, such as advertising partners, know the user is actively choosing their response, so that they can wait for the user to finish.
In the world of ads, if we immediately loaded ads, we would see that the user has not consented to sharing data yet, so we would load non-personalised ads. But the user may have been about to select "Accept all", so this would have been a waste of an ad load. However, if we know that the user was picking their response, and waited for that to happen, then we could load personalised ads as soon as "Accept all" was chosen.
It goes even further than this. There are lots of situations that may occur that third parties need to be aware of. For example, if there is no CMP at all, there would be no use waiting around for user consent, when we could just load ads right away (non-personalised of course).
Now, down at a technical level (bear with us), there are two important things loading on the page in order for ads to load: your CMP of choice and your Content Ignite Publisher Tag. Our tag wants to read from the CMP to check we have user consent. But what if our tag loads before your CMP? Well, we would load, see there is no CMP, and then continue to load ads with personalisation **disabled**. But this might have missed that fact that user consent was present, the CMP just hadn't loaded yet!
This is where a third important script comes into the mix: The CMP "Stub"
### Stub
A CMP "Stub" is a small piece for Javascript code, that tells third parties that a CMP will be present.
It loads before any script that needs to read from a CMP, and before the CMP itself.
This is much more important than it may first seem. By knowing that a CMP is going to be present, if the CMP loads after your Publisher Tag, the Publisher Tag will still wait for user consent to be detected, because it **knows** it is coming.
Without a Stub, the following is possible:
```mermaid theme={null}
flowchart TD
start([User loads page on publisher site])
q1{Does the CMP load before the Publisher Tag?}
tick([Publisher Tag detects or waits for consent, loads personalised ads if applicable])
cross([CMP not found, ads default to non-personalised])
style tick fill:#F66F5E
style cross fill:#F66F5E
start -->q1
q1 -- Yes --> tick
q1 -- No --> cross
```
With a Stub, the error routes are prevented:
```mermaid theme={null}
flowchart TD
start([User loads page on publisher site])
s1([Stub fires])
s2([CMP and Publisher Tag load in any order])
s3([Publisher Tag fires knowing a CMP is present])
tick([Publisher Tag detects or waits for consent, loads personalised ads if applicable])
style tick fill:#F66F5E
start --> s1
s1 --> s2
s2 --> s3
s3 --> tick
```
**Key Takeaway**
By not correctly implementing a CMP Stub, you introduce a "race condition", where sometimes the CMP will load before your Publisher Tag, and sometimes after. This leads to intermittent monetisation issues. So correctly implementing a Stub is vital.
#### Implementation
This warrants a little background about the web (we'll try not to get too technical). Both the CMP and your Publisher Tag are linked to from the head of your page via a "script" tag. It might be obvious to think that the order in which you add these is the order in which they will load, but unfortunately, this is not the case. The browser will load each resource, but the speed at which they return determines which loads first. If the CMP is first up in the head of your page, but takes 2 seconds to load, but your Publisher Tag takes 1 second, then the Publisher Tag will load first.
This is important because you can never guarantee the firing order. It may swap around between page loads or vary depending on connection speed, such as mobile browsing on a 3G network, or even be affected by browser cache or plugins!
These differences in loading times and firing order are referred to as "race conditions", where both scripts are racing to load, with different outcomes possible each time the race is run.
With that being said, it is crucial to correctly implement the Stub to completely eliminate the chance of a race condition. The Stub needs to be placed directly in the head of your site, before your CMP and Publisher Tags are linked. It is vital to never put the Stub in an external file that is then linked to. If you were to link to an external file, you'd be introducing a new race condition where the the CMP or your Publisher Tag could load before the Stub, negating the Stub altogether. By including it directly in the head, there is no "fetching" of the file, so it is always loaded immediately.
```html title='Example of what "direct in the head of your page" looks like' theme={null}
```
#### Vendor List
One key area of CMP configuration is the vendor list. This is a list of all the third parties that you want the user to consent to. It is important that Content Ignite and all the ad partners we integrate with, are listed. Without this, we will read our consent as missing, and default to non-personalised ads.
Most CMPs will enable all vendors by default, but it is always worth checking, especially if you plan to whittledown this list.
#### Example Stubs
It is worth noting that some CMP providers include a stub! Look out for a bit of text that reads `cmpStatus:"stub"`, and if you find it in the code you are deploying **directly in the head of your page (not in an external file)**, then you are all sorted!
For those who need a stub, its handy to know that they are simple, generic bits of code, and are not tied to the specific CMP you chose, all that matters is that they are implemented correctly (direct in the head of your site, before your CMP and Publisher Tag), and that you match against your CMPs framework:
**TCF Stub**
```html theme={null}
```
Source:
[https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/](https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#is-there-a-sample-cmp-stub-api-script)
**GPP Stub**
```html theme={null}
```
Source:
[https://github.com/InteractiveAdvertisingBureau/Global-Privacy-Platform/](https://github.com/InteractiveAdvertisingBureau/Global-Privacy-Platform/blob/main/Core/CMP%20API%20Specification.md#examples)
### Caching plugins
There are certain plugins and services out there aimed at improving your site's speed and efficiency. One of such services is Cloudflare's "Rocketloader". One of the many things that Rocketloader (and other services) can do is defer Javascript.
What this means is it will block all JS from loading until the page content itself has loaded, and then it will allow the Javascript to load.
While this might improve the responsiveness of a page, it can mess with the firing order of your CMP and Publisher Tag. In addition, as latency is such an important metric for reviewing ad performance, delaying ads will almost certainly impact your monetisation.
So it is important to make sure your core ad tech scripts (CMP and Publisher Tag) are excluded from any caching plugins. For instructions on this, please review the documentation from your caching service.
### Let Fusion handle implementation
Getting all of this right can be a bit finicky, but is certainly doable. But even with the perfect set up, things might get accidentally changed. For example, your tech department migrates to a new site template and misses that fact that the scripts are now firing in a different order.
This is where we can help. By [using Fusion to deploy your CMP](/integrations/ad-tech#cmps), we can ensure it makes it to page before your Publisher Tag, and that CMP errors can be avoided. Fusion deployment negates the need for a Stub and simplifies implementation.
We have a number of CMPs integrated into Fusion, but if you don't see yours in there, reach out as we can likely add it for you.
## Tracking CMP stats
With so many pitfalls to avoid, it's important to be able to verify your setup and track CMP metrics over time.
This is where our [Diagnostics Insights Hub](/reporting/insights/diagnostics) comes in. Here we will tell our outright if your Stub has been found and what your error rate is. We'll also track the consent rates that we detect, ensuring you always have actionable insights at your fingertips.
Fusion is also geared up to scan and detect issues such as CMP consent rates and revenue, where it will alert you to sudden drop-offs, helping catch and accidental changes that may impact your ad setup.
## FAQ's
#### Question: So how do I pass consent from the CMP on to you, my ad tech partner?
Answer: You don't! With the Stub and CMP in place, we can communicate directly with the CMP, with no input from you. All just works as it should.
#### Question: Instead of a Stub, can't I just delay your Publisher Tag from loading?
Answer: This would be a very inefficient approach and would also still not guarantee that the CMP fires first. The Stub ensures we wait only as long as necessary; delaying us longer will impact monetisation.
#### Question: Can I use Google's CMP?
Answer: From our experience, Google's CMP is designed for direct use with Google Publisher Tag only, and doesn't work well as an independent CMP. Because Google is in control of both the CMP and the ad server, it can ensure that the CMP is loaded first and that consent is waited for, so does not require a Stub. Our publishers have found that when using Google's CMP by itself and implementing a Stub, the CMP fails to function correctly.
#### Question: My CMP provider, has provided a stub file to link to..
Answer: Shame on them! External stub files are just not valid. However, you can copy the file contents and put it direct in the head of your page, between script tags. E.g: ``
# General FAQ's
Source: https://docs.contentignite.com/getting-started/faqs
Let's cover off some common FAQ's for publishers working with Content Ignite for the first time.
Any burning questions that we haven't covered off here? We'd love to hear them! Please reach out via [hello@contentignite.com](mailto:hello@contentignite.com)
You can contact the support team for help with any issues, questions, or feature requests.
You can create a ticket in our [support centre](https://resource.contentignite.com/support).
The dashboard log-in can be found here: [https://admin.contentignite.com/](https://admin.contentignite.com/).
We optimise based on yield. This is the balancing of CPM's and fill to ensure you get the most revenue possible by maximising the value of your inventory. This will lead to blank ads now and then, but more revenue!
The bottom line is, more fill **does not equal** more revenue.
So unlike using the standard Google Publisher Tag, where `` elements need to be placed throughout your site, and units need defining in the head of your site, we operate on a true one tag solution. Place our tag in the head of your page once, and forget about it.
But how do we target ads? We use standard CSS selectors to target ads, we can use Div ID's, classes or even target every 5th paragraph in an article for example.
All of this is set up inside our Fusion platform, so you don't need to keep making development changes to your site for every change in ad targeting or behavior.
Once you have set up a publisher in Fusion, you will find your Publisher Tag shown to you.
Our tag is a JavaScript script tag, and looks something like this:
```html theme={null}
```
This tag is unique for each publisher and is designed to run site-wide by being placed directly in the head of your site along with a CMP (where applicable), and that's all you need!
This is a text file included on your website to list authorised companies selling your ad inventory, aimed at increasing transparency and reducing fraud. If it is incomplete or incorrect, it can have huge ramifications for the monetisation of your website. Check out [this Article](https://www.contentignite.com/article/mastering-ads-txt-file-optimisation-with-content-ignites-insight-tool) for a easy overview on how you can easily improve the health of yours.
You can submit requests for campaigns by filling out a [form here](https://www.notion.so/Campaigns-d65647eb001b4f9b969f8b2a6276b42c?pvs=21). We also **require** you to fill out the google sheets insertion sheet attached to the notion submission form. Please populate all fields of the sheet and if not there is no required targeting or info populate the field with **N/A**.
Feel free to reach out to you AM on help on how to get direct campaigns set up.
We accept jpg, png, gif files as raw creatives. We also accept GAM compatible HTML5 Zip files and certain 3rd party code compatible with GAM
Content Ignite can set Protections for you. Just send a block list to [adops@contentignite.com](mailto:adops@contentignite.com)This [Article](https://www.contentignite.com/article/optimising-website-ad-performance-using-content-ignites-experiment-technology) will show you how to set an Experiment. For the first one or two, we recommend dropping us a note with the details so we can check the set up for you.
If Content Ignite is becoming your sole ad-tech provider and you are moving over from Google, the setup process is pretty seamless. First and foremost, there is Google's GPT tag that gets replaced with your Content Ignite Publisher Tag:
```html title="Before" theme={null}
```
```html title="After" theme={null}
```
You will then have some sort of header script or file where you previously had to define your Google ad units, this can be removed or commented out:
```html title="Before" theme={null}
```
```html title="After" theme={null}
```
Finally, you will have ad containers throughout your site with unique ID's such as `div-gpt-ad-1611935295857-0`, you can keep these containers in place if you still want ads there, removing or commenting out the inner script tags:
```html title="Before" theme={null}
```
```html title="After" theme={null}
```
Then simply enter the container ID's into the Fusion platform as unit targets to place ads in your existing containers! Nice and simple, and even means you can easily switch back at any time (although we are confident you won't want to).
The Fusion platform can be fully set up to use your connections (your GAM account, your SSP's), ours, or a mix of both. When using your own connections, this is classed as SaaS (Software As A Service).
For SaaS you are charged a CPM fee for using our technology (compared with the revenue share of P\&P -- Plug and Play; using our connections).
To use a SaaS setup, you can connect your GAM account into Fusion via our [integrations section](/integrations), this is a simple approval flow that grants us the access we need. This gives you the ability to see centralised reporting inside Fusion and have child units set up automatically for you.
The same goes for ad demand, if you already have contracts in place with SSP's, you can set those up in Fusion too.
If you have containers on page already, you can easily add them into Fusion, no changes to your site are required in this regard. Our team can even help migrate targeting for you so you are up and running quickly.
Targeting inside your Ad Server (if using our SaaS feature) can also remain the same, no need for new line items if you have demand set up already. Fusion can use your existing ad units to create the required child units, or create new ones automatically for you, the choice is yours.
Our aim is not to change the way you are set up to work, but to be flexible and agnostic as a platform. Read more about [Fusion "Pro" vs Fusion "Mapped"](/getting-started/pro-vs-mapped) if you want to preserve your entire ad unit setup within GAM.
This is actually up to you! For those who don't want to be overly involved in ad operations, the simplest route to monetisation is to use our GAM account where we pay you your revenue share each month, but you can also use your own GAM account (SaaS) or even use both:
A hybrid setup can have different ad servers targeted to different geos, audiences etc, or served via a "second-look", where if your ad server fails to return an ad, ours can jump in and attempt to fill the opportunity. View our [example ad stacks](/getting-started/ad-stack-examples) to find out more.
Through our drag-and-drop ad stacks, you can drag multiple Google Ad Manager ad servers in. The order matters here as only one ad server gets first-look, then another can get second-look and so on.
There is no setup inside of GAM needed to make this work. We get all the relevant signals for when an ad request has not been filled, we will then pass the opportunity on to the next ad server if one is set up, this "second-look" is orchestrated by our tag so doesn't suffer the inherent inefficiencies of legacy passback tags.
If using our Ad Server in the mix, all the P\&P requirements apply; billing information so we can pay you your earnings, MCM connection in place, site approved etc. Then your ad server will need to be set up with all SaaS requirements in place. This is why we class this as a "hybrid" setup. View our [example ad stacks](/getting-started/ad-stack-examples) to find out more.
Creative fallbacks give you the opportunity to fill a space that has otherwise failed to serve an ad. "Blanks" or missed ad opportunities are common and by design as we always optimise for yield, meaning more revenue for you the publisher.
This opens the door for you to place ads directing users to your merch shop for example. You can upload image assets and a link, or get more involved with script fallbacks.
All fallbacks impressions are tracked, and image fallbacks are click-tracked and all available in your revenue reporting as you'd expect.
You can even configure multiple fallback and have them cycle (and even weight them accordingly).
Fallbacks do not replace booked campaigns, where you can target creative, control serving and compete with programmatic, they are purely a final chance to fill a space when all other options have been exhausted. View our [example ad stacks](/getting-started/ad-stack-examples) to find out more.
# 2. Creating your first publisher
Source: https://docs.contentignite.com/getting-started/first-publisher
Set up your first publisher in just a few clicks
For each of your publishers (websites), you will need to create a publisher in our system. This will be the place you set up your ad units, and get your ads.txt requirements and the all-important Publisher Tag!
Simply navigate to the publisher's section and click the "New Publisher" button. Enter the publisher domain (for [https://www.example.com/](https://www.example.com/) the domain is: example.com).
You can enter an optional label to help you identify the publisher, for example, if you have a separate forum and blog, you might want to label them accordingly.
Hit the "Create publisher" button and you will be taken to your newly created publisher!
We recommend you put the Publisher Tag live on your site as soon as possible. The tag won't go live until you turn it on, but by putting it live now, you minimise any delay in the approval process.
# 3. Creating your first ad unit
Source: https://docs.contentignite.com/getting-started/first-tag-config
A few simple settings to get you a fully functioning ad unit
The settings that describe the ad unit type (in-image, IAB etc), its behaviour and targeting are called "tag configs".
[Get to know our ad units here](/getting-started/ad-units) if you haven't done so already.
Tag configs can be combined in highly flexible ways to achieve the outcome you are looking for. For example, if you want in-image on mobile to target just the header image, but on tablet and desktop to target all article images, you can simply create two tag configs for in-image, one with mobile device targeting and the relevant image targeting, and the other for desktop and tablet.
Things can get even more powerful still as we come to the first big decision; our ad server or yours?
## Ad stack choice
Ad stacks are powerful groupings of all the various pieces that make up the ad tech ecosystem. This could be as simple as a single ad server, or as complicated as header bidding, Amazon TAM, ad block recovery tech and custom fallback creatives all bundled together.
We will get you started with the minimum requirement: a single ad server. To learn more about ad stacks, check out the page here: [Publisher Tag Ad Stacks](/publishers/tag-ad-stacks).
### Ad Server
You have two options for the ad server (the bit that hosts the final ad auction and is responsible for providing the ads to the ad units):
#### 1. Use ours (Plug-and-play)
By using our ad server, you can get up and running quickly and with minimal ad operations knowledge. Once approved, our team will manage your publisher's ad demand for you. The earnings will be paid out to you on industry-leading Net30 terms and publisher rev-share.
Simply select the "Default Ad Stack (P\&P)" and you are done. Auto-approval will follow shortly after.
#### 2. Your Google Ad Manager (SaaS)
Have your own GAM account and demand? You can connect your GAM account into Fusion and benefit from all our tech including our high-impact units, centralised reporting, contextual targeting and dynamic floors.
Connect your GAM now over in the "Integrations" section or by clicking the "+" icon in the left-hand sidebar, it's quick and easy. [Learn more about integrations here](/integrations).
Impressions served by this setup are charged on a CPM basis.
#### 3. Hybrid
There is a sneaky 3rd option, and that is to use both our ad server and yours! You can use our demand and yours in a first-look second-look set up, where, for example, if your ad server does not fill a request, the opportunity will be passed on to our ad server automatically. Additionally, if you want to control some geos and use us to serve others, that's easy too! Just connect to your ad server and choose the best fit for each tag config.
## Tag Config
Once you have made your ad server choice and connected in your GAM account if going for option 2, you can continue and set up your first tag config.
Within your publisher, select the "Create Config" button and choose the ad unit you'd like (Adhesion is a great one to get started with).
You will be taken to the tag config page, with various fields on display. The fields vary per ad unit type, but should all make sense and default to sensible choices for you.
Our P\&P ad stack is selected by default, but for SaaS users, you can change this by clicking the ad stack and dragging in your own integration. [Learn more about the GAM integration here](/integrations/ad-servers).
Once you are happy with your settings, click "Save config".
# 4. Going Live
Source: https://docs.contentignite.com/getting-started/going-live
Your list of pre-flight checks
Now that your first publisher and tag config have been created, you can prepare for go-live.
The onboarding checklist on your publisher page is your guide here.
1. You will need to deploy the Publisher Tag to your site ([tag deployment](/publishers/tag-deployment))
2. Set up payment (depending on your ad server choices)
3. Await approval
4. Deploy any ads.txt requirements
5. Ensure you have a CMP in place for applicable regions, and that Content Ignite is included as a vendor option.
Once all those pieces are in place and all you see are lovely green ticks, you are ready to go!
Make sure the tag config is enabled by clicking the switch next to it so it is green, and then finally enable the tag by clicking the switch in the "Publisher Tag status" box. This will turn on your tag for the first time!
Tag enablement can take a few minutes, and if using our Ad Server, demand can take 15 minutes or so to start coming through, so give it half an hour, enjoy a cup of tea and revel in the stress-free setup of your first publisher.
### Notes on CMP's
Consent Management Platforms (CMP's) are a requirement when serving in the EAA and UK, and are even becoming required in some form by other countries and US states. A CMP's job is to collect user consent and make it readable by ad tech providers like us.
The Fusion platform tracks CMP issues in the [Diagnostics insights](/reporting/insights/diagnostics) report, as unfortunately, there are many mistakes that can be made during the implementation of a CMP on site, namely script execution order and missing out of the CMP "Stub". The net result of incorrect CMP implementation is a direct loss in revenue.
The CMP Stub is a piece of JavaScript code that should be placed inside `` tags, and **not** included as a hosted file (``.
4. **Check for External Scripts and iFrames**: CMPs might load their functionality from external sources. You can examine the network requests (in the Network tab of Developer Tools) for any CMP-related files being fetched when the page loads.
5. **Observe Cookies and Local Storage**: CMPs manage consent preferences and might store these settings in cookies or local storage. Using the Application tab in Developer Tools, check for entries related to consent.
6. **JavaScript Objects**: Some CMPs create global JavaScript objects that can be accessed via the console in Developer Tools. Typing common CMP object names like `__cmp`, `__tcfapi`, or the names of known CMP services and checking for a non-null response can indicate the presence of a CMP.
These steps will help you identify whether a CMP is being used on a website and understand how it's implemented.
Content Ignite Vendors List:
* Content Ignite
* Adform A/S
* Index Exchange, Inc.
* Sovrn, Inc.
* Onetag limited
* OpenX
* PubMatic, Inc
* TripleLift, Inc.
* Google Advertising Products
* Improve Digital
* Smaato, Inc.
* Yahoo EMEA Limited
* Magnite, Inc.
* Equativ
* ADYOULIKE SA
* LoopMe Limited
* Unruly Group LLC
* Criteo
* The MediaGrid Inc.
* Onfocus (adagio)
* Sharethrough, Inc
* ADman Interactive SLU
* Monet Engine Inc
* PulsePoint, Inc.
* Emodo, Inc.
* Verve Group Europe GmbH
* Xandr, Inc.
* Microsoft Advertising
* LinkedIn Ireland Unlimited Company
* Revcontent
* GumGum, Inc.
* Ogury Ltd
* Seedtag Advertising S.L
* media.net
* The UK Trade Desk Ltd
* Amazon Ad Server
* Amazon Advertising
* Yieldmo, Inc.
* Beachfront Media LLC
* Mintegral International Limited
* Sonobi, Inc
* Intercept Interactive Inc. dba Undertone
* Kargo Global Inc.
* Smile Wanted Group
## Technical Setup
Yes. When a new publisher transitions over to Content Ignite we replace their GPT Tags with the Content Ignite GPT & One tag. When the publisher has no direct sales campaigns this is very straightforward - but when direct sales are involved we have to treat the setup slightly differently:
* Option (1) In most instances Content Ignite will be responsible for the publisher's ad operations and trafficking and deliver those campaigns via our own GAM instance.
* Option (2) If the publisher wishes to remain in control we typically work via a "Teams" function in GAM. These campaigns would still flow via our GAM instance, but the publisher has access to traffic those campaigns.
Ads.txt helps protect your inventory from fraud by making it clear who is authorised to sell your ad space. This improves trust with buyers, supports better demand quality, and can positively impact revenue.
Read our complete guide to find out more: [Mastering Ads.txt](https://www.contentignite.com/article/mastering-ads-txt-file-optimisation-with-content-ignites-insight-tool)
Ads.txt ensures buyers can verify that they are purchasing legitimate inventory from approved sellers. Without it, you may see reduced demand, lower bids, or increased risk of invalid traffic.
Read our complete guide to find out more: [Mastering Ads.txt](https://www.contentignite.com/article/mastering-ads-txt-file-optimisation-with-content-ignites-insight-tool)
Your ads.txt files are crawled every 5 hours so changes will not be immediate, but will appear swiftly. If you do not see the changes after 24hours, please contact [adops@contentignite.com](mailto:adops@contentignite.com)
Follow the property ID mapping process in Fusion admin panel
Mapping the GA property ID[¶](https://docs.contentignite.com/integrations/analytics/#mapping-the-ga-property-id)After verifying the integration and establishing the connection, you’ll need to map the Property ID to the specific Google Analytics properties you want Fusion to track. Here’s how to do it:
1. **Log In**: Access your Google Analytics account under the account you'd like to connect.
2. **Locate the Property ID**:
* Open the **Admin** settings.
* Under **Property**, select **Property Details**.
* Find and copy your Property ID, typically a 9-digit numeric code.
3. **Map the Property ID**:
* Navigate to Google Analytics (GA4) in the [Integrations](https://admin.contentignite.com/integration) section in Fusion, click the **more** icon (with the 3 dots) and select the option to **Manage** the integration.
* Under **Property ID Mapping**, select the relevant publisher and paste the copied Property ID into the Publisher ID column.
4. **Save and Activate**: Click **Save** to activate the integration and start fetching analytics data straight away.
[Mapping the GA property ID](https://docs.contentignite.com/integrations/analytics/#mapping-the-ga-property-id)
[Integrations and Analytics](https://docs.contentignite.com/integrations/analytics/)
Required for new publishers, with special handling for direct sales
The most common reason for this is (ironically) because an Ad Blocker is in place. If this is not the case, please get in touch with the details of the bowser you’re using and a screen grab of what you’re seeing so we can dig into it.
This is what checks your site for outages, is vital for contextual crawling and various other protective features. Our bot identifies itself with the following user agent: FusionBot/1.0 (compatible; Mozilla/5.0; +[https://api.tagdeliver.com](https://api.tagdeliver.com))
The IAB Tech Lab's ads.txt specification explicitly states that the file must be hosted on the root domain, not on any subdomain.Ads.txt must exist from the root domain, so always enter the domain direct in the browser, e.g.
rootdomain [.com/ads.txt](http://wareable.com/ads.txt) , running it on [www](http://www). is invalid
This is not uncommon with programmatic ads as creatives can take any shape or form. We suggest testing your site with basic and predictable ad server creative using the following query string parameters: `?cipt_test_ads=true&cipt_no_hb_ads=true`
If you are seeing nothing on the page affected or any issues such as partners not bidding then this is nothing to worry about, this error is commonly seen in Prebid.js setups where multiple SSPs are firing at the same time, causing occasional race conditions or timing overlaps. These are typically non-critical and do not affect ad delivery, making them a normal occurrence in complex header bidding environments.
## Campaign Management
Campaign reports are stored within the reporting feature on the Fusion platform ([Login](https://admin.contentignite.com) using your email and password, unless using custom Content Ignite wrapper), you can view latest data after 7:30am when the reports are updated with the last 24 hours of data.
[https://admin.contentignite.com/report/campaign](https://admin.contentignite.com/report/campaign)
Access campaign reports through the Fusion platform reporting feature after 7:30am daily
[https://admin.contentignite.com/report/campaign](https://admin.contentignite.com/report/campaign)
Standard sizes: 728x90, 970x250, 300x600, 320x50, 300x250
Yes. Custom sizes can be added to Ad Unit Configs by typing the size (900x400 for example) in to the Unit Size field within the config settings and clicking the prompt to add
Yes, for SaaS clients or Teams access (ID remains fixed)
Use Config Label under Advanced Options > Scheduling & Naming
Yes, we can support ad serving of 3rd party JS and iFrame tags but we require these to meet Google Ad Manager and IAB specifications. Ideally any 3rd party tags should be recognisable by Google Ad Manager for correct tracking macro insertion such as click macros.
Yes, we can support ad serving HTML5 Creative Bundles providing they are correctly setup to Google Ad Manager specs - [https://support.google.com/admanager/answer/7046799?sjid=8068901518823437570-EU](https://support.google.com/admanager/answer/7046799?sjid=8068901518823437570-EU)
## Ad Unit Management
Yes, especially if you’re a Plug & Play client. From within the ad unit config setting select the 'Advanced Options' dropdown. You will see a group of options named 'Scheduling & Naming' and a field called 'Config Label' where you can add you desired config name.
Yes, if you are a SaaS client or have ‘Teams’ access. Any Child ad units that are published from Fusion to GAM can be renamed it is just the ad unit ID which will not be editable.
Yes. Custom sizes can be added to Ad Unit Configs by typing the size (900x400 for example) in to the Unit Size field within the config settings and clicking the prompt to add.
## Experiments & Testing
Experiments can be fully setup all within the Fusion platform.
Read our [Experiment Guide](https://www.contentignite.com/article/optimising-website-ad-performance-using-content-ignites-experiment-technology) for a full walkthrough.
## Protections, Quality & Blocks
Via Protections in Google Ad Manager and for each SSP on each website - block by either sending an email or adding the block/protection into the SSP manually.
We can review quality of ads in the Ad Review Center in Google Ad Manager. If you would like to use a 3rd-party to do this like Geoedge and TheMediaTrust, you can reach out to those companies individually and contract directly - then speak to Content Ignite about adding them as an integration in Fusion.
Our bots user agent is below and should be whitelisted. In addition to this, it is highly important that bot targeted files (robot.txt, ads.txt, sitemap.xml etc) are all excluded from your WAF, as blocking access to these can harm SEO, ad revenue and more. `FusionBot/1.0 (compatible;
Mozilla/5.0; +[https://api.tagdeliver.com](https://api.tagdeliver.com/))`
We don't store PI. IP address and UA are present in our raw server logs but don't go into long term storage. The only contact we have is the Hash, which uses IP and US in a secured way. Things like device ids, cookies etc are not used or stored by Content Ignite.
Please see our [Privacy Policy](https://www.contentignite.com/privacy-policy) (section 4) for more information
.
You can also refer to our [PI Data Flow](https://docs.google.com/presentation/d/1sIRaz8HQhySSDDfi6DhCmejQya5xKPt5Zatv_WtXCJ8/edit?usp=sharing) diagram for a visual representation.
.
If you spot the bad ad on the page and want to keep it there to inspect where the ad was served from follow the below instructions:
To enable the debug feature on page without activating the debugging mode enabled in the Fusion publisher settings you **MUST** follow step 1.
If you already have debugging enabled in Fusion publisher setting skip to step 2. ***Important to note* you will not be able to capture the bid data on the page before the debug script is enabled, so we advise having this enabled in publisher settings rather than adding to the URL and waiting for the bad ad to be produced.**\*
1. Add this string to the end of the page url `?cipt_debug=true&cipt_disable_refresh=true` ***important to note*** when adding the query string parameters to the url make sure the url doesn't already include a `?` such as `example.com?page_id=1234` as in this case you would need to include our debug parameters starting with `&` not `?` so `&cipt_debug=true&cipt_disable_refresh=true`\*
2. Open page inspect and select console view
3. Amongst the script you will see a list of completed auctions with the assigned unit and the partner who won the auction ***Important to note*** If you don't see the SSP win for a unit, that means either GAM (Adx, Open Bidding, Campaigns) or Amazon has won the auction, as neither shares details about the creative that get served.\*
4. Please export all this data in the console view and send it over to [adops@contentignite.com](mailto:adops@contentignite.com)
in a plain text file. \*If this does not return any information about the prebid auction SSP that usually means it was won by one of the previously mentioned ad servers which do not share creative details, to confirm this you can filter by `auction` (it will show as *APS or adx as the winning bidder)*
Some ads can be removed from the browser which is called **heavy ad intervention (HAI) by Google Chrome.** This can be affected by **overall browser resource usage**, not just the individual ad unit.
Here's a breakdown:
### What triggers a "heavy ad intervention"?
Chrome defines a *heavy ad* as one that uses more than:
* **4 MB** of network data,
* **15 seconds** of CPU usage in any 30-second window,
* or **60 seconds** of total CPU usage overall.
If an ad exceeds **any one** of those thresholds, Chrome may block or unload it.
***
### But what if the **browser is already under strain**?
If a page is already consuming significant CPU or memory due to:
* lots of JavaScript activity,
* multiple videos,
* animations,
* complex rendering tasks,
* or just too many tabs open,
...then even **marginal ad units** may cross the thresholds more easily.
In other words:
* A "normally fine" ad unit might tip over the limit **faster** if the system is already under pressure.
* The thresholds are **absolute**, but how quickly an ad hits them can vary depending on the environment.
***
If you are seeing heavy ad intervention or seeing ad units not loading, it may not always be because the ad itself is misbehaving — the **page context and user environment matter too**.
Read more here [https://docs.contentignite.com/reporting/insights/diagnostics/#heavy-ad-intervention-publisher-issue](https://docs.contentignite.com/reporting/insights/diagnostics/#heavy-ad-intervention-publisher-issue)
## Floors
1. Created new custom key-values (ci-df) in GAM
1. Create the `ci-df` key
2. Copy and paste the following values as values with with Value Type `Predefined` selected
* Values
```txt expandable theme={null}
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.10
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.20
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.30
0.31
0.32
0.33
0.34
0.35
0.36
0.37
0.38
0.39
0.40
0.41
0.42
0.43
0.44
0.45
0.46
0.47
0.48
0.49
0.50
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.60
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.70
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.80
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.90
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
1.00
1.01
1.02
1.03
1.04
1.05
1.06
1.07
1.08
1.09
1.10
1.11
1.12
1.13
1.14
1.15
1.16
1.17
1.18
1.19
1.20
1.21
1.22
1.23
1.24
1.25
1.26
1.27
1.28
1.29
1.30
1.31
1.32
1.33
1.34
1.35
1.36
1.37
1.38
1.39
1.40
1.41
1.42
1.43
1.44
1.45
1.46
1.47
1.48
1.49
1.50
1.51
1.52
1.53
1.54
1.55
1.56
1.57
1.58
1.59
1.60
1.61
1.62
1.63
1.64
1.65
1.66
1.67
1.68
1.69
1.70
1.71
1.72
1.73
1.74
1.75
1.76
1.77
1.78
1.79
1.80
1.81
1.82
1.83
1.84
1.85
1.86
1.87
1.88
1.89
1.90
1.91
1.92
1.93
1.94
1.95
1.96
1.97
1.98
1.99
2.00
```
2. Edit your existing AdX line item
1. Set start time to now, set end time to unlimited
2. Set to Run of Network
3. Set Inventory Type to `Display` (set more up for `Interstitial` etc)
4. Set Custom Targeting to;
1. `ci-df` is any of `0.01` , `0.02` etc for the 200 values
3. Add each Unified Pricing Rule to GAM
1. name = `ci-df-0.01`
2. custom targeting = `ci-df` is any of `0.01`
3. check `Set floor prices`
4. Branded = `0.01`
1. **Created new custom key-values (ci-df) in GAM**
1. Create the `ci-df` key
2. Copy and paste the following values as values with with Value Type `Predefined` selected
* Values
```txt expandable theme={null}
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.10
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.20
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.30
0.31
0.32
0.33
0.34
0.35
0.36
0.37
0.38
0.39
0.40
0.41
0.42
0.43
0.44
0.45
0.46
0.47
0.48
0.49
0.50
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.60
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.70
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.80
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.90
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
1.00
1.01
1.02
1.03
1.04
1.05
1.06
1.07
1.08
1.09
1.10
1.11
1.12
1.13
1.14
1.15
1.16
1.17
1.18
1.19
1.20
1.21
1.22
1.23
1.24
1.25
1.26
1.27
1.28
1.29
1.30
1.31
1.32
1.33
1.34
1.35
1.36
1.37
1.38
1.39
1.40
1.41
1.42
1.43
1.44
1.45
1.46
1.47
1.48
1.49
1.50
1.51
1.52
1.53
1.54
1.55
1.56
1.57
1.58
1.59
1.60
1.61
1.62
1.63
1.64
1.65
1.66
1.67
1.68
1.69
1.70
1.71
1.72
1.73
1.74
1.75
1.76
1.77
1.78
1.79
1.80
1.81
1.82
1.83
1.84
1.85
1.86
1.87
1.88
1.89
1.90
1.91
1.92
1.93
1.94
1.95
1.96
1.97
1.98
1.99
2.00
```
2. **Edit your existing AdX line item**
1. Set start time to now, set end time to unlimited
2. Set to Run of Network
3. Set Inventory Type to `Display` (set more up for `Interstitial` etc)
4. Set Custom Targeting to;
1. `ci-df` is any of `0.01` , `0.02` etc for the 200 values \
\\
Now we want to set up pricing rules in the following increments in the table
| Range | Increments | Rules |
| :------------ | :--------- | :----- |
| £0.01 – £0.09 | £0.01 | 9 |
| £0.10 – £0.50 | £0.05 | 9 |
| £0.51 – £1.00 | £0.05 | 10 |
| £1.00 – £2.00 | £0.10 | 10 |
| **Subtotal** | | **38** |
3. **Add Unified Pricing Rules to GAM for £0.01 to £0.09 (9 UPRs in total)**
1. name = `ci-df-0.01`
2. custom targeting = `ci-df` is any of `0.01`
3. check `Set floor prices`
4. Branded = `0.01`
5. REPEAT this for £0.02, £0.03 etc up to £0.09
4. **Add Unified Pricing Rules to GAM for £0.10 to £0.50 (9 UPRs) in £0.05 increments**
1. name = `ci-df-0.10_0.14`
2. custom targeting = `ci-df` is any of `0.10, 0.11, 0.12, 0.13, 0.14`
3. check `Set floor prices`
4. Branded = `0.10 `
5. Any floors that get set by our technology at 0.10, 0.11, 0.12, 0.13, 0.14 will be set at a floor price of 0.10 in GAM
6. REPEAT this up to £0.50
5. **Add Unified Pricing Rules to GAM for £0.51 to £1.00 (10 UPRs) in £0.05 increments**
1. name = `ci-df-0.51_0.55`
2. custom targeting = `ci-df` is any of `0.51, 0.52, 0.53, 0.54, 0.55`
3. check `Set floor prices`
4. Branded = `0.51 `
5. Any floors that get set by our technology at 0.51 0.52, 0.53, 0.54, 0.55 will be set at a floor price of 0.05 in GAM
6. REPEAT this up to £1.00
6. **Add Unified Pricing Rules to GAM for £1.01 to £2.00 (10 UPRs) in £0.10 increments**
1. name = `ci-df-1.01_1.10`
2. custom targeting = `ci-df` is any of `1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10`
3. check `Set floor prices`
4. Branded = `1.01 `
5. Any floors that get set by our technology at 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10 will be set at a floor price of 1.01 in GAM
6. REPEAT this up to £2.00
## Looker Studio
Unfortunately, Content Ignite cannot provide access to our Google Ad Manager (GAM) instance to link to your Looker Studio as our GAM also hosts information from other publishers. We do provide access to all of our reporting via our API suite.
[https://docs.contentignite.com/reporting/api](https://docs.contentignite.com/reporting/api)
# Introduction
Source: https://docs.contentignite.com/index
Welcome to the world of Content Ignite!
## Getting help
We are here to help you throughout your experience, from initial sign-up through years of happy collaboration.
Our docs should provide everything you need to get started and to support you as you become a pro user of our platform. But if you ever do get stuck, help is only ever one click away.
Raise a support ticket and our friendly team will get back to you
## Get to know our products and concepts
Get familiar with our platforms concepts by reading up on them here, or by following the onboarding walkthrough once signed into our platform.
Different approaches, but the same platform and fundamental features &
behaviours
If you choose to go the "SaaS" route, you have control over the ad unit
structure inside your GAM
Get to know our ad units across web and app; everything from standard IAB,
to our bespoke high-impact units
Built from the ground up to be developer friendly; from simple reporting
access, to a full native integration into your UI
## Your questions answered
If you are new to Content Ignite, you probably have a lot of questions about how our tech works, what moving over to Content Ignite looks like, can it really be as simple as a single tag on page?? (Spoiler: yes!).
Jump on over to our Intro to Content Ignite Tech for common getting started
FAQ's.
## Onboarding, live and earning
Once signed up and signed in, you will see an onboarding banner on your dashboard. This will guide you through every step needed to get live and earning! Here is an overview of the top level steps required:
Create your account and verify your email address
Get your publisher verified and approved
Configs provide everything needed to serve an ad
Worth through your in platform onboarding steps to get live
# Ad Demand Integrations
Source: https://docs.contentignite.com/integrations/ad-demand
Plug in demand beyond your ad server
Ad Demand partners inside Fusion come under whats known as "Header Bidding". A technology that allows a secondary ad auction to take place before the final ad server auction.
## Prebid.js
Prebid.js is a open source client-side header bidding solution, and is widely used across the digital advertising landscape. It allows for a client-side auction to take place between configured SSPs. The winning bid is then sent to the ad server to compete with other server side demand sources.
Header bidding adds auction pressure and can compliment your ad stack set up, but it does come with the overheads of additional client resource demands. Header bidding is known to impact CWV (learn more here: [Publisher Tag Core Web Vitals](/publishers/tag-core-web-vitals)), so it is important you don't overload header bidding with too many partners, and that the set up is optimised for your site.
Making use of Prebid inside Fusion is a breeze. You can connect in your own SSP relationships if you have them, or you can make use of the relationships that Content Ignite have worked to put in place.
Adding a partner into your stack is as simple as dragging it in during ad stack set up. No more headaches over the complexities of prebid setup and how it communicates with your ad server, no more weeks of development resource to get everything in place, just drag and drop!
Fusion will take care of everything, from integration on page to reporting. Header bidding as it should be.
## Prebid Server
An extension of Prebid.js is Prebid Server, where the auction is moved from the client's browser to servers hosted by Content Ignite. This minimises one of the downsides of header bidding; client side resource usage. Instead of weighing down the client browser, the heavy lifting is handled by our servers instead.
The great thing is, no additional set up is needed by you! Simply include any partners marked as "Prebid Server" into you ad stack as normal, we'll take care of the rest.
Another complex set up, reduced to a single drag and drop action, bliss!
## OpenWrap
OpenWrap is a wrapper implementation of PreBid.js, provided by Pubmatic. As it uses Prebid.js at its core, it allows several additional demand partners to enter a client-side auction and can complement your ad stack setup as Prebid does. The built-in P\&P integration is available to all publishers, but must be configured by the Content Ignite Ad Ops team to function.
If you have your own Pubmatic account with OpenWrap configured, you can connect it in easily.
Note; you can not run Prebid along with OpenWrap as they are alternative versions of the same thing. Content Ignite recommends direct usage of Prebid, as you get far more granular control inside Fusion (just think about the experiments you could run against different demand partners!).
## Amazon Publisher Services (TAM/UAM)
APS is another header bidding solution that runs a server-side auction via a client-side script before passing any winning bids to the ad server. The benefit here is direct access to Amazon's demand. As with Prebid Server, the client impact is minimal as the auction is hosted on Amazon servers.
Control over the individual SSPs is not possible outside of the APS platform, so it is more comparable to a wrapper like OpenWrap where you drag it into your ad stack as a single entity. The default P\&P integration provided by Content Ignite is available to all and has a number of key SSPs connected in, but will require approval for each publisher on a case-by-case basis.
If you have your own APS account, you can connect it easily and control the SSP partners via your APS dashboard.
### APS Reporting (SaaS)
Unfortunately, Amazon does not have a reporting API, and states that one "is not on the roadmap". This is frustrating as reporting APIs allow for easy and seamless integration. Instead, they offer "S3 exports" which requires you to configure a report that then gets hosted as a file on Amazon's servers, this can be accessed by us through the use of a report ID, key and secret.
One limitation here is that Amazon expires tokens every 90 days, with no way to extend them or re-generate them as a client. This means going into Amazon's platform every 90 days, copying the key and secret and putting them into the Fusion platform. Not exactly slick, but that's all we have to work with!
**Setting up access:**
1. Log in to the APS Portal at the URL provided by your account manager.
2. Navigate to Admin then S3 Credentials
3. Click Add Public Key.
4. Paste the entire contents of the .pub file found here: [https://cdn.tagdeliver.com/assets/aps\_reporting\_key.pub](https://cdn.tagdeliver.com/assets/aps_reporting_key.pub).
5. Click Submit.
**Setting up the report:**
Follow these steps to set up APS reporting if connecting your own APS account into Fusion:
1. Create a new report in your APS dashboard here: [https://ams.amazon.com/webpublisher/analytics/custom\_reports/new](https://ams.amazon.com/webpublisher/analytics/custom_reports/new)
2. Select a date range of "Last 7 days"
3. Set a schedule of "Daily" with delivery to "Export to S3" and a file format of "CSV"
4. Select the following dimensions: `Date`, `Browser Family`, `Country`, `Device Type`, `Site Name`, `Slot Name`, `Slot Size`, `Bidder`
5. Select the following metrics: `Impressions`, `Earnings`
6. Click "Save"
7. Enter the name "API Report" (or anything of your choosing)
8. Back in your report list view, hover over the "View details" link on the report you just created
9. Copy the report ID & version ID into Fusion; found under "S3 Location" e.g:
Any change you make to the report will change the versionId. Ensure if you
make any changes to the report, you update the versionId in Fusion, otherwise
reporting will stop pulling in.
## Google Ad Manager Setup (SaaS)
With any header bidding provider, winning bids need to be passed to the ad server to compete in the final auction. The complexities of this process are handled for you by Fusion, but does require that your ad server is set up to receive these bids.
If you are using the Content Ignite P\&P Ad Server, nothing more is required from you. However, if you are using your own Ad Server, then read on.
### Orders, Line Items & Creatives
APS will connect to your GAM account and auto-populate it with all the require line-items it needs, however the same is not true of Prebid.
Prebid requires you to manually set up the required orders, line items and creatives. This can be streamlined with the "Line item manager" tool provided by the Prebid project. This tool is not made by Content Ignite, so we can not be responsible for it use, more information can be found here: [https://docs.prebid.org/tools/line-item-manager.html](https://docs.prebid.org/tools/line-item-manager.html).
One important part of the Prebid line item set up, is pricing granularity. This is how a bid at a certain price point gets rounded so that it is handled appropriately inside the ad server (a limitation of how GAM and Prebid work together). Pricing granularity can be set via the ad stack to whatever your preference is.
### Header Bidding Trafficking (HBT) -- GAM360, Beta
The point previously made about price-granularity, and its requirement due to the limited way in which Prebid and GAM interact is a problem that Google is working on via a new feature called HBT.
This feature does away with the need to set up orders, line items and creatives as Google directly collects and handles the winning prebid bid.
However, this feature is in Beta currently, and is only available to GAM360 users. If you do have a GAM360 account, details of how you can enable this feature can be found here: [https://support.google.com/admanager/answer/12273163?hl=en](https://support.google.com/admanager/answer/12273163?hl=en)
Once enabled inside your GAM account, no other set up is needed. Fusion will automatically work with Prebid and Google to pass in bids as needed!
# Integrating Ad Servers
Source: https://docs.contentignite.com/integrations/ad-servers
The all important ad server, the minimum needed for a complete ad stack
The role of an ad server is host the final ad auction, which ultimately decides which ad creative will be served to page. Ad servers allow the connection in of multiple demand partners, as well as the ability to traffic direct campaigns.
By default, all accounts get access to the Content Ignite P\&P Google Ad Manager account. This comes preloaded with a number of great performing demand partners and is optimally set up to deliver the highest yields for our partners. Additionally, we have a team of Ad Operation experts that are always monitoring and optimising our set up, and our GCPP status grants us access to certain restricted features and functionality along with direct access to the Google team to ensure we get the best out of GAM.
## Google Ad Manager (GAM)
By connecting to your own GAM account, you can choose to use our tech for its high-impact ad formats and our easy-to-use management and reporting platform while remaining in complete control of demand.
**Requested access**
Google Ad Manager currently only has a single level of access that a platform can request from a user, and that is complete access to an account.
Unfortunately, this makes it seem that we are accessing more than we require, but there are currently no other options. What we actually do with our access is explained below
You have two connection types to choose from when connecting to GAM:
1. **Reporting & Management (recommended)** -- This option allows us to create all the ad units needed for our ads to serve, shortcutting a chunk of manual work by your team. Each new ad unit you create in our platform can then be created in your GAM as needed. We will also handle the complex MCM flow and site approval process, all requirements of Google to allow the serving of ads; you can therefore be confident that once everything is ticked off in our onboarding UI, that you are 100% set up to successfully serve ads. We will also pull in your reporting data each morning, allowing you to see everything in one place inside our platform blended with our own reporting data.
2. **Limited** -- Would you rather keep our access to the bare minimum? No problem. We will not pull any reports or attempt to automate any part of your account set up other than syncing the required ad units. You will continue to see basic summaries of ad impressions per ad unit for billing but will still benefit from the time savings of ad unit set-up.
### What exactly do we do inside your GAM account?
As part of our core "Limited" integration, we create ad units. That's it. Our tag requires a parent ad unit (often the domain name of the publisher) and child ad units of a certain set-up. For example, we need a child unit for each config such as `ci-cid-1234` where `1234` is the config id. These must be present with correct naming to work.
As simple as this sounds, we do all this intelligently and efficiently. Our integration works tirelessly behind the scenes to ensure that upon every change you make, the required GAM units are present and correct so your Publisher Tag can serve ads without issue.
What we do not do is touch anything to do with ad serving, you can attach your own placements as needed and target demand in any way you see fit to ensure your partnership with Content Ignite does not affect the processes you already have in place as an organisation.
Opt for our full integration, and benefit from even more automation:
1. **MCM automation (GAM360 only)** -- You and your customers will be able to trigger Googles Multiple Customer Management (MCM) flow. This is a required link between you and your customer for non-owned sites. It tells Google that the publisher has granted you permission to monetize their site. This involves creating a company in your GAM and sending out an invite to your publisher. The publisher then needs to accept the invite.
Our full integration allows a user to send the invite to themselves and handles the set up in your GAM automatically, setting the required MCM id at the ad stack level on completion and submitting the seller\_id in order to complete the supply chain object (part of the ad industries bid transparency specification and required by many partners).
That's a lot of steps that you'd have to remember to avoid disruption to ad serving!
2. **Site approval** -- Once MCM is complete (if applicable), the publishers domain needs to be submitted and approved by Google. MCM acceptance is detected automatically and site submission is handled immediately, no input needed! Your publisher will be informed of the status of this process through out, including any issues that arise so you can work through it with them
### Targeting demand
It is critical that you target demand in some way, to allow ads to show. This can be done by targeting line items to the parent ad unit, or by assigning the units to placements and targeting those. There are many ways to target demand that ultimately comes down to preference and the way you have structured your GAM. The method does not matter (one of the many benefits of Content Ignite SaaS), so long as it is in place.
### SaaS without GAM Integration
For those with trust issues (we get it, especially given Google's open access roles), you can opt for the fully manual route. Where the set-up of ad units is left to you and your Ad Ops team.
#### Unit hierarchy
Ad unit set up can take two forms:
1. A single unit - This is simple to set up, but limits your reporting
2. A child unit for each tag config - By far the best set up, but without the API integration, it could be time consuming to implement
Our tag will always take the given parent ad unit you provide, and attempt to fetch from the child unit named after the tag config that target matched against it. For example, if you have an in-image unit set up via config 678, we will attempt to call, for example: `/1234/example.com/ci-cid-678`
If that child unit is not found in your GAM account, Google will assume serving from the next parent up: `/1234/example.com/`. This means you can get away with a simple set up, but you do forfeit reporting down to the tag config level (which might be fine if you are only running one unit with us).
#### Limitations
Be warned that as we roll out new features, GAM setup requirements may change and you will need to make changes to accommodate this. Additionally, we can not provide support to these types of setups.
By going down the manual route, you will lose out on:
1. Being able to enter ads.txt requirements and having our system inform publishers of missing lines as well as seeing a network-wide health report on ads.txt completeness
2. Having units sync automatically as new tag configs are added (ensuring ads always have what they need to serve to the page while efficiently only creating units that we know will get used)
3. Having unit requirements update automatically as new features and units are rolled out
4. Auto-synchronisation of audience keys
5. The full support of our expert team to help if any issues do arise
6. Speedy single platform rollout of new publishers
7. MCM handling
8. Site approval handling
9. AI Dynamic Floors
### GAM Set-up
We don't require much in the way of set-up in your GAM account, other than the parent ad unit, you are left to target demand in any way you see fit!
One requirement to consider is native ads inside our adhesion and in-image units:
#### Native Templates
To prevent large native ads from rendering inside your adhesion or in-image unit, you need to limit the sizing via native templates inside your GAM. These are targeted to just Content Ignite placements, so they won't affect your wider network.
The steps are as follows:
1. Inside GAM, head to Delivery > Native
2. Click “New native ad” and select “Single ad"
3. Select “Guided design editor"
4. Select ad size “728x90” and click continue
5. Click continue again
6. Use the inventory section to target just the Content Ignite in-image inventory (in-image and adhesion placements if used)
7. For device category, select Desktop and Tablet
8. Name the template at the top of the page (e.g. Content Ignite Native In-Image - Desktop)
9. Hit “Save and activate"
10. Repeat steps once more, but this time select “320x50” for the size and “Smartphone" and "Feature phone" for the device category
#### Video
Our video instream unit is built for pre-, mid- and post-roll ads only and does not support display "bumper" ads. Ensure "Inventory format” is set to "In-stream video and audio” only inside your line-items.
#### Line Items (Prebid)
If you are using prebid demand, you will need to set up various price priority line items to allow prebid bids to compete and potentially serve to page. Prebid offers a tool that simplifies this process as the setup would be very time-consuming to do manually: [https://docs.prebid.org/tools/line-item-manager.html](https://docs.prebid.org/tools/line-item-manager.html).
What will this tool do we hear you ask? It will create a single order which will act to serve all incoming Prebid bids via key-value targeting. Under this order will be a number of price "bucket" line items, then within each line item will be a number of creatives that serve a small script whose job it is to tell Prebid that it won and that it can serve the creative to page.
It may all sound a little complicated (and it is), but the Content Ignite wrapper takes care of the technical implementation and the Prebid tool helps you set up the order, line items and creatives inside your GAM as a one-time set it and forget it task.
Our recommended setup is to use the "dense" option, which creates 424 line items with 5 creatives under each (not something you want to do manually). The config file we used with the tool to set up our own GAM can be found here for your reference: [https://cdn.tagdeliver.com/assets/prebid-line-item-tool.yml](https://cdn.tagdeliver.com/assets/prebid-line-item-tool.yml).
## Publisher Provided Signals
Content Ignite will automatically push IAB-aligned contextual categories into GAM when contextual is enabled for your publishers. This makes actionable, privacy-focused data available at your fingertips!
## MCM - Linked Account
Googles Multiple Customer Management (MCM) is a required link between a GAM360 integration and an organisation for non-owned sites. It tells Google that the publisher has granted the integration permission to monetize their site.
Don't worry if you do not have an existing GAM account to link to, the invite that gets sent out will allow you to create a new one or pick an existing one. This is a quick process to set up, and does not require any knowledge of GAM, in fact, once you have accepted the invite and set up your account, you needn't ever use it again.
In the Content Ignite platform each organisation can link to a single MCM agreement, where each MCM agreement can link only to a single organisation.
You can share an MCM connection through organisation hierarchy, child organisations will have the ability to select the parents MCM at the ad stack level, giving you the flexibility to structure your publishers as needed.
MCM also ties in tightly with the Supply Chain Object (SCO), an industry technology aimed at increasing transparency in the bid request. More and more buyers will require this to be in place to bid, so it is highly important to have in place to protect from revenue loss.
### How do we decide when and where to apply MCM?
MCM is a requirement of GAM360 accounts, so if you are using our ad demand, or connect in a GAM360 account for SaaS usage, you will need to have MCM in place.
However, MCM only applies to non-owned sites. Under publisher settings you can mark a publisher as "Owned and Operated" (O\&O) by a particular organisation. This gives us the ability to deduce the correct MCM requirements.
For example, if you use Content Ignite demand, your site will not be marked as O\&O by Content Ignite, so we know to apply MCM. If you were a SaaS user with organisation "X" connecting in their own GAM360 account, MCM would apply by default, but if O\&O is also set to "X" then MCM can be bypassed as it does not apply.
If there is MCM connected to the current organisation, and the parent organisation, you will be given the option to choose which applies via the integrations "Organisation Mapping".
The current MCM connected to the logged in organisation can be viewed from the "Integrations" section. Selecting "Manage" allows users to send out a new invite to connect in a new MCM. Users who have owner access to an integration can change an organisations MCM link to any non-assigned MCM agreement via the "Organisation Mapping" section, where all tags will be updated accordingly.
# Ad Tech Integrations
Source: https://docs.contentignite.com/integrations/ad-tech
Beyond demand; think ID's, think ad block recovery
Ad technology integrations are typically publisher level connections, weather it be connecting in your CMP, or utilising an ad block recovery platform, these complimentary technology offerings can boost the features of your ad tech set up.
## Sub Types
### CMP's
Consent Management Platforms (CMP's) are a requirement when serving in the EAA and UK, and are even becoming required in some form by other countries and US states. A CMP's job is to collect user consent, and make it readable by ad tech providers like us.
The Fusion platform tracks CMP issues in the health report, as unfortunately, there are many mistakes that can be made during the implementation of a CMP on site, namely script execution order and missing out of the CMP "Stub". The net result of incorrect CMP implementation is a direct loss in revenue.
A CMP is a third party piece of tech that must make it to page, and Content Ignite always recommends you implement this directly in the head of your site wherever possible, however, integrating a CMP through the Fusion platform guarantees a correct set up and peace of mind.
Privacy is at the forefront of everything we do at Content Ignite, and it is our belief that you the publisher should own control of privacy, so we do not provide a "default" CMP set up. We can however advise on various third party CMP's based on our extensive experience and knowledge in this field, simple reach out to your account manager who will be happy to assist you!
### ID/Signal Providers
We offer various integrations with ID/Signal providers to help identify users/audiences unlocking better monetisation.
Our implementation of ID’s is designed to be as easy as possible. Most providers require a user email address or phone number to function, so this must be [passed via our tags JS API](/publishers/js-api). By using this method, you only need to implement the passing of PI once, from there you can activate or deactivate these ID integrations inside Fusion and we will take care of passing the required data as needed.
It is important to note, as a privacy-first company, there are protections in place our side to ensure consent is given via your on-page CMP, before we pass any PI on to the ID provider. In addition, we take care of deploying the ID providers script to page as and when needed.
ID solutions are unique in a number of ways, first in that there are two parts to them, one at the publisher level (the data collection and ID exchange script), and one at the ad stack level (which passes the ID into the bid stream). Both are separately configurable so you the publisher remain in control (you may already have one part in place already), but both need to be on page in one form or another.
Secondly, an ID provider that handles PI will require you to accept terms over in [Fusions Policy Centre](/integrations/policy-centre). This is to protect you and your users by communicating any legal requirements (such a privacy policy amends) and by preventing unauthorised activation of an ID provider.
The main steps involved in activating an ID provider are:
1. **Accepting of terms** -- Some ID providers handle/require Personal Information (PI) such as email addresses, in these cases you need to agree to the terms of the 3rd party over in [Fusion's Policy Centre](/integrations/policy-centre).
2. **Include the publisher level integration** -- Every ID solution requires a script on page that exchanges user information for the all important "ID". This ID is what is then passed into the bid stream. Fusion can handle this step for you if you have not deployed these scripts already, simply [include the ID integration in your publisher stack](/publishers/settings#integrations-publisher-stack)!
3. **Include the ad stack integration** -- This is the important bridge between the collection and generation of the ID, and the ID actually making it into the bid stream where it can hopefully provide incremental uplift.
4. **Pass user information** -- Some ID providers require PI such as email address, this should be passed via your [publisher tags JS API](/publishers/js-api).
We highly recommend you [run an experiment](/publishers/experiments) when you activate IDs for the first time, it is notoriously difficult to measure incremental uplift from ID's, but Fusion makes it a breeze!
### Others
There are other ad stack integration sub types such as ad block recovery, all of which follow a similar setup and connection process, follow on for how to connect these to a publisher.
## Connection to publishers
Once you've connected an ad tech integration into Fusion, you'll want to make use of it at the publisher level.
You can do this via your publisher settings page, under the "Integrations" section by simply clicking "Connect Integration" and picking the integration you just added to Fusion!
# Analytics Integrations
Source: https://docs.contentignite.com/integrations/analytics
Empower Fusion with data from your analytics platform
Website analytics data provides valuable insights into your site's performance and audience behaviour. By connecting a Google Analytics account (with more integrations to come), Fusion leverages this data to deliver blended analytical reporting and actionable insights.
Our [Revenue Analytics Insights Hub](/reporting/insights/revenue-analytics) allows publishers to gain a comprehensive view of earnings performance through a series of graphical and statistical views that cross-reference revenue with key analytic metrics. This helps publishers identify trends, uncover traffic sources or audience segments driving the most revenue, and refine content strategies to target high-performing areas. The actionable insights enable data-driven decisions to fine-tune revenue strategies, optimise performance, and align user experience improvements with financial goals.
## Connecting in Google Analytics (GA)
Follow [these steps](/integrations#connection) to connect your Google Analytics account and begin integrating your data into Fusion.
## Mapping the GA property ID
Once you've verified the integration and connected your account, the next step is to map the Property ID to the Google Analytics properties you want Fusion to track. Here's how to do it:
1. **Log In**: Head to your Google Analytics account using the profile you want to connect.
2. **Locate the Property ID(s)**:
* Open the **Admin** settings.
* Under **Property**, click on **Property Details**.
* Find and copy your Property ID, usually a 9-digit numeric code.
3. **Manage the GA Integration**:
* In Fusion, go to the Google Analytics (GA4) section under [Integrations](https://admin.contentignite.com/integration). Click the three-dot **more** icon and select the option to **Manage** the integration.
Fusion gives you two ways to map Property IDs - **Organisation Mapping** and **Publisher Mapping** - depending on how you would like the data to be linked and reported.
### Organisation Mapping
This is the recommended method. It lets you map multiple GA properties to one organisation, and Fusion will automatically sync the data to the right publishers within that organisation.
Benefits include:
* Add multiple GA property ID's for each publisher GA connection - Fusion takes care of the dynamic syncing to the correct publishers under your organisation.
* It uses exact domain matching, so Fusion will only report on data for the domains that matter (no staging or subdomain noise).
* It's all managed in one place.
Setting it up:
1. Under **Organisation Property ID Mapping**, pick the organisation, then paste your Property ID(s) into the Property ID column.
2. If entering multiple properties, separate them with commas.
3. Click **Save** to activate and start fetching analytics data straight away.
### Publisher Mapping
This method links a Property ID to a single publisher. Use this if you want all the GA data under that property - including staging sites and subdomains - to go to that publisher.
Setting it up:
1. Under **Publisher Property ID Mapping**, choose the publisher and enter the Property ID into the Property ID column.
2. Click **Save** to activate and start fetching analytics data straight away.
Once it's all set up, Fusion will begin syncing your GA data, giving you valuable insights to help optimise your performance and revenue.
# Communication Integrations
Source: https://docs.contentignite.com/integrations/comms
Stay informed via the communication platforms you already use
Each day thousands of events are triggered in our platform, anything from acknowledging the re-build of a Publisher Tag, to urgent health alerts for things like revenue drop-off.
Integrations allow you connect in a messaging system such as Slack, to receive these events into a central group.
You can of course choose the types of events you want to be notified about, and where those messages end up.
## Event Groups
After you go through the connection process for the platform of your choice (choosing where notifications should go), you'll be able to pick which event groups you wish to subscribe to, these are as follows:
| Event Group | Default? | Description |
| ------------------- | -------- | ----------------------------------------------------------------------------------------------------------- |
| Tag & SDK Updates | ❌ | Any changes that trigger a re-build; publisher status change, config change, audience enablement etc |
| Onboarding | ✅ | Any onboarding step; MCM, site approval, publisher appeal, suspensions, new publisher, new organisation etc |
| Health Alerts | ✅ | Revenue drop off, traffic drop off |
| Billing | ✅ | Invoice Generated, paid, in arrears, new profile set up or removed |
| Experiment Activity | ✅ | Experiment end, winner auto activated |
| Ads.txt Updates | ✅ | New requirements, now up-to-date |
| User Access | ✅ | Includes adding new users, existing users added to new organisations and user suspension |
| Integrations | ✅ | Expiry warnings, new integrations added, removed |
| Policy | ✅ | Terms have been accepted |
| System | ✅ | System notices, such as reporting outages or industry alerts |
# Fallback Creatives
Source: https://docs.contentignite.com/integrations/fallbacks
When all demand sources have been exhausted, choose how you want to handle blanks
Content Ignite tech will always push for maximum advertising yield, meaning the most revenue for the publisher. This means you will not see 100% fill and as a result, you will see the occasional blank ad.
Blank ads are not an issue, and by design help improve revenue. We also find that ad ops teams and site owners see a greater number of blank ads, as behaviour detection see's frequent site visits with minimal ad interaction as an undesirable user group to serve ads to.
That being said, you might want to capitalise on these blank slots and fill them with house ads, sending users to your merch shop or a newsletter sign up for example. This is where fallback creatives come in!
## Fallbacks vs ad served campaigns
For granular control of serving frequency, client bookings or prioritisation over programmatic ads, you should traffic campaigns via the ad server. For simple use cases where you'd like to serve something when no ad would otherwise be shown, fallbacks are perfect.
## Fallback Types
There are two core types, a simple "Image" creative, and the more custom "Script" creative.
### Image Creatives
Image creatives are just as you'd expect. Select the image fallback option and upload your image asset (you can also upload a copy at twice the size for high resolution screens). You'll need to provide a title for reference and a click through URL.
Its as simple as that! Click tracking will automatically be applied, so you can report on it via your standard Fusion revenue report.
### Script Creatives
Script creatives allow a JS script file to be served to page. The contents of which is controlled and hosted by you. This could make additional calls to dynamically load assets for example. Content Ignite can not assist with the creation of script creatives, this will be the responsibility of the publishers development team.
Set up of a script creative is as simple as providing a title and the URL to the remote JS file. You can also specify the size of creative that your script will load if applicable, this will ensure your script is not loaded in unit of mismatched size.
Please note, we can not track clicks for script creatives, so will only report on the number of times it was served to page.
## Usage and Weighting
Usage of fallbacks is done via ad stacks (learn more here: [Publisher Tag Ad Stacks](/publishers/tag-ad-stacks)). Simply drag your fallback into the ad stack as needed.
You can even drag in multiple fallbacks, where a random one will be chosen upon each empty ad response. To adjust how often each creative gets served comparative to each other, you can add an optional "weighting". This number weights creatives relative to each other, where if one creative is set to "1" and another to "2", the second creative will serve twice as much as the first (equally "15" and "30" would have the same outcome).
# Integrations
Source: https://docs.contentignite.com/integrations/index
Integrations unlock various features and monetisation options throughout the Fusion platform.
Connect in your own Ad Server to use our technology on a SaaS basis, or connect in your own Prebid demand partners. You can even connect in CMPs, ad block recovery partners or analytics platforms. However you choose to use Fusion, you can unlock a world of opportunity with integrations.
## Control
There are numerous integrations marked as "Built-In", these are default (P\&P) integrations provided by Content Ignite, and help you get up and running quickly and easily. If you do want to go down the SaaS route, and would prefer not to use any of our Content Ignite connections, you don't have to!
Integrations can only be deleted or re-authorised when logged in under the organisation that created them but will be available down your organisation's hierarchy for use by all (unless filtered).
Organisations down the hierarchy can manage filtering of an integration for their children.
## Connection
Connecting in a new integration is simple. Select the platform you want to connect to and click "Continue". Some platforms will present you with a form to enter your account details, while others will take you to their platform where you will be asked to confirm the connection. After doing so you will be taken back to our platform where if applicable, you will be presented with a list of accounts to select which get connected in.
From here you can [manage your integration](/integrations/settings), or simply [start using it inside your tag configs](/publishers/tag-configs) or other areas of Fusion!
# Policy Centre
Source: https://docs.contentignite.com/integrations/policy-centre
Control and transparency where it matters most
Our Policy Centre is part of our pillar of transparency and control. As a publisher, you should know exactly what is done with Personal Information and only involve third parties when you have explicitly agreed to it.
In the policy centre you will see any system terms or integration terms when personal information is involved (think ID solutions).
Any integration that shows up in here will require explicit approval from someone in your organisation before it can go live on a publisher site. Even if you drag an ID integration into your ad stack for example, it will not go live until terms have been accepted.
## The role of Content Ignite
On the topic of ID solutions, you can think of Content Ignite as the "pipes" between you and the third party ID company. You, the publisher, pass user information (e.g. email address) to your Content Ignite tag via the [JS API](/publishers/js-api), and we make sure it is passed to all the third parties you have approved and configured inside Fusion.
This makes onboarding ID solutions a breeze, as you don't need to figure out the nuances of each individual company; pass it to Content Ignite once, and we make sure it makes it to the ID companies just as they need it.
It is highly important to note that this passing of information is all done "client-side". This means no PI is ever passed to Content Ignite servers where it could be stored, logged or mishandled in any way. In this scenario Content Ignite is acting as a data processor.
The Policy Centre exists so you know exactly who has permission to be active on your site, and what that companies terms are, including how they handle the information being passed to them.
It is important to us, especially as experts inside the EEA where laws such as GDPR exist, that publishers are in full control, that they know what is legally expected of them (some ID solutions require amendments to your privacy policy for example!), and that at no point do you have any nasty surprises when it comes to your users privacy!
## Accepting of terms
Accepting terms does not mean going live with that integration, it is simply a preliminary step. You can accept all terms (submitting them to your legal department if need be), and then go on to activate them as and when you are ready.
Terms typically take the form of a block of text from the third party, or a link to the third parties website. These resources should state any legal requirements of you, such as amendments to your privacy policy, so read them carefully.
Once you are happy, click "Accept terms" and that's all there is to it.
### Adding and Removing an integration
Once an integrations terms are accepted (if they have them), you are free to drag that integration into your publisher stack or ad stack. This is the important step that actually activates the integration. All active integrations are fully visible inside Fusion and can be added or removed by you at any time.
Accepting terms may be a one way street, but as we mention, you are free to remove integrations from publishers or ad stacks at any time, and this will fully remove that integration from running on your site. The publisher will always remain in control.
# Integrations Settings
Source: https://docs.contentignite.com/integrations/settings
Dive into an integrations and set your preferences
## Description
The contents of this field will show up when a user hovers over the integration during ad stack selection. This allows you to explain to the user what this option is.
## Filters
Use filters to control the options available at the ad stack level. For example, if you have multiple organisations and a GAM account for each, you could connect them all at the parent level and restrict each integration to its appropriate organisation. Or even filter out our default GAM option if you are SaaS only.
This removes the chance of human error where the wrong integration is selected because there are multiple options available to select.
You can include or exclude both organisation and publishers.
Note; excluding an organisation does not hide it from the list of integrations on the integrations management page. Users with access to integrations can still see it and can modify the filters at any level of your organisation hierarchy.
## Ads.txt Requirements
Here you can optionally input your line-separated ads.txt requirements for this integration if applicable. This will do several things when selected inside an ad stack:
1. Each publisher will see these ads.txt lines listed as go-live requirements (preventing issues before they can happen)
2. We check the status of all our publisher's ads.txt daily and flag anything that is missing in the UI for all to see
3. We send out a report once a week to publishers highlighting any missing ads.txt lines
4. You can view the status of ads.txt completeness across your network via your health report
### Macros
We have a number of available macros for use when an ads.txt line needs to contain publisher or organisation information as part of it, these are:
* `__UID__` -- This is the publisher's unique ID inside the Content Ignite system
* `__OID__` -- The ID of the publishers parent organisation
* `__PID__` -- The ID of the highest parent organisation
* `__ID1__` -- In the case of GAM, this is the Network ID
* `__ID2__` -- In the case of GAM, this is the MCM ID
* `__UID_DOMAIN__` -- The publishers domain
* `__OID_DOMAIN__` -- The domain of the publishers parent organisation
* `__PID_DOMAIN__` -- The domain of the highest parent organisation
These can be used to include the ID in the ads.txt line:
```txt theme={null}
contentignite.com, __UID__, DIRECT
```
This will be substituted for each publisher, so for a publisher with UID 12345, they will see the following requirement in their ads.txt section:
```txt theme={null}
contentignite.com, 12345, DIRECT
```
If the macro is empty, for example, no MCM ID has been entered, that entire line will be left out.
#### UID Macro
The UID macro enables the implementation of specific ads.txt lines for each publisher during the integration setup. Simply include this macro at the beginning of the line.
```txt theme={null}
[UID:81111] contentignite.com, 12345, DIRECT
[UID:82222] contentignite.com, 67890, DIRECT
```
### Direct vs Reseller
Have direct relationships with some publishers, but indirect with others? This often means different ads.txt lines.
To accommodate this, we have two flags that can be inserted before an adx.txt line so our system can make the correct choice for each publisher. The first part is correctly setting the "Managed" status of each child organisation, where managed means you have a direct relationship.
Then for any lines that need to change based on this, you can add `[managed]` or `[unmanaged]` before it. For example:
```txt theme={null}
[managed] pubmatic.com, 160530, DIRECT, 5d62403b186f2ace
[unmanaged] pubmatic.com, 160530, RESELLER, 5d62403b186f2ace
openx.com, 539625136, RESELLER
```
For the above, the first line will only show for managed publishers, the second line will only show for unmanaged publishers, and the last line will show for all publishers.
## Mapping
Certain integrations require mapping. This is the process of connecting an entity in the third-party integration platform, with an entity inside of Fusion.
A common example of this is publisher mapping, where it is likely that each publisher needs to be set up in the third-party platform, and will have some sort of unique identifier associated with it. You can then enter this identifier into Fusion, against the correct publisher via Publisher Mapping.
This ensures that when you build an ad stack that is shared across publishers, Fusion can deduce the correct id to use when running an ad auction on-site. Do it once and forget about it!
Mapping can be done at any point, such as before updating the ad stack.
You can also map from within an organisation, publisher or config. The net result is the same, its just a question of what works best for you. Typically on boarding a new integration, it would be easier to map everything from within that integration, but onboarding a new publisher, it would likely be more streamlined to map all integrations in one go from within the publisher.
## Additional fields
Integrations can present any number of additional fields and options to you, for example, Google Ad Manager has toggles for various behaviours.
Each field will have a description of its use, provided by the integration.
# Organisation Branding
Source: https://docs.contentignite.com/organisations/branding
Control unit branding to match your identity
You can access custom branding by clicking through to your account settings from your name in the primary navigation menu.
From here, you will be able to select "Organisation Settings" from the top tab bar and scroll down to the branding section.
Custom branding is enabled on request. Colours and logos can be set to brand your dashboard, however, this will only take effect once you have a custom domain set up; something our team will be happy to discuss with you.
## Organisation display name
By default, your organisation name is used throughout the Fusion platform. In some cases, this may not be the most user-friendly format, for example when it includes suffixes such as “Limited”.
You can set a shorter, friendlier display name to use across Fusion instead.
## "About our ads" link
All our high-impact units have a clickable "About our ads" icon next to them to help users understand how our units work and to provide access to our privacy policy and general legal help docs.
By default, this link takes users through to [https://info.contentignite.com](https://info.contentignite.com). However, if you are looking to white-label, then the mention of the "Content Ignite" brand throughout the legal texts might not be ideal. In that case, you can use this field to achieve just that.
We recommend working closely with your account manager to sample the important information we display to users to implement on your own site.
## Support link
For white label solutions, you may have your own support or ticketing system where users can get help, report bugs, or contact your team.
If you provide a support link, the support channels across the Fusion platform will remain available and point to your link. If no link is provided, these will be disabled when white label is active.
## Ad Unit Logo
This logo will be used in non-IAB branded units, and will link through to the "About our ads" page, and onwards to our legal help centre, providing information to website visitors should they need it.
You *must* upload both a dark and light version of your logo to support the various possible placements of ad units.
The logo must be in SVG format to ensure the highest quality visuals.
We recommend a circular logo 20px by 20px. See the following default logos as an example:
| Unit Logo (default, light theme) | Unit Logo (dark theme) |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|  |  |
# Organisation Management
Source: https://docs.contentignite.com/organisations/index
Control various aspects of your organisation and its children
You can manage your child organisations through your organisation management section. From here you can control organisation details and user associations.
Speak to your account manager about enabling organisational hierarchy if it is not currently available on your account.
## Features
From your organisation management pages, you can:
1. Set organisation name
2. Set "Invoice Parent". More details over on the [billing page](/reporting/billing#invoice-parent)
3. Set [custom branding options](/organisations/branding)
4. Manage user access
### User Roles
Users can be created as needed and given access via access roles (see the [User Management help page](/users) for more information).
To grant a user access to an organisation, you need to assign them a role.
1. You can do this simply by clicking the **+ ADD USER** button.
2. In the modal that appears, select your target user from the dropdown list of available users
3. Scan through the groups and roles available and click to select those that apply
4. Click **Save**
An explanation of roles can be found under each role.
*Note: Beware. If you remove a user from all your organisations, they will no longer appear in your list of available users* and you will need to reach out to us to re-gain access
# Organisation Tag
Source: https://docs.contentignite.com/organisations/tag
For large networks, and org tag can streamline rollout
It is always better to use individual publisher tags as opposed to this "Run
Of Network" style tag as this introduces an extra network hop, and therefore
marginal upfront latency.
Our Organisation Tag is a "Run Of Network" style tag designed to make a rollout across a large number of publishers easier when centrally managed.
Every organisation has an organisation tag generated automatically. This tag will dynamically load the correct Publisher Tag based on a domain match (ignoring subdomain). Therefore, ensure that the domain name entered for a publisher inside Fusion is correct — otherwise, no ads will be displayed.
## Management
There is no separate management for organisation tags; they simply load a Publisher Tag.
Configuring of publisher tags is handled at the publisher level. See [Publisher Tags](/publishers/tag) for more information.
# Experiments
Source: https://docs.contentignite.com/publishers/experiments
Manage users and their roles
Experiments allow you to set up a head-to-head against two or more tag configs to test their effectiveness. Don't know what would perform better on your site; two MPU units spaced out or one double-mpu unit? Now you can get your answer!
## Config selections
To run an experiment, simply set up your tag configs as needed. Importantly, you **don't** need to enable them. When an experiment runs, the winning config will be enabled for that users session (if it is not already), and the losing configs will be disabled.
For example, say you have an In-image unit with "In" image targeting, enabled and in active use across your site, but you think "Under" image targeting might be preferred by your users, but want to know any potential revenue impact.
You can do so by duplicating your existing in-image tag config, updating the targeting to "Under" and leaving the config disabled.
When you create your experiment you will be able to select the two configs, and during the experiments lifetime your live config will be disabled as needed and the disabled config enabled when needed! This way, you could perform the experiment on a small amount of traffic, e.g. 20% for each, when 60% of the traffic defaults to the existing "in" image targeting and isn't measured as part of the config.
## Scheduling
Set the start and end date for an experiment as needed. Dates and times are set in your local timezone, with UTC values shown underneath for ease.
You can leave the end date blank to have the experiment run indefinitely until you manually terminate it. We recommend you run experiments for a minimum of two weeks as any new units or new sizes you introduce via experiments, will be seen as new inventory and will go through a ramping phase as buyers slowly start to increase bidding.
Note: Experiments that are live become locked, and can only have their end date adjusted!
# Publisher Management
Source: https://docs.contentignite.com/publishers/index
Each publisher dashboard is your window into a world of insights and control
You can reach your list of publishers from the "Publishers" menu item inside the primary navigation.
From here you will see a tabulated list of publishers and a "New Publisher" button.
Creating a new publisher is as simple as clicking the "New Publisher" button and entering a valid domain name and clicking "Create". There are options to add an optional label to help you identify publishers quickly as well as bulk upload for speedy onboarding.
From here, or from clicking on an existing publisher, you will be taken to the main management page for an individual publisher.
## Publisher Onboarding
For all new publishers, there are several steps that need to be completed before you can go live with your Publisher Tag. These steps will be shown at the top of the page with details on how to complete each step. Once these are all complete, you can enable the Publisher Tag and start monetising your site!
The vital steps to complete are:
### Upload Ads.txt requirements
Adding the required entries to your publisher's Ads.txt is vital to successful ad serving. Your Ads.txt grants us access to serve ads to your site, so without this, advertisers assume we do not have your consent. Click the **View requirements** button to see the lines that need to be present, then upload them to your site Ads.txt file.
You will find a contentignite.com line for each parent organisation. These lines form part of the Supply Chain Object (SCO), part of the ad industries bid transparency specification and required by many partners. It is therefore vital for protecting from revenue loss that these lines are in place.
Our systems check Ads.txt files every hour.
### Add billing information
If you are a SaaS customer, aka someone just using our technology, then we need to be able to charge you for your usage each month. The same goes for the usage of our contextual technology.
If you are using Content Ignite demand, then we need your bank details so we can pay you your hard-earned revenue!
So we make sure these details are on file before going live, to avoid any delays or interruptions to service later down the line.
For more information on billing/payments, see our [billing help page](/reporting/billing).
### Setup up MCM connection
When using our ad server, Google must approve each organisation and publisher to ensure they meet their policy requirements, this is an automated process and we will inform you of any issues in this process via email. Approval typically takes one business day but can take up to two weeks.
There is nothing additional required from you for this step.
### Get site approved by Google
Every publisher needs their domain approved by Google for monetization. No actions are needed here and approval typical happens within a day (but can take up to two weeks). Googles decision is outside of our control but we will notify you of any status changes as they happen.
### Get approved
Internal verification ensures your organisation and publisher meet our quality standards. Verification is automated and you will get an instant decision upon initial set up of a new publisher.
If you are rejected at this stage, you will be given a single opportunity to appeal the outcome, where a member of our team will then review your case and make a decision typically within 3 working days.
### Set up your first tag config
Before you can go live, make sure you have at least one config in place. A config is a group of settings describing a single ad unit type and its targeting specific to its parent publisher.
For more information on tag configs, see our [Tag Configs help page](/publishers/tag-configs).
### Accept our terms
Our platform terms need to be accepted before you go live. Your account manager will reach out regarding this and once signed, will be marked as completed here in platform.
### Go live!
The only thing left to do at this stage is to integrate the Publisher Tag into your site. See our section on [Tag Deployment](/publishers/tag-deployment) for more information.
## Tag Status
The tag status block contains a toggle allowing you to turn your Publisher Tag on or off as required. This will be disabled if any of the onboarding steps are still outstanding. It will also display information if there are any tag issues, such as out-of-date code, or missing active tag configs.
Above the tag status, you will also notice the build status. Any changes to your tag that would require we push an update (config changes, publisher setting changes etc) will be queued up to be re-built and deployed live (takes place with 5 minutes of change).
These statuses are for your information only and require no input from you. Until the status reads "Complete" you can assume any changes you have made will not be live and in-effect yet.
The status flow is as follows:
1. `Update queued` - The tag update is in the queue waiting to be processed by our systems.
2. `Update in progress` - Our systems are re-building your tag at this very moment
3. `Purge pending` - The tag has been updated, but we need to clear the cache for it to show
4. `Purge in progress` - The cache purge is in progress
5. `Complete` - The tag has been fully rebuilt and the cache has been cleared. You should see your latest changes in effect.
There is also a sixth status, of `Deploy frozen`, for when a [deployment freeze](/publishers/settings#deployment-freeze) has been set up against the publisher.
## Publisher Insights
From quick dashboard overviews to detailed Insight Hub pages, the Publisher Management platform offers a wealth of performance and health data for publishers to dive into.
Monitor a quick collection of graphical and statistical data over a 30-day rolling period, all accessible from the Publisher Management Dashboard. Toggle between various graphs to view different aspects of publisher health, with hoverable daily breakdowns.
You can also navigate to the Insights Hub dashboard to uncover in-depth data on various health and performance aspects of your publisher setup.
## Tag Configs
The last block on the page contains a list of all your tag configs, these instruct the Publisher Tag on what units to load, where to place them and what features to enable. More information can be found on the [Tag configs help page](/publishers/tag-configs).
## Publisher Actions Menu
Clicking the three vertical dots in the top right of a publisher page will open up a publisher actions menu. From here you can manage various publisher-specific settings.
### Tag instruction emails
If you are managing a none O\&O publisher that you have not given dashboard access to, you can use this feature to send them instructions on tag integration and Ads.txt requirements.
The email will open up in your email client, allowing you to review the content before sending it.
### Live demo
Click this option and enter a full URL to a page on your publisher site, and we will generate a page that includes the Publisher Tag and all its configs. Great as a first step before go-live, to get an idea of what units work best with a publisher, or to simply help you sell a non-O\&O publisher on the product.
### Ads.txt requirements
Click this to bring up the Ads.txt requirements if you ever need to reference them. These can change from time to time, however, any issues will be highlighted in your organisation's [Diagnostics report](/reporting/insights/diagnostics).
### AdAgents.json requirements
Click this to bring up the AdAgents.json requirements if you ever need to reference them. These can change from time to time so be sure to check out the [managed version](/publishers#managed-adagents-json) to avoid needing to make manual changes!
AdAgents.json is similar (in its intended outcome) to Ads.txt. But instead of authorising supply platforms, it authorises agents! The Agentic ad ecosystem is still in its infancy, but we expect to see this grow rapidly. As you are a Content Ignite customer, you'll be fully with us on this journey into the future of AdTech!
## Managed Ads.txt
We understand that managing your ads.txt file can be a bit of a hassle, especially when ensuring a smooth supply chain and avoiding common pitfalls. That’s why we offer a Fusion-managed ads.txt file for each publisher — fully set up and ready to go, with no ongoing maintenance required.
You can find a link to the hosted version of your file in any of the Ads.txt requirements modals. This link can then be pointed to from your domain setup.
Working with other third-party partners? No problem. In our [Third-party
Requirements](/publishers/settings#third-party-adstxt-requirements) Settings
section, any valid third-party ads.txt lines you enter will be automatically
tracked and added to your hosted file.
### Setting up a domain redirect
Each setup may vary and could require some development resources, but once it’s done, you shouldn’t need to manage it further.
There are two fundamental approaches to consider; **redirecting** and **proxying**. Redirecting is simply sending a user/bot from one URL to another, this is typically quite easy to set up, but in the example of Fusion, it does mean the user/bot will end up on our domain and not yours. To keep the URL on your domain at all times you can use proxying; where the contents of the target URL is pulled in behind the scenes.
```txt title="Redirection" theme={null}
Start URL: https://example.com/ads.txt
[REDIRECT]
Final URL: https://cdn.tagdeliver.com/ciat/12345/ads.txt
```
```txt title="Proxying" theme={null}
Start URL: https://example.com/ads.txt
[Fetches content from https://cdn.tagdeliver.com/ciat/12345/ads.txt]
Final URL: https://example.com/ads.txt
```
Here are some typical high-level methods for common web servers, setting up redirects to the hosted ads.txt file:
#### Apache (using `.htaccess` file)
There are several ways to set up redirects in an Apache environment, such as server or domain-level configuration files. To keep things simple, we’ll show you how to do it at the individual domain level using an `.htaccess` file.
1. Access your web server where your website is hosted via FTP, SSH or a file manager.
2. Locate or create the `.htaccess` file in the root directory of your website. This is usually in the `public_html` folder.
3. Open the file using your preferred text editor, or via terminal/SSH using something like the `nano` editor, and add an Apache redirect line. For example:
```apache title="Option 1: Redirection" theme={null}
Redirect permanent /ads.txt https://cdn.tagdeliver.com/ciat/{your_pub_id}/ads.txt
```
```apache title="Option 2: Proxying" theme={null}
ProxyPass /ads.txt https://cdn.tagdeliver.com/ciat/{your_pub_id}/ads.txt
```
4. Save the changes, then restart Apache. You can do this with a command like:
```sh theme={null}
sudo systemctl restart apache2
```
***
#### Nginx (using `return` directive)
There are two main ways to implement redirects in Nginx: `return` and `rewrite`. Since this is just a simple file redirect, we’ll demonstrate the easier `return` method.
1. Locate and edit (or create) the Nginx configuration file, usually found at `/etc/nginx/nginx.conf`, or in `/etc/nginx/site-available` for specific domains (recommended).
2. Find the `server` block corresponding to the website domain.
3. Add the location redirect. For example:
```nginx title="Option 1: Redirection" theme={null}
location = /ads.txt {
return 301 https://cdn.tagdeliver.com/ciat/{your_pub_id}/ads.txt
}
```
```nginx title="Option 2: Proxying" theme={null}
location = /ads.txt {
proxy_pass https://cdn.tagdeliver.com/ciat/{your_pub_id}/ads.txt
}
```
4. Save the changes, then reload Nginx to apply them. You can do this with:
```sh theme={null}
sudo systemctl reload nginx
```
***
#### Cloudflare
Cloudflare lets you set up URL redirections using **Redirect Rules** via the dashboard, API, or Terraform. We’ll go through setting up a single redirect in the dashboard.
1. Log in to the Cloudflare dashboard and select your domain.
2. Go to **Rules** > **Redirect Rules**
3. Under **Single Redirects**, click on the **Create rule** button
4. Enter a rule name (e.g., Ads.txt Redirect)
5. For **When incoming requests match**, set the following:
* **Field** = `URI Path`
* **Operator** = `equals`
* **Value** = `/ads.txt`
6. For **Then...**, configure:
* **Type** = `Static`
* **Status code** = `301`.
* **URL** = `https://cdn.tagdeliver.com/ciat/{your_pub_id}/ads.txt`
7. Review your settings and click **Save** or **Deploy** to activate the redirect.
*Note: Cloudflare dashboards may vary depending on your plan and might change
over time.*
***
#### cPanel
Using cPanel’s built-in redirect tool is a straightforward way to add redirect rules for your domain.
1. Log in to cPanel and go to **Domains** > **Redirects**
2. In the **Add Redirect** section, set the following:
* **Type**: Select `Permanent (301)`
* **Domain**: Choose your domain from the dropdown (`https?://(www.)?`)
* **Path**: Enter `/ads.txt` in the field after the selected domain
* **Redirects to**: Enter your hosted ads.txt URL: `https://cdn.tagdeliver.com/ciat/{your_pub_id}/ads.txt`
* **Redirect with or without www**: Choose whether this applies to just the `www` version, non-`www` version, or both (recommended)
* **Wild Card Redirect**: Leave `unchecked`
3. Click **Add** to create the redirect
Redirects added through the cPanel interface are placed at the bottom of the
`.htaccess` file. Some third-party applications might ignore these rules
because they only read configurations within their section of the `.htaccess`
file. In such cases, you may need to edit the `.htaccess` file directly or
through the **File Manager** interface.
### Conclusion
Each of the examples provided will set up a permanent 301 redirect for any request to **[https://yourdomain.com/ads.txt](https://yourdomain.com/ads.txt)**, pointing it to your hosted ads.txt file.
It’s a good idea to test the redirection after setting it up. Here are a couple of common methods to do this:
* **In the browser**: Visit `https://yourdomain.com/ads.txt` and check if it redirects correctly.
* **Using a command-line tool**: Run a command like `curl -I https://theirwebsite.com/ads.txt` to ensure the status code is `301` and that it points to the right destination.
These examples are meant as a starting point for setting up redirects. Since server and domain configurations can be quite complex and vary widely, it’s always a good idea to consult your technical team for tailored advice and assistance with your specific setup.
### Common Implementation Issues and Troubleshooting
* **Setting the Wrong Redirect Type**
Make sure you set the redirect as a 301 (permanent). Using a 302 (temporary) redirect could confuse ad verification systems.
* **Single Redirects**
According to the [IAB Ads.txt 1.1](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1.pdf) guidelines, only single redirects are allowed when redirecting to destinations outside of the original root domain. This means you should avoid any additional redirects to ensure one-hop delegation.
* **Case Sensitivity**
Some web servers are case-sensitive. Double-check that your redirect points to `/ads.txt`, not `/Ads.txt` or any other variation.
* **Watch for Overrides**
When setting up redirects at the domain level (e.g., Apache, Nginx), be cautious of other redirect rules that might override or conflict with yours. This can happen either at the same level or within server-level configuration files.
* **Multiple Sources**
Only set up one redirect per domain. Having multiple redirects can cause issues with ad verification systems.
* **SSL/HTTP Issues**
If your domain uses HTTPS, ensure the redirect points to the secure URL (e.g., `https://cdn.tagdeliver.com/...`). Also, confirm that the original domain uses HTTPS or set up an HTTP-to-HTTPS redirect.
* **Caching**
When using Cloudflare or other CDN services, don’t forget to purge the cache to apply your changes immediately.
### Useful Redirection Resources
* [How To Create Temporary and Permanent Redirects with Apache and Nginx](https://www.digitalocean.com/community/tutorials/how-to-create-temporary-and-permanent-redirects-with-apache-and-nginx) by DigitalOcean
* [Nginx Rewrite URL Rules Examples](https://www.digitalocean.com/community/tutorials/nginx-rewrite-url-rules) by DigitalOcean
* [Creating Nginx Redirects](https://runcloud.io/docs/creating-nginx-redirects) by Runcloud
* [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/) by Cloudflare
* [Redirects](https://docs.cpanel.net/cpanel/domains/redirects/) by cPanel
* [IAB Ads.txt 1.1](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1.pdf) by IAB
## Managed AdAgents.json
AdAgents.json is a new concept as of 2025, so the spec may update frequently as the AdCP protocol matures. With that in mind, you don't want to be making manual changes little and often to this file if you can help it, hence our offering of a Fusion hosted version! Simply redirect or proxy to your unique file, found in your [publisher dashboard](/publishers#adagents-json-requirements).
### Setting up the redirect
The process is exactly the same as it is for Ads.txt, [which can be found here](/publishers#setting-up-a-domain-redirect), just remember it needs to redirect from `https://example.com/.well-known/adagents.json` where example.com is your domain.
E.g. For Apache:
```apache theme={null}
Redirect permanent /.well-known/adagents.json https://cdn.tagdeliver.com/ciat/{your_pub_id}/adagents.json
```
### Useful Redirection Resources
* [Official AdAgents.json Tech Spec](https://docs.adcontextprotocol.org/docs/media-buy/capability-discovery/adagents) by AdContextProtocol
* [Validate, create, and manage adagents.json files](https://adcontextprotocol.org/adagents) by AdContextProtocol
# JS API
Source: https://docs.contentignite.com/publishers/js-api
Our tag has a number of public methods for setting data and triggering actions
**Cloudflare Rocket Loader Warning**
For any on page scripts using the Content Ignite JS API, it is important that you exclude the script from Rocket Loader (if used), which defers JS and in the case of the examples below, can prevent them from running altogether. Our JS API is a simple and fast way to queue the passing of information to our Publisher Tag, and as a result of the code not running immediately, has nil impact on page performance. [Read more](/getting-started/going-live#notes-on-caching-and-firewalls)
## Passing data to ID/Signal providers
```ts title="Definition" theme={null}
.passSignalData(type: 'email'|'phone', value: string)
```
When passing us PI for use by id/signal providers, ensure you pass it on every page load that the PI is available.
For email, the obvious one is on login and every page load while logged in, but a secondary important scenario is newsletter sign up! In this case, you are looking to pass the email address at every opportunity.
**Privacy**
It is worth noting that any PI passed through using this method never reaches the Content Ignite servers. We do not store this data in any way, we simply act as the "pipes" to pass it to the ID vendors you've configured in Fusion, all handled client side.
```js title="Example" theme={null}
window.__ciads = window.__ciads || { cmd: [] };
window.__ciads.cmd.push(() => {
window.__ciads.passSignalData("email", "jamie@contentignite.com");
});
```
## Setting targeting
```ts title="Definition" theme={null}
.setTargeting(key: string, values: string | string[])
```
This method allows you to pass custom page targeting directly to our tag, this could be data returned by your CMS for example.
It is against our terms of service, and Googles, to pass in Personal
Information via this feature, things such as email addresses, age, gender etc
are forbidden.
```js title="Example" theme={null}
window.__ciads = window.__ciads || { cmd: [] };
window.__ciads.cmd.push(() => {
window.__ciads.setTargeting("tags", ["news", "politics"]);
});
```
### Mergeing vs Overwriting vs deleting key-values
When you call `.setTargeting()` with a string value, it will merge that value with any existing values for that key. If you call it with an array value, it will overwrite any existing values for that key. To delete targeting values for a given key, call `.setTargeting()` with the value `NULL`.
### Config/Slot level targeting
```ts title="Definition" theme={null}
.setTargeting(key: string, values: string | string[], slotId: string)
```
The optional third parameter of `.setTargeting()` allows you to pass targeting for a specific slot, identified by either the config ID, unit type or parent container ID. If not passed, the targeting will be applied at the page level.
```js title="Example" theme={null}
window.__ciads = window.__ciads || { cmd: [] };
window.__ciads.cmd.push(() => {
window.__ciads.setTargeting("tags", "news", "12345"); // targeting for config with id of 12345
window.__ciads.setTargeting("tags", "news", "in-image"); // targeting for all in-image units
window.__ciads.setTargeting("tags", "news", "div-gpt-ad-1611935295857-0"); // targeting for the unit with the parent container ID of 'div-gpt-ad-1611935295857-0'
});
```
### Targeting Macros
When passing targeting values, you can also use macros to pass dynamic values. The macros available are:
* `{CONFIG_ID}` The config ID as it is in Fusion; e.g. 1234
* `{INSTANCE_COUNT}` The instance count for repeating units; e.g. 1, 2, 3 etc
* `{UNIT_TYPE}` Unit type from Fusion; e.g. in-image, adhesion, iab etc
Simply include the macro in the value string and it will be replaced with the relevant value for each ad unit when the tag processes the targeting.
```js title="Example" theme={null}
window.__ciads = window.__ciads || { cmd: [] };
window.__ciads.cmd.push(() => {
window.__ciads.setTargeting("pos", "ad-{INSTANCE_COUNT}"); // will pass pos: ad-1 for the first instance of a unit, pos: ad-2 for the second instance etc
});
```
### IAB Taxonomy (reserved keys)
We support two different IAB taxonomy types, which you can pass in via `.setTargeting()` by use of their reserved keys, these are:
* `IAB_AUDIENCE_1_1` - [IAB Specification](https://iabtechlab.com/standards/audience-taxonomy/), [List of Values](https://github.com/InteractiveAdvertisingBureau/Taxonomies/blob/develop/Audience%20Taxonomies/Audience%20Taxonomy%201.1.tsv)
* `IAB_CONTENT_2_2` - [IAB Specification](https://iabtechlab.com/standards/content-taxonomy/), [List of Values](https://github.com/InteractiveAdvertisingBureau/Taxonomies/blob/develop/Content%20Taxonomies/Content%20Taxonomy%202.2.tsv)
For example, to pass the content taxonomy of "Automotive", you'd call:
```js title="Example" theme={null}
window.__ciads = window.__ciads || { cmd: [] };
window.__ciads.cmd.push(() => {
window.__ciads.setTargeting("IAB_CONTENT_2_2", [1]);
});
```
Note that if you enable contextual inside of Fusion for a given publisher,
then the `IAB_CONTENT_2_2` taxonomy is already passed for you!
## SPA reloads
```ts title="Definition" theme={null}
.reload()
```
Strictly for use in SPA's (Single Page Applications). This will cause a new page impression to register and all existing ads to be destroyed and re-built.
```js title="Example" theme={null}
window.__ciads = window.__ciads || { cmd: [] };
window.__ciads.cmd.push(() => {
window.__ciads.reload();
});
```
## Tag Events
For custom development, there are several JavaScript events that are triggered throughout an ads life cycle. You can hook into these as needed to perform additional follow-up actions.
These are standard JavaScript events, available on the window the tag was deployed into.
For example, for a direct tag-on-page deployment, you can listen to an event with the following:
```js title="Example" theme={null}
window.addEventListener("ci_al", function (e) {
console.log(e.detail);
});
```
Depending on the event, a `detail` object is returned with the following optional fields:
* `detail.config_id` - STRING - The id of the ad unit the event was triggered from
* `detail.msg` - STRING - Further details of the event
* `detail.targeting` - OBJECT - The key-value targeting applied to the slot for the ad request. Only present on the `ci_al` and `ci_am` events (see [Reading slot targeting](#reading-slot-targeting) below).
The following events are available:
| **Event Name** | **Description** |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Audience Push `ci_ap` | Fired when an audience is matched and will be pushed into Ad Manager. Fired once per ad unit. |
| Ad Impression `ci_ai` | Fired when an ad has had a viewable impression (50% of the ad’s pixels are visible in the browser window for a continuous 1 second.) |
| Page Impression `ci_pi` | Fired once for each page once the tag has loaded |
| Ad Unit Load `ci_aul` | Fired once an ad unit has been loaded. Once user consent has been received (if applicable) and an ad has been served. For in-view units, this will be once the in-view event was detected. |
| Ad Load `ci_al` | Fired once an ad unit has been loaded. Once user consent has been received (if applicable) and an ad has been served. For in-view units, this will be once the in-view event was detected. For refresh units, this will fire once per refresh. |
| Ad Miss `ci_am` | Fired if an ad unit did not receive an ad (either ad\_load or ad\_miss will be triggered for each ad and any subsequent refreshes) |
| Consent Denied `ci_cd` | Fired when user consent is required but was not given |
| Tag Error `ci_te` | Fired on an unexpected tag error |
### Reading slot targeting
The `ci_al` (Ad Load) and `ci_am` (Ad Miss) events include a `detail.targeting` object containing all of the key-value targeting that was applied to that slot for the ad request — in other words, everything that was sent to the ad server. This includes any values you set via [`.setTargeting()`](#setting-targeting), the tag's own key-values, and the header-bidding keys applied during the auction (such as `hb_pb`, `hb_size`, `amznbid` and `amznsz`).
Each value is returned as an array of strings.
This lets you react to the outcome of the auction — for example the winning size and price — from your own page code, without needing to read from Prebid or Amazon directly.
```js title="Example" theme={null}
window.addEventListener("ci_al", function (e) {
console.log(e.detail.config_id); // e.g. "12345"
console.log(e.detail.targeting);
// {
// "hb_pb": ["7.00"],
// "hb_size": ["970x250"],
// "amznsz": ["970x250"],
// "pos": ["ad-1"]
// // ...plus any other key-values applied to the slot
// }
});
```
# Publisher Settings
Source: https://docs.contentignite.com/publishers/settings
Powerful high-level settings for your publisher, enable contextual, integration and so much more
Clicking the cog icon in the top right of a publisher page will take you through to publisher settings. From here you can manage various publisher-specific settings.
## Branding
Set internal labels for easier identification throughout the system as well as branding & RSS feed URL for use in video content.
You could use the 'Tags' feature to group publishers with custom, meaningful entries such as grouping publishers by country of origin or by different categories. It's easy to use! Simply type in a tag, hit enter to add it and then remember to save.
## Integrations (Publisher Stack)
There are a number of integrations grouped as "Publisher-level integrations". These are integrations that apply to a publisher as a whole, rather than individual parts of the ad stack (such as demand sources). Common examples of these integration types are CMP's, ad block recovery tech and ID solutions.
You can activate these integrations in this section by simply picking from a list of applicable integrations that have been [previously connected in](/integrations).
Some integrations are a simple one click to integrate, others require further information, if they do need additional input, you will be guided through the process.
## Tracking
You can use this section to add custom pixel or JavaScript trackers. This section is for technically trained users only. It is worth speaking to your account manager if you have additional tracking needs, where we can then advise you on the required setup.
## Visual Customisations
You can set Global CSS overwrites here to fix publisher-specific styling issues. However, this feature is for experienced web developers only. It is recommended you do not change this field, and leave it to your account manager to fix styling issues on your behalf.
## Custom Key-values
Custom key-values allow you to pass in targetable data into the ad server. More on this over on [Publisher Tag Features](/publishers/tag#custom-key-values).
## Optional Features
Optional features are features that can be enabled with a simple toggle.
### AI Dynamic Floors
Whether P\&P or SaaS, you can make use of our AI Dynamic Floors system. Dynamic Floors are enabled on a traffic percentage basis, so you can be confident in the model as you ramp up. Simply drag the slider between 0% (completely off) and 100% (fully on).
Dynamic floors are deployed daily at midnight (UTC), so the percentage traffic split you have chosen will only take effect come midnight, and will remain as is for a full 24-hour period.
Our model takes into account historic date trends, device, browser and country all applied at the granular tag config level for highly targeted floors.
Note: Dynamic floors apply to your ad server demand (some set up required for SaaS) and all Prebid SSP's. Dynamic floors do not apply to wrappers such as OpenWrap and Amazon Publisher Services.
### Debug Mode
Debug mode can be enabled on a per page basis by adding the `?cipt_debug=true` query parameter to the page URL. This is the recommended way of debugging our Publisher Tag. In cases where our tag is served into a safe frame, for example, that query parameter will not work, so enabling the debug mode toggle here turns it on globally.
Debug mode provides additional output in your browser's developer console. This is to be used by your development team only to help identify or track down any issues and should be disabled as soon as it is no longer needed.
### βeta Tag
This feature should not be used without first discussing it with your account
manager.
We are constantly developing and improving our Publisher Tag, and before we release an update to everyone, we release it in "βeta". This is an early development preview and comes with the risk of not being tested. Enabling this could therefore break your ad serving and reduce your revenue.
If we are working with you on a new feature that benefits your particular publisher, we may enable this for you to test its effectiveness.
### Page change detection
Our tags can detect when a page change event occurs, these are events triggered by client-side scripts that don't reload the whole page. This is often used by Single-Page Applications (SPA's) or by feature libraries such as galleries, where each change in viewed image, updates the URL accordingly which helps users share or bookmark pages.
When our tag detects these events, we reload the ads on page as if a full page change occurred, ensuring we re-assess all the targets on page, and load ads as expected.
This feature should be enabled as required by your developers, there is a small risk that rouge scripts could cause page change events when they are not supposed to, causing ads to reload and performance stats to decrease.
For SPA sites, we recommend you disable this feature and use the more targeted method of calling `window.__ciads.reload()` to trigger our tag to reload, as this is a much more narrow and controlled approach. More on this method in our [JS API section](/publishers/js-api#spa-reloads).
### Guarantee roadblocks
Usage of this feature is discouraged as it disables in-view and the
efficiencies it brings, please discuss with your account manager before
activation.
Guaranteed roadblocks are roadblocks where the ad server guarantees that multiple creatives will be served together on a page.
In most cases, guaranteed roadblocks are unnecessary. We recommend you serve campaigns via tenancy, where creatives serve throughout the page. This is the most flexible and efficient setup while maintaining pacing control, targeting etc.
In the case of guaranteed roadblocks, for the ad server to ensure all units fill from the same line-item, it needs to receive all ad requests together. This means that in-view can not be active (where we efficiently load a unit only when it comes into view), causing units to inefficiently load out-of-view, directly impacting your viewability stats and increasing the resources used on each page load.
Caveat; For targets that are not initially found on page, but load in later on (for example, lazy-load images or extra content via infinite scroll), these will not participate in the shared session, unless loaded in with 10 seconds of the rest.
## Deployment freeze
You can schedule a deployment pause for the Publisher Tag being rebuilt, temporarily queuing up any changes to the Publisher Tag between the selected start and end dates. Once the end date has passed, your tag will resume building automatically.
Benefits of this feature include:
* The ability to make lots of changes to publisher settings, tag configs etc, and deploying them all together at a set time.
* Pausing new tag builds over a period where publisher management is trickier, such as over a company Christmas 'shutdown'.
We've setup a 30-day maximum period from the start date to ensure your tag doesn't go too long without a rebuild, guaranteeing it stays up-to-date with the latest features and security upgrades.
## Third-party Ads.txt Requirements
As part of our [Ads.Txt Insights](/reporting/insights/ads-txt#file-lines) analysis, we are able to map a publishers current ads.txt file lines against the required lines derived from the demand partners in your ad stacks. This allows us to discover what lines fall outside of our requirements and are deemed as "Untracked".
These untracked lines may include genuine inventory required from other third party partners you work with.
In order for us to ascertain between genuine inventory and lines that may be legacy or dormant (which can pose many complications and negative revenue effects), we provide a field on the publisher settings page where you can enter any **active** third party ads.txt lines. This allows us to track these lines and add them as part of the requirements for the given publisher, making any untracked lines a flag for removal as part of the ads.txt insights.
Simply input your line-separated ads.txt requirements, remembering to follow [IAB Ads.txt 1.1](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1.pdf) guidance, and we'll do the rest.
Further information on how we use these requirements, macro usage and relationship management which can be applied, [read more](/integrations/settings#adstxt-requirements) in our docs.
# Publisher Tag
Source: https://docs.contentignite.com/publishers/tag
Our single Publisher Tag is at the core everything we do
We operate our units via a single Publisher Tag, unique to your domain. This tag orchestrates as many units as required, minimising resources while providing maximum flexibility.
Upon signing up to Content Ignite and creating your first publisher, you will be presented with your unique Publisher Tag.
We advise you put this live as quickly as possible, along with your ads.txt requirements, to minimise delays in earnings. (no ads will be shown until onboarding is complete and you directly toggle on the tag in our UI).
## Privacy
Our tags only collect anonymised logs, which are only stored for 5 days to be processed and stored as daily summary reports.
We also read from CMPs to ensure GDPR compliance, defaulting to non-personalised ads if consent could/was not obtained. We, therefore, recommend that all publishers have a CMP in place, and ensure that Content Ignite is enabled as an advertising partner/vendor.
We also abide by CCPA and global privacy laws by offering opt-out functionality via contentignite.com, and additionally we read and honour GPC (Global Privacy Control) flags.
All of our high-impact ads have an info button for users to find out more information and opt-out of personalisation if they so wish. This can be found at [https://info.contentignite.com/](https://info.contentignite.com/).
Full details about privacy can be found over on our [Privacy
Policy](https://contentignite.com/privacy-policy/).
## Tag & Unit Features
Our Publisher Tag has a number of features that can be used to your advantage. At the top level, before individual units are initiated, there are:
* Custom tracking support
* GDPR management (CMP support)
* Custom events
Find out more about these publisher-level settings over on the [Publisher Settings help page](/publishers/settings).
Other features are unit (config) specific, as follows:
| | **In-Image** | **In-Article** | **Adhesion** | **IAB** | **Interstitial** |
| ------------------------------------ | ------------ | -------------- | ------------- | ------- | ---------------- |
| **Native & Display** | ✔ | ✔ | ✔ | ✔ | ✔ |
| **Interval Refresh** | ✔ | ✔ | ✔ | ✔ | - |
| **High Viewability \[1]** | ✔ | ✔ | ✔ | ✔ | - |
| **Brandable** | ✔ | ✔ | ✔ | 𐄂 | - |
| **Auto-scaling** | ✔ | ✔ (down only) | ✔ (down only) | 𐄂 | - |
| **In-View \[2]** | ✔ | ✔ | 𐄂 | ✔ | - |
| **Multi-target** | ✔ | ✔ | 𐄂 | 𐄂 | - |
| **Every-other targeting** | ✔ | 𐄂 | 𐄂 | 𐄂 | - |
| **Video** | 𐄂 | ✔ | 𐄂 | 𐄂 | 𐄂 |
| **Responsive re-locate** | 𐄂 | 𐄂 | ✔ | 𐄂 | - |
\[1] High Viewability is a progressive feature, supported by all
modern browsers, older browsers will not refresh. This ensures we can guarantee
industry-leading viewability while practising responsible advertising.
[https://caniuse.com/#feat=intersectionobserver](https://caniuse.com/#feat=intersectionobserver)
\[2] InView is a progressive feature, supported by all modern
browsers, older browsers will load the ad immediately as a fallback (IE).
[https://caniuse.com/#feat=intersectionobserver](https://caniuse.com/#feat=intersectionobserver)
### High Viewability
Our high viewability feature ensures ads *only* load & refresh when we know the ad is in view of the user, ensuring maximum efficiency and inventory viewability.
By keeping track of a unit's visibility in the user's current viewport, taking into account minimised windows and background tabs, we can ensure we only process a unit when a user can see it in that moment.
This feature is enabled for all publishers. You may see a reduction in your overall impressions if coming from a less viewable solution. With high-quality traffic, this will reduce your revenue in the short term, but boost viewability and click-through rate, and therefore you should see an increase in CPMs after a short while.
### Ad Refreshing
Google requires that you declare inventory that refreshes. If you are a SaaS customer, you must do this yourself by following Google's instructions: [https://support.google.com/admanager/answer/6286179](https://support.google.com/admanager/answer/6286179). We operate off of "Time intervals" at a default of "35 seconds" between refreshes.
## Custom Key-values
As the publisher, you have the ability to pass key-values directly to the Content Ignite Publisher Tag via our [tags JS API](/publishers/js-api#setting-targeting).
While the API method gives you full control over custom key-values, for those publishers that are resource constrained, we have the ability to pull key-values from the page without any development on the publisher side. This could be data in meta tags, data attributes on HTML elements, or really anything that exists in the pages source code.
This is particularly useful when migrating ad servers to Content Ignite and continuing campaigns via the GAM Teams feature. We can mimic your existing setup to help ease the transition.
Custom key-values are something that can be set up by your account manager and will be visible in your publisher settings page.
# Ad Stacks
Source: https://docs.contentignite.com/publishers/tag-ad-stacks
Group ad servers, demand and more into reusable ad stacks
Ad stacks are powerful groupings of all the various pieces that make up the ad tech ecosystem. This could be as simple as a single ad server, or as complicated as header bidding, Amazon TAM, ad block recovery tech and custom fallback creatives all bundled together.
Ad stacks are designed to make building complex set-ups that would otherwise involve a huge technological undertaking to implement, as simple as dragging and dropping your desired platforms.
## Core Concepts
### Reusable
Ad stacks can be reused across any publisher in your organisation if desired, simply give your ad stack a name, and it will be surfaced for selection. Changes to a shared ad stack will be applied to all uses of it in one go.
Going further, you can select an existing ad stack and "detach" it, making a copy for you to change as needed. This makes it nice and easy to create a new ad stack based on an existing one.
So how many ad stacks do I need? What is the optimal setup? Really this depends on your requirements, but we'd recommend you start with a single ad stack across all your publishers. Handily, a "Default Ad Stack" is automatically created for every organisation, which contains the Content Ignite Ad Server; the easiest route to monetisation. Speak with your account manager should you need help with more advanced set ups.
### Your relationships or ours?
All elements of an ad stack can utilise our direct relationships with the various platforms or your own existing contracts, the choice is yours!
If you'd like to connect in your own integrations, you can do so easily via the [Integrations](/integrations) section.
### Mapping
Certain integrations require mapping. This is the process of connecting an entity in the third-party platform, with an entity inside of Fusion.
A common example of this is publisher mapping, where it is likely that each publisher needs to be set up in the third-party platform, and will have some sort of unique identifier associated with it. You can then enter this identifier into Fusion, against the correct publisher via Publisher Mapping.
This ensures that when you build an ad stack that is shared across publishers, Fusion can deduce the correct ID to use when running an ad auction on-site. Do it once and forget about it!
Mapping can be done by the integration owner, and for integrations that require it, will prevent the integration from going live until this step is complete. You will be warned of any missing requirements in the UI. If you are using Fusion on P\&P basis, all mapping requirements will be on your account manager.
More info available here: [Integration Mapping](/integrations/settings#mapping)
## Ad Tech
Here you can activate per unit tech such as ID solutions. In the case of ID solutions, including a 3rd party into your ad stack only facilitates the passing of IDs into the bid stream. There are a number of other key steps that may need to be followed for IDs to come into effect:
1. **Accepting of terms** -- Some ID providers handle/require Personal Information (PI) such as email addresses, in these cases you need to agree to the terms of the 3rd party over in [Fusion's Policy Centre](/integrations/policy-centre).
2. **Include the publisher level integration** -- Each ID solution require a script on page that exchanges user information for the all important "ID". This ID is what is then passed into the bid stream. Fusion can handle this step for you if you have not deployed these scripts already, simply [include the ID integration in your publisher stack](/publishers/settings#integrations-publisher-stack)!
3. **Pass user information** -- Some ID providers require PI such as email address, this should be passed via your [publisher tags JS API](/publishers/js-api).
## Ad Demand
The first integration type for ad stacks is ad demand. This is header bidding partners/SSPs/wrappers. Essentially any bidding that will occur before the ad server auction. The great thing here is that you don't need to worry about the underlying technology, just pick the SSP's you want and away you go!
Content Ignite have carefully curated settings that we believe will work optimally for all our publishers, but you always have the control to make changes yourself. Clicking the cog icon next to the ad demand section allows you to control things such as timeouts, bid throttling and user ID modules.
Clicking the cog icon on individual integrations will show you all configuration options available.
## Ad Servers
The ad server is responsible for hosting the final auction that returns an ad to page. You have the option to use yours or ours and even set things up in a first-look second-look setup, meaning that if your ad server failed to deliver an ad, it would automatically pass the request onto our server!
Clicking the cog icon on individual integrations will show you all configuration options available.
## Fallback Creatives
Fusion is laser-focused on optimising for yield, ensuring the maximum revenue for you, but with this comes less than 100% fill. If you'd like to make use of that empty space when an ad is not served, you can place your own creatives to page! This is perfect if you have a merchandise shop you'd like to promote.
Fallbacks can take the form of images uploaded to Fusion, where you can set the click URL and standard and high-resolution images. All activity is tracked and viewable in your report builder as you'd expect.
The second option is script creatives, where we can serve a custom JavaScript file to page, unlocking limitless possibilities.
Multiple creatives can be added at the same time, where they will be randomly cycled through. An optional weighting allows you to show some creatives more than others if preferred.
# Publisher Tag Configs
Source: https://docs.contentignite.com/publishers/tag-configs
These configs wrap up unit types, behaviours, targeting and more
Each set of instructions inside the master Publisher Tag is referred to as a "tag config".
Each tag config describes the behaviour and targeting for a single ad unit type (in-image, adhesion etc)
You can build up as many configs as needed to match your requirements and the publisher's site structure.
For example, need in-image on desktop and tablet, but under-image on mobile? Just create two configs which will both have identical targeting, except for device and in-image positional behaviour.
## Creating a Config
To create a config, simply click the "New Config" button, and select an ad unit type.
After selecting an ad unit, you will be taken to the configuration page.
## Configuration Options
When configuring a config, you will see various ad unit-specific options available, such as supported formats, and unit placement/targeting.
For an insight into ad unit features, see the [Publisher Tag features table](/publishers/tag#tag-unit-features)
## In-image
In-image is perhaps our most advanced unit, attaching to an element on the page (doesn't even have to be an image!) and scaling perfectly to fit it. You can even have it appear under its target if covering content is not an option for your site.
The minimum size requirements for in-image's target element is 250px wide and 120px high, and a max ratio of 3 (width/height). Also, be aware of targeting images that are inside a cropping container as this might crop the ad too. Speak to your account manager if in doubt as we will be happy to help with targeting setup.
# Core Web Vitals
Source: https://docs.contentignite.com/publishers/tag-core-web-vitals
CWV's represent industry defined performance metrics
Core Web Vitals (CWV) are a group of universal metrics that inform on the overall performance of a site. These metrics have an effect on how your site is perceived by users and by search engines alike.
Advertising in general will effect CWV's as an unavoidable consequence of making network requests to fetch ads, running auctions (header bidding) and downloading various assets such as ad creatives. Sites need revenue to operate, and for most, that revenue comes from some form of advertising, so while building a new site its easy to be disappointed to see those perfect CWV scores decline once advertising is activated, but it is a balancing act, as a site with no income can't operate for long!
Content Ignite is dedicated to minimising the impact we have on a site, there are some areas we can control and some we can't, so lets take a deeper dive:
## CLS, Ad containers & targeting flexibility
We have the ability to target ads to any area of your site without any dev requirements on your side, this is incredibly powerful and allows the flexibility to experiment with ad position and refine over time, for example; targeting ads after every 5th paragraph inside articles.
That being said, CLS (Content Layout Shift) is a core web vital that is commonly tracked by publishers, so how do Content Ignite ads effect this? As with any third party script you place on page, we aren't present the second your site loads, browsers load us just after page load, so there is no way for us to directly prevent CLS for content we place on page, however that doesn't render our flexible targeting void!
CLS is about shifting content around that is in the primary viewport (aka whats in view of the user). Our recommendation is to set fixed sized ad containers for your known units, such as billboard/leaderboard header units, MPU in the side bar etc, anything that is in that initial viewport. This prevents CLS as we can place an ad inside this container. You can then leave us to flexibly target article content, end of article etc.
Remember that our high impact Adhesion and In-image units never effect CLS.
## General Performance, TTI
Our tag operates asynchronously, meaning we don't block the page from loading, ensuring we don't effect the all important Time to First Interaction.
## Network request and Bandwidth
The Content Ignite scripts are carefully built for each publisher, optimising for the specific features and configuration you have set up. For example, if you don't set up header bidding or video units, we wont include those files, which contribute to over all file size.
We compress our scripts and serve them from a globally distributed CDN to ensure our files download quickly no matter where your users are browsing from, and often see lightning quick file lookup speeds of around 40 milliseconds.
### Third party scripts
As much as we tightly control our own scripts, we don't have control over required third party scripts such as Googles Publisher Tag scripts (gpt.js and pubads\_impl.js). These are scripts that handle the final ad auction and are controlled by Google, but are often flagged for having unused code.
The same goes for ad creatives. Programmatic advertising means no prior knowledge of the winning creative, so the content of that ad (images, scripts) are out of our control. We push for quality by optimising for yield, which will help, but we can not optimise the assets that a winning ad loads.
# Publisher Tag Deployment
Source: https://docs.contentignite.com/publishers/tag-deployment
Get your Publisher Tag to page once, and manage the rest inside Fusion
There are two primary ways you can deploy our tag on your site; direct on page, or via an ad server.
## 1. Tag-on-page - Recommended
Direct tag on page deployment is the most flexible integration method, a “do it once and forget about it” option. By deploying directly on the page you can amend your units at any time inside our platform without making any changes on your end. This method also offers the quickest load speeds and minimises resources and impact on your site.
You will be provided with a script tag during onboarding. It is as simple as inserting this tag in the `` of your site after your CMP Stub.
Learn more here: [Getting Started: Going Live](/getting-started/going-live)
### Via WordPress plugin
We offer a WordPress plugin for quick integration with WordPress sites, search for "Content Ignite" or follow this link: [https://wordpress.org/plugins/content-ignite/](https://wordpress.org/plugins/content-ignite/) to install the plugin. Activate the plugin, navigate to the settings page and insert your UID then save to activate.
### Via a 3rd party service or Ad Server
You can also use a service such as Google Tag Manager to deploy our script. Or serve our tag onto your page via a “1x1 unit”, from your ad server, for example through GAM. This will add a slight delay to the initial loading of ads but maintains the other benefits of a direct deployment.
"Ad Server Integration" code is available on each publisher page, along with "Tag-on-page Integration" for easy reference.
## 2. Ad Server - Single-serve unit
Note: Serving multiple units to your page via this method increases the resource demand. If you require multiple units, consider the much more flexible and efficient “Tag-on-page” method detailed above.
If you need to load a single unit, via an ad server, sandboxed in an iframe and targeted by your ad team, you can do so by adding our tag as a custom creative.
In these cases, and in addition to the script tag, we will provide you with a `div` to include.
Simply include these two elements in a custom creative and serve accordingly.
# Publisher Tag Targeting
Source: https://docs.contentignite.com/publishers/tag-targeting
On web we target units with CSS selectors and use filters to refine it
## Positional Targeting
On-page placement of an ad unit is achieved via CSS selectors. You will need to be able to look at your website's HTML and pick the elements you want to target, and using your knowledge of CSS selectors be able to uniquely identify them in code.
Don't worry if all of this sounds alien, CSS Selector-based targeting is highly flexible, but requires an experienced web developer to implement. If you don't have a web developer on your team, a member of our team will be available to help!
### Advanced CSS selectors
Most of your targeting will use basic CSS selectors, as shown in the example tables below. These consist of using classes and IDs to identify and target your desired page elements. However, we support a large range of more advanced selectors, one useful one you may find helpful is the `:nth-child` selector.
These types of selectors allow you to do useful things such as targeting every 3rd paragraph on an article page (`.article-page p:nth-child(3n)`). Or targeting every 4th paragraph starting with the 1st (`.article-page p:nth-child(4n-7)`)
More information on `:nth-child` selectors can be found here: [https://css-tricks.com/useful-nth-child-recipies/](https://css-tricks.com/useful-nth-child-recipies/).
It is also worth noting that you can include multiple selectors in a single config by simply using a comma, no need for multiple configs!
**CSS Extension**
We have implemented an extension to CSS to allow for index selection of matches, this is the `:eq(n)` selector, where `n` is a zero indexed number. For example, if you've got a list of blog posts listed on a category page, mixed in with other containers, it can actually be very hard to select the "second match" of a given class, because CSS selectors like `nth-of-kind` always count from the first element, not the first "matched" element.
In this example, we could use `.blog-post:eq(1)` to select the second match! (With zero indexing, the first match is `0`, second is `1` etc).
**Helper Classes & Unit Dependencies**
When targeting configs to your page, you can make use of helper classes that are automatically added to the body of the page, or to create dependencies between units, or react to unit state.
We add the following helper classes to the body of the page, which can be used in your CSS selectors:
* `ci-{CONFIG_ID}` - added when at least one target match of the given config is present on the page.
* `ci-{CONFIG_ID}-open` - added when at least one of the given config's units is open on the page (e.g. adhesion unit is expanded, or in-image unit is visible in the viewport).
* `ci-{CONFIG_ID}-empty` - added when there are no available ads to serve for the given config, and therefore the unit is not shown.
With these you can accommodate for various scenarios, for example: Say you have a unit on page that serves skin/takeover ads, say config ID 1, and you have two skyscraper units on page that you only want to load if there is no skin/takeover available, you could add the targeting class `ci-1-empty` to the skyscraper configs, meaning they would only load if there are no skins/takeovers available.
For more complex setups, such as waiting for another unit to miss or waiting for an external page process to complete, see the [Unit Dependencies guide](/publishers/unit-dependencies).
### In-Image Examples
| Type | Selector | Example Notes |
| ----------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| class + img | `.post_content img` | To target the contents of an element (div, span etc) use class (.) In the example you would be targeting all `` tags, inside of the element `` |
| id + img | `#content img` | To target the contents of an element (div, span etc) use id (#) In the example you would be targeting all `` tags, inside of the element `` |
| class | `.post_content` | To target the contents of an element (div, span etc) use class (.) In the example you would be targeting all `` elements |
| id | `#content` | To target the contents of an element (div, span etc) use class (#) In the example you would be targeting all `` elements |
### In-Article Examples
| Type | Selector | Example Notes |
| ----------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| class + tag | `.post_content p` | To target the contents of an element (div, span etc) use class (.) In the example you would be targeting all `
` tags, inside of the element `
` |
| id + tag | `#content p` | To target the contents of an element (div, span etc) use id (#) In the example you would be targeting all `
` tags, inside of the element `
` |
| class | `.post_content` | To target the contents of an element (div, span etc) use class (.) In the example you would be targeting all `` elements |
| id | `#content` | To target the contents of an element (div, span etc) use class (#) In the example you would be targeting all `` elements |
## Device Targeting
You can also target individual configs based on device type (mobile, tablet or desktop), or any combination thereof. Simply select the devices you need, simple!
This opens up a huge range of flexibility. Want a video unit that sticks on desktop & tablet, but not on mobile? Easy. Create one config with desktop & tablet selected and sticky enabled. Duplicate the config and select just mobile while disabling sticky.
Use as many individual configs as you need to achieve your desired setup!
## Geographic Targeting
Target countries easily by including or excluding them as required. Target fallback creatives to better match the audience or tailor your ad stack!
## Browser Targeting
You can target any of the top 7 browsers, representing 95% of all internet traffic. This is great for trialling different ad stacks for the likes of Safari with its intelligent tracking prevention features, vs others.
## Viewport Targeting
While device targeting as described above allows for quick and easy targeting of key device widths, viewport targeting offers highly customisable width targeting to perfectly match your sites custom breakpoints.
If your site has a special wide breakpoint such as anything equal to or above 1400px, you can easily target this with a value of `≥1400px`.
This field will accept up to two values; a start value and an end value (to capture a breakpoint range), or just one value with an open start or open end (see example below).
All values will be assumed `px`, pixels. We accept the following comparison operators:
* `>=` Greater than or equal to.
* `<=` Less than or equal to.
* `>` Greater than.
* `<` Less than.
Remember to enter your viewport declaration in to the field and hit enter to commit it, you can then add a second one if required, hitting enter again.
### Examples
1. `<576px` -- Open start, so anything from 0 up to a maximum of 575px
2. `≥576px` -- Open end, so anything from 576px upwards
3. `≥1200px`,`<1400px` -- Range, anything from 1200px up to 1399px
## URL Path Targeting
We also support config targeting down to the URL path. Only want adhesion on article pages? Want to try out a new config on a single old article? Not a problem!
URL path targeting is done via one of two behaviours; include or exclude.
Selecting "include" enables the config on all pages that match your list of URL paths. "Exclude" enables the config on all pages that **don't** match your URL path list.
Matches are made against the URL path, the bit highlighted in green here:
[https://docs.contentignite.com](https://docs.contentignite.com)/publishers/tag-targeting/
\#advanced-css-selectors
So to match the above URL, the target would need to be `/publishers/tag-targeting/`.
### Wildcard Matching
We also support wildcard matching where you'd like to match against URL path patterns.
For example, take the following common URLs where there is a category and a post name in the URL:
*
[https://the-race.com/formula-1/aston-martin-f1-chief-szafnauer-exits-team/](https://the-race.com/formula-1/aston-martin-f1-chief-szafnauer-exits-team/)
*
[https://the-race.com/formula-e/formula-es-new-qualifying-format/](https://the-race.com/formula-e/formula-es-new-qualifying-format/)
*
[https://the-race.com/motogp/what-to-expect-from-petruccis-dream-dakar-switch/](https://the-race.com/motogp/what-to-expect-from-petruccis-dream-dakar-switch/)
What if we wanted to match all "formula-1" articles on this site? This is where the wildcard character comes in; `*`, it matches any number of characters.
To target *"formula-1"* articles, we can simply use the target:
```
/formula-1/*
```
We always match from the start of the path to the end of the path. In this case, the wildcard character matches anything after `/formula-1/`, therefore matching any articles within that section as they start with `/formula-1/` and end with any other characters.
Also, consider the following URLs:
*
[https://the-race.com/formula-e/results](https://the-race.com/formula-e/results)
*
[https://the-race.com/motogp/results](https://the-race.com/motogp/results)
We could easily target all result pages with:
```
/*/results
```
In this case, (because we match from the start to the finish) the wildcard character matches any characters at the start of the URL path, and then we match `/results` at the end of the URL path.
Combine wildcard matching with the ability to add as many entries as needed and you can tailor advertising across your site in an incredibly flexible way, down to a hyper-targeted level.
**Something or nothing**
Please note that `*` matches *anything*, including *nothing*. If you'd like to match "something" like any subsection under `/section/`, use a double wildcard like so: `/section/**`
### Additional Examples
# Publisher Tag - Video Unit
Source: https://docs.contentignite.com/publishers/tag-video
A video unit designed to server your supplementary content
Our video unit is an in-stream unit, this means ads are served alongside a video of the publisher's choice. Allowing your site to host engaging video content for the user, supplemented with ads.
Like all our units, video has several configurable options that you as a publisher have ultimate control of:
## Video content
The content that is served to the video units is controlled in the separated [Video Configs](/publishers/video-config) section of your dashboard. This allows you to set various settings such as enabling auto-content and running that across various publishers in one fell swoop. Leaving these unit configs for video, to control just the behaviour of the unit such as when and where it is served.
Why not tie video content and unit config together? It's incredibly flexible having the two separate and reduces duplication (and therefore the chance for human error). Consider these scenarios:
1. A sponsor provides a video to run in a certain section of your site, you have one video unit running across your site so to do this you can simply create an audience for the target section of your site, and create a new video config to target that audience with the sponsor's video file. Video serving across the rest of your site remains unaffected and the video unit doesn't have to be changed in any way.
2. You've got your video serving set up via a single network-wide config, but you want units in different places in different sections of your site, with different behaviours for mobile vs tablet/desktop. You can set up as many unit configs as needed to achieve this while defining the content that will serve to all those different unit setups in a single video config.
## Behaviours
Our unit has three distinct behaviour types as explained below. Regardless of the chosen behaviour, we take steps to ensure a users experience is not diminished by our ads, and that advertisers are treated fairly, to this effect we implement intelligent "Auto pause" functionality, to pause videos when scrolled out of view; avoiding frustrating background audio for users and ensuring high viewability for advertisers (and more revenue for you!).
In addition, our video unit never hides or collapses after being shown, preventing disruptive content shift.
Only one video unit can be loaded per page - less is more in this case!
Be sure to check out "Click-to-stick" for publishers concerned about the impact video ads have on user experience.
### Static
This is how you'd expect any standard video element to behave on the page, it stays where you put it; completely non-intrusive.
### Scroll-to-stick
This is what is commonly seen in the advertising industry; a unit that sticks to a corner of the page as the user scrolls past the inline element, keeping it in view at all times. High viewability stats often lead to great revenue, hence it's commonplace, but potentially at the detriment of the user's browsing experience.
#### Stick-on-load
For all our behaviours, our "in-view" tech is enabled and can not be turned off, except for Scroll-to-stick. Here you get the option to disable in-view. This allows for Stick-on-load behaviour where the video will load and stick to the position of your choosing, as soon as the page loads. This is a highly engaging setup, but it's down to you as the publisher to weigh that up against user experience impact.
### Click-to-stick
This is the Content Ignite hybrid solution. A unit that is static by default, but when scrolling past it, a small floating button appears, allowing the user to pop the video out and continue watching.
This type remains highly viewable for users who want to engage, but stays out of the way for those not interested - ensuring their experience on the site is unaffected by video advertising.
## Position
Chose where a "popped out" video appears. Whether initiated by the user, or via the "Scroll-to-stick" behaviour, you have control of where a floating video is positioned, allowing you to place it somewhere that best fits the design of your site.
## Disable auto-play with sound
We aim for the most engaging behaviour we can to drive good ad revenue balanced against a good user experience. Therefore, the decision on when to play videos with or without sound is given to the user's browser, which has much more knowledge about that user than us (privacy is of top importance to us here at Content Ignite!).
The browser's decision is based on a “Media Engagement Index” MEI. This takes into account how much someone has previously interacted with the site to gauge their interest in a publisher. For most users, this will mean the video will play without sound with the option for them to unmute it at their own convenience.
This is the best balance for the user. If they have actively engaged with the site and have a high MEI, videos may play for them with sound.
Most site owners will be interacting with their site daily, so are likely to hear sound on videos more often, but this will not be the norm for the majority of users.
If however, you have had user complaints or want to take the executive decision to block sound by default and disable MEI control, you can do so via the "Disable auto-play with sound" toggle.
For more information on how MEI works, please visit the explainer here: [Chrome Auto-play, new behaviours](https://developer.chrome.com/blog/autoplay/#new-behaviors)
## Config Flexibility
A general note on the flexibility of the Content Ignite Publisher Tag config setup.
You can create as many configs as needed to achieve your desired setup. Want scroll-to-stick on desktop, but click-to-stick on tablet and mobile? Simply create two configs targeting these two groups and configure as needed!
Want "Always play" enabled on video articles and disabled on everything else? no problem!
There is great flexibility and control afforded to you as a publisher, you can do what is best for your site and your user base.
# Unit Dependencies
Source: https://docs.contentignite.com/publishers/unit-dependencies
Delay selected ad units until another unit or page-level process has resolved
By default, the Publisher Tag is designed to load ads as quickly as possible. Units already in the current viewport, units configured to load out of view, and in-view units that are not blocked by their buffer limits are batched and loaded immediately.
This is the recommended setup for most pages because faster ad delivery usually improves engagement and revenue. Use dependencies only when an ad unit genuinely needs to wait for another unit, or for a page-level process such as authentication, subscription detection, or consent-adjacent publisher logic.
There are two dependency patterns:
* For one Content Ignite unit depending on another Content Ignite unit, use the automatic body helper classes added by the tag. This does not require any publisher development work.
* For a unit depending on an external page process, use a publisher-controlled body class that is added when that process is ready.
In both cases, the dependent unit's CSS selector is prefixed with a class that is not present until the dependency is ready. The tag monitors class changes on `document.body`. When a body class changes, it checks targeting again, finds any newly matching configs, and loads the units that are now eligible.
## Gating a unit with a body class
Say a config normally targets this container:
```css title="Normal targeting" theme={null}
.ad-mpu
```
To make that unit wait, add a body-class prefix in Fusion. For example, if the unit should only load after config `1` has returned empty:
```css title="Dependent targeting" theme={null}
.ci-1-empty .ad-mpu
```
Until the `ci-1-empty` class exists on the page, the selector will not match. If config `1` receives no ad, the Publisher Tag adds `ci-1-empty` to `document.body`, target matching runs again, and the dependent MPU becomes eligible to load.
Body helper classes are added to `document.body`, so they should be used as a
prefix before the dependent unit's normal selector.
## Depend on another ad unit
A common example is a skin or takeover unit. You may want the skin to have the first opportunity to serve. If it does not return an ad, you then unlock one or more fallback units such as MPUs or skyscrapers.
In this example:
* Config `1` is the skin or takeover unit.
* Config `2` is an MPU that should only load if config `1` misses.
* Config `2` normally targets `.ad-mpu` in Fusion.
Set config `2`'s selector to:
```css title="Fallback targeting" theme={null}
.ci-1-empty .ad-mpu
```
No event listener or custom JavaScript is required. The Publisher Tag adds `ci-1-empty` to the body when config `1` has no available ads to serve. Because config `2` only matches after that class exists, it will not load unless config `1` has attempted to serve and returned empty.
You can use the same prefix on multiple fallback configs. For example, both a desktop skyscraper and an MPU could use selectors that start with `.ci-1-empty` if both should wait for the skin to miss.
The available unit-state helper classes are:
* `ci-{CONFIG_ID}` - added when at least one target match for the config is present on the page.
* `ci-{CONFIG_ID}-open` - added when at least one of the config's units is open on the page.
* `ci-{CONFIG_ID}-empty` - added when there are no available ads to serve for the config, and therefore the unit is not shown.
## Depend on an external process
Another common dependency is a client-side user authentication or subscription service.
For example, a publisher may need to pass a subscription state into ad targeting before any ad requests are made. If ads load before the auth service is ready, some requests may go out without the required value.
To avoid that race condition, prefix the affected unit selectors with a class such as `show-ads`:
```css title="Auth-gated targeting" theme={null}
.show-ads .ad-mpu
```
Then, when the auth service is ready, set the targeting value first and add the class afterwards:
```js title="Unlock ads after auth is ready" theme={null}
window.__ciads = window.__ciads || { cmd: [] };
function unlockAdsForUser(user) {
const subscriptionState = user && user.isPaidSubscriber ? "paid" : "free";
window.__ciads.cmd.push(function () {
window.__ciads.setTargeting("subscription_state", subscriptionState);
document.body.classList.add("show-ads");
});
}
window.authService.on("ready", unlockAdsForUser);
```
The important detail is the order: call `.setTargeting()` before adding the body class. Adding `show-ads` causes target matching to run again, so the targeting value should already be queued before dependent units become eligible to load.
Do not use `.setTargeting()` for personal information. Subscription state,
entitlement tier, or a non-identifying audience segment is fine; names, email
addresses, phone numbers, age, gender, or other personal information should
not be passed through targeting.
## Avoid blocking ads forever
If an external dependency can fail, timeout, or be blocked by a browser extension, add a fallback path. Otherwise the gated units may never become eligible to load.
```js title="Auth dependency with a fallback" theme={null}
window.__ciads = window.__ciads || { cmd: [] };
var adsUnlocked = false;
function unlockAds(subscriptionState) {
if (adsUnlocked) {
return;
}
adsUnlocked = true;
window.__ciads.cmd.push(function () {
window.__ciads.setTargeting("subscription_state", subscriptionState);
document.body.classList.add("show-ads");
});
}
window.authService.on("ready", function (user) {
unlockAds(user && user.isPaidSubscriber ? "paid" : "free");
});
window.setTimeout(function () {
unlockAds("unknown");
}, 2000);
```
The timeout value should be agreed with your technical and commercial teams. A short timeout protects revenue and ad delivery; a longer timeout gives the dependency more time to return richer data.
## Implementation checklist
* Gate only the units that need the dependency. Leave unrelated units loading normally.
* For unit-to-unit dependencies, use the automatic helper class for the config being depended on, such as `ci-1-empty`.
* For external dependencies, add the publisher-controlled class to `document.body`, not to the individual ad container.
* If using JS API targeting, set targeting before adding the body class.
* Include a fallback if the dependency is controlled by a third-party or publisher-owned service.
* Test with [ad debugging parameters](/guide/ad-debugging) and browser developer tools to confirm the class is added, target matching reruns, and the dependent config loads.
For more detail on selector targeting, see [Publisher Tag Targeting](/publishers/tag-targeting). For more detail on passing targeting values before external dependencies unlock, see [Setting targeting](/publishers/js-api#setting-targeting).
# Video Config
Source: https://docs.contentignite.com/publishers/video-config
Describe the content and content behaviour of your video unit
Video configs allow you to configure the content that will serve to a video unit on your network. They work alongside unit configs (which control the targeting and behaviour of a video unit) to serve content and ads to your publishers in a highly configurable way.
Video configs can target everything across your network in one go (network default) or go more granular and target specific publishers or audiences. Use as many configs as needed to serve relevant content to your video units.
A simple and fully functional set-up can use a single video config to enable auto-content across an organisation, with optional fallback videos. A more complex set-up may target individual audiences with audience-specific video playlists.
## Auto-content
Auto-content is a powerful system that builds videos on the fly. It allows you to tap into video monetisation without investing in your own video content creation, while also circulating users around your sites!
We either look to your RSS feed for the latest articles, or through our logs for the most popular articles. We then piece together a video using your article's title and feature image along with your publisher branding (logo and display name) to create bespoke video content. For each article shown, a "Read more" button is displayed linking to that article, circulating users around your site with all actions of course viewable from our reporting!
Content is periodically re-generated to keep it up-to-date. Each generated video is viewable from the video config that controls it, so you can always see what we are serving!
*NOTE:* Please allow up to 30 minutes for your auto-content to be built upon the creation or implementation of change.
### Branding
Be sure to set your publisher's display name and logos inside publisher settings if you want these to be added to your auto-content video.
### RSS Feed
If you select the "Latest" content focus, then we will look for the RSS feed set in your publisher settings. This can be any URL, for example, you could use a 3rd party service to curate an RSS feed just for your video content!
**Your RSS feed must contain a `title`, `link`, `pubDate` and `media` or image `enclosure` field.**
### Rendering
Content is periodically re-generated to keep it up-to-date. Each generated video is viewable from the video config that controls it, so you can always see what we are serving.
We can fail to generate content for a number of reasons, so we make every effort to show you the reason for failure in the dashboard. Simply go to the relevant video config and select the target in the "Auto-content preview" section. Videos can fail if there is not enough content found, missing images in your RSS feed, RSS feed errors etc.
Also, be sure to set your publisher's display name (how you would like your brand to be written), and light and dark logos on the publisher settings page, so these can be added to your video.
## Video playlist
You can upload your own video content. This can be used instead of auto-content if you have your own video content/strategy or can be used as a fallback to auto-content if you want to guarantee video ad serving opportunity.
Simply upload your files (or drop in the link to any self-hosted content) and make your selection, dragging items to re-order as needed.
If auto-content is enabled, auto-content will always take precedence, and only fall back to your playlist when needed. See [video config hierarchy](/publishers/video-config#hierarchy).
## Targets
Targets are either the organisation you are logged in as, a publisher, or an audience.
Selecting your organisation means all publishers will inherit these settings by default. This will NOT create an organisation-level video via auto-content but will create one video per publisher where applicable.
Publisher and audience targets act as you would expect. Be aware that each target can only be used in one video config, and that when a page on a publisher's site matches more than one target, the more granular targets take precedence, see [video config hierarchy](/publishers/video-config#hierarchy).
## Hierarchy
You can target video content to your organisation (network default), individual publishers and audiences. Each target can only be used once, and the more granular targets take precedence.
For example, if you have a config set up for your entire network, another for a publisher and another for an audience, if a particular publisher page on site matches all three, the Audience config will be used, followed by the publisher config (if the audience is not matched) then by the organisation config.
```mermaid theme={null}
flowchart TD
start([In-stream unit loads])
ender([No videos to load, abort])
audience1{Audience config match?}
audience2{Auto-content enabled and found?}
audience3([Load Auto-content & loop])
audience4{"Has fallback video(s)?"}
audience5(["Load fallback video(s)"])
publisher1{Publisher config match?}
publisher2{Auto-content enabled and found?}
publisher3([Load Auto-content & loop])
publisher4{"Has fallback video(s)?"}
publisher5(["Load fallback video(s)"])
organisation1{Organisation config match?}
organisation2{Auto-content enabled and found?}
organisation3([Load Auto-content & loop])
organisation4{"Has fallback video(s)?"}
organisation5(["Load fallback video(s)"])
style audience3 fill:#F66F5E
style audience5 fill:#F66F5E
style publisher3 fill:#F66F5E
style publisher5 fill:#F66F5E
style organisation3 fill:#F66F5E
style organisation5 fill:#F66F5E
style ender fill:#F66F5E
start --> audience1
audience1 -- Yes --> audience2
audience2 -- Yes --> audience3
audience2 -- No --> audience4
audience4 -- Yes --> audience5
audience4 -- No --> publisher1
audience1 -- No --> publisher1
publisher1 -- Yes --> publisher2
publisher2 -- Yes --> publisher3
publisher2 -- No --> publisher4
publisher4 -- Yes --> publisher5
publisher4 -- No --> organisation1
publisher1 -- No --> organisation1
organisation1 -- Yes --> organisation2
organisation2 -- Yes --> organisation3
organisation2 -- No --> organisation4
organisation4 -- Yes --> organisation5
organisation4 -- No --> ender
organisation1 -- No --> ender
```
# Releases
Source: https://docs.contentignite.com/releases
Platform release notes
View our major platform announcements here, or dive into each incremental update via our [changelog](/change-log).
## Introducing Publisher Tags
A simple way to group your publishers — and put those groups to work across Fusion.
### Tag your publishers
Pop custom tags onto any publisher and group them by whatever makes sense to you — region, vertical, account team, you name it. Smart suggestions appear as you type to keep things tidy. Head over to any of [your publishers](https://admin.contentignite.com/publisher) settings branding block to start tagging.
### Filter the Insights Hub by tag
Your tags now show up in the same publisher picker you already use — pick a tag (or a few) and your view follows you everywhere. Want to see your UK publishers across every Insights report? One click and you're there. Even mix tags with specific publishers if you want to layer them up.
### Report by tag
Report Builder gets the same treatment. Filter reports by any combination of tags, or add Tag as a dimension to roll your data up group by group.
### Smarter Diagnostics
Diagnostics now flexes to whatever you've picked. A single publisher gets you the full traffic-light deep-dive; a tag (or several publishers) gets you a focused issues table for just that group.
## Introducing bid throttling & more
Tag upgrades from minor improvements to new advanced controls.
### Bid Throttling
A method to remove underperforming SSPs from the Prebid Auction in real time, for a given user. Improve efficiency without impacting revenue. The configuration of this is ripe for experimentation, to find what works for your publishers.
### IAB Curated Audience
Our contextual tech now not only feeds into custom audiences built inside Fusion, but also into pre-defined IAB taxonomies. This happens automatically without any configuration, as long as contextual is enabled (you can also pass your own values if that's your thing!).
### New experiment data
Revenue is not the only important metric when running experiments, and while we previously included viewability, we never showed latency or bid rates… until now!
### New live header bidding visualisation
A new “Header Bidding” chart now shows bid rates broken down by no bids, throttled bids, won bids and lost bids, making it clear how bid requests move through the funnel in real-time.
### A whole load more
From tweaks to improve key-value pass through rates, to more pixel unit controls and better unit sizing defaults to minimise fluid layout impact, this is a great bundle of upgrades!
## Introducing the Benchmarking Insights Hub
See how your data stacks up!
### Benchmarking Insights Hub
Discover how your ad tech setup and performance compares to other publishers in your cohort, as well as the wider Content Ignite network. Our benchmarking tool gives you a clear picture of where you stand and highlights opportunities to optimise and grow.
Explore side-by-side comparisons through enhanced graphical views, all fully configurable using our layered filters, so you can focus on the metrics that matter most to your strategy.
## Introducing Alerts & Notifications
We've opened out our powerful monitoring system to allow direct alerting!
### Alerts
Everything from revenue and traffic drop-offs, to getting notified about each tag re-build, you are in control over your sites and now have time sensitive information at the tips of your fingers to react to events quickly and efficiently.
### Notifications
For the first time, we've introduced web push notifications and integration into your Slack in addition to traditional emails. This ensures the right information reaches the right people in a way that fits their workflow.
### Dashboard & Reporting
You will notice an improved dashboard when you first log into Fusion from now on, better UX and filters to view net vs gross, or P\&P vs SaaS.
You'll also find new fields in the report builder for viewable impressions, cost, revenue source and integration owner, along with improvements throughout Fusion in how we calculate and report on net revenue and how we handle campaign data.
## Introducing Revenue Insights & More
Say hello to the new Revenue Insights Hub - your monetisation data, right at your fingertips.
### Revenue Insights Hub
Get a complete view of your publisher earnings and dig into revenue performance from every angle. With all the powerful filtering tools baked in, it's easier than ever to analyse, compare, and optimise.
Start exploring right away in the [Revenue Insights](https://admin.contentignite.com/report/insight/revenue), or read up on what this new hub has to offer over in [our docs](reporting/insights/revenue).
### Fusion Features
A new warning alert now appears when editing configs tied to live experiments, along with a free text field to add clear descriptions for each experiment.
We’ve added revenue filtering to Metric Insights, so you can now narrow down revenue sources and dig deeper into the data that matters most.
## Introducing Insights Hub
A huge upgrade to Fusion that we couldn't be more excited to introduce. Strap in for one of the biggest and most impactful updates we've released; the culmination of a lot of hard work by our team.
### Insights Hub
Encapsulating a huge total of 9 visual reports designed to provide actionable insight into various key areas.
This is the area you'll never want to leave, bringing you next level visibility on everything from diagnostics, to blending analytics data to deep diving into individual SSP performance.
Read about all the Insights Hub has to offer over in our docs: [docs.contentignite.com/reporting/insights/](reporting/insights)
### System Toolbar
Welcome a new home for key links, new widgets and new ways to navigate. The System toolbar is present on every page and helps declutter the main navigation.
In addition, it houses our new "Ask AI" widget, which searches our docs and blog posts for you, as well as the presence widget, showing you who else is on page along side you.
## Introducing Policy Centre & ID Solutions
As a privacy first company and experts in the stringent data protection laws in the EU, this launch signifies a new standard for approaching ID's in the AdTech landscape.
### Policy Centre
We would never pass on PI to 3rd parties without your explicit consent. Policy Centre firmly puts the control in your hands by centralising terms & activation in one place.
Transparency always remains a core pillar of Content Ignite, and it couldn't be more important than when it comes to ID solutions and personal information.
### ID’s and addressability signals
We are excited to introduce this new integration category. Trial the deployment and activation of RampID, EUID and UID2, with more coming down the tracks.
Tap into the full power of Fusion by running experiments and measure incremental uplift with ease.
## Introducing ID solutions and more
Welcome to a world where ID solutions are given the Fusion treatment, and are as easy to use as checking a box!
### ID’s and addresability signals
We are excited to introduce this new integration category. Trial the deployment and activation of LiveRamp ID solution. Lots more will be added in the coming months.
### Mapping upgrades
Users now have the ability to map centrally inside of organisations, publishers and configs, speeding up onboarding and giving flexibility to work your own way.
## Introducing New Publisher Insights
Introducing powerful new Insight Hubs for Revenue Analytics and Core Web Vitals, all from your redesigned Publisher Dashboard.
### Revenue Analytics Insights
Discover what's driving your revenue with in-depth on-site analytics in our brand-new Revenue Analytics Insight Hub.
### Core Web Vital Insights
Monitor your Core Web Vitals trends that shape user experience, boost rankings, and drive revenue through our handy CWV Insights.
### Extended highlights
Explore the refreshed Publisher Insight view on your dashboard, delivering extended insights for improved performance tracking.
## Introducing Campaign Reporting
Providing powerful insights into the performance of your campaigns.
### Visual Insights
Explore charts and tables to dive into your campaign data and easily track performance over time.
### Fine-Tune Your Filters
Adjust the filters to hone in on the data and get a clearer, more focussed analysis.
## Introducing Experiment Reporting
Providing powerful insights into the outcome of an experiment.
### Visual Insights
See various charts to gauge the success of your changes. Dive into the raw data and track progress over time.
### Auto-activate
Toggle on this new setting to have the winning config enabled automatically upon experiment completion.
## Introducing Fusion Ad Stacks
Changing things up in a big way with Fusion ad stacks and a host more.
### Ad Stacks
Drag and drop in ad demand, Ad Servers and fallback creatives and target them via tag configs. Oh, and connect in your own integrations too!
### Global Search
One central search modal to get anywhere quickly and efficiently.
### Lots more!
Check out our blog post on everything new in Fusion 4.3: [contentignite.com](https://www.contentignite.com/article/introducing-fusion-ad-stacks)
# Notifications & Alerts
Source: https://docs.contentignite.com/reporting/alerts
Fusion can keep in the loop at all times, via your preferred comms method
Each day thousands of events are triggered in our platform, anything from acknowledging the re-build of a Publisher Tag, to urgent health alerts for things like revenue drop-off.
Each user has the ability to receive these notifications via web push notifications or email, or through the [connection of a communications integration](/integrations/comms) at the organisation level.
## Event Group Subscription
You can manage the event groups you are subscribed to from your account page: [/account](https://admin.contentignite.com/account)
The event groups you can subscribe to are as follows:
| Event Group | Email Default? | Web Push Default? | Description |
| ------------------- | -------------- | ----------------- | ----------------------------------------------------------------------------------------------------------- |
| Tag & SDK Updates | ❌ | ❌ | Any changes that trigger a re-build; publisher status change, config change, audience enablement etc |
| Background Activity | ❌ | ✅ | For delayed actions triggered by you, e.g. tag build complete |
| Onboarding | ✅ | ✅ | Any onboarding step; MCM, site approval, publisher appeal, suspensions, new publisher, new organisation etc |
| Health Alerts | ✅ | ✅ | Revenue drop off, traffic drop off |
| Billing | ✅ | ❌ | Invoice Generated, paid, in arrears, new profile set up or removed |
| Experiment Activity | ✅ | ❌ | Experiment end, winner auto activated |
| Ads.txt Updates | ✅ | ❌ | New requirements, now up-to-date |
| User Access | ✅ | ❌ | Includes adding new users, existing users added to new organisations and user suspension |
| Integrations | ✅ | ❌ | Expiry warnings, new integrations added, removed |
| Policy | ✅ | ❌ | Terms have been accepted |
| System | ✅ | ✅ | System notices, such as reporting outages or industry alerts |
| Personal | ✅ | ❌ | \[Non-Optional] Password reset, welcome emails etc |
Be sure to whitelist [no-reply@hey.contentignite.com](mailto:no-reply@hey.contentignite.com) in your email provider to ensure you receive email notifications.
Web notifications will only be delivered if you have Fusion open in your browser. If you'd like more consistent delivery of push notifications, consider [installing Fusion as a web application](/getting-started/top-tips#web-app).
## Organisation Hierarchy
If you have access to multiple organisation, weather that's in a parent-child arrangement, or separate entities, your subscription to the above events is managed per organisation. That means if you switch organisations, you'd be able to manage all your preferences independently.
# API Reporting
Source: https://docs.contentignite.com/reporting/api
Use your own BI systems? Pull in your Fusion data easily with our API
Content Ignite provide a fully open API for all core aspects of our Fusion platform, and this includes reporting.
Anything you pull from your revenue report section, you can pull via API for ingestion into your own reporting systems.
## API Documentation
Our API docs can be found linked in the top right of this docs site, or via this link: [API Reference](/api-reference)
### API Key
You personal API key can be found on your account page inside Fusion: [https://admin.contentignite.com/account](https://admin.contentignite.com/account).
Do not share this token with anyone as it is unique to you and has the same access to Fusion as you do.
## Recommendations
While you can build a report and then pull that report all via API, we recommend that you build the report you need inside the Fusion UI fo ease.
Once built, you will see the report ID in the URL. Simply use this with the `GET report/:id/data` endpoint to pull data daily or as needed.
Reports are only updated once per day from 6am UTC and should generally be complete by 7am UTC.
Reports are reconciled over a 4 day period, meaning data for the past 4 days can change. With this in mind, we recommend you always pull for a 4 day period as minimum, overwriting any previously pulled data.
# Billing
Source: https://docs.contentignite.com/reporting/billing
Simple auto-generated invoices and billing processes
Billing can be found in the primary navigation of the platform. From here you can see your current month's estimate, your billing profile set up and your invoice history.
## Profiles
We allow the set up of two organisation billing profiles; one for paying out and one for collection.
Payouts come from using the Content Ignite ad server within your publisher tags. Our demand fills the ad units and earnings get paid directly to us on Net30 terms, we then pass this on to you the publisher after applying our agreed revenue share.
Collections come from using your own ad server (using our tech on a SaaS basis) or from using our contextual features where we charge you on a simple per-page-crawl basis.
Your account allows you to use any combination of features you wish, you can use our ad server in some places, and your own in others! As you set up various use cases throughout the system, you will be prompted to set up the relevant billing profile if you have not done so already.
### Processing Bills
If you have a mixed set-up where both collection and payout profiles are required, we will calculate the sum of what we owe you, and what you owe us each month. We will then make a single payment in the direction required.
It is important you have both billing profiles in place if requested of you. While it might be the case that your payout total will always exceed your collection total (meaning you will never be charged), invoices can vary month by month and if we can not take payment your account may be disabled.
## Currency Usage
Currency is set as part of your payment setup (you can set the currency your dashboard is shown in separately). We are always looking to support as many countries/currencies as possible, so if you don't see yours on the support list, please do [get in touch](https://resource.contentignite.com/support).
Invoices will always be generated in GBP (our base currency) but will be paid out / collected according to your configured local currency, with the final exchange rate/amount details shown at the time of payment.
## Fees
You will not be charged fees for billing in your local currencies. Exchange values are taken at the time of payment and we use mid-market rates to ensure you get the truest value, no hidden nasties!
You can check out current rates and subscribe to rate notifications here: [https://wise.com/tools/exchange-rate-alerts/](https://wise.com/tools/exchange-rate-alerts/)
## Invoice Parent
If your organisation is configured with child organisations, you can enable "Invoice Parent" on each child. This will mean that the invoice and subsequent payment will be made to you, and not directly to the child.
This trickles down to all children. For example, consider the following setup:
```
Parent Organisation (you)
├── Child 1
├── Child 2
└── Child 3
```
If you enable pay parent on child 2, you will receive invoices and payment for all publishers under child 2 and child 3.
This setting removes all payment setting screens from the child. They will however still see their reporting and will be told that payment will be directed to their parent organisation.
## Collection - SaaS
SaaS fees are calculated off of impressions served.
SaaS pricing is tiered, meaning if you cross a certain ad impression threshold, the CPM cost decreases. This means that reporting partway through the month may show a higher CPM which may decrease throughout the month as more impressions register under a cheaper tier.
Ad impressions are totals at the liable parent organisation level, for example, if you have one parent organisation and multiple child organisations that are all configured to "Invoice parent", then the total ad impressions across all child organisations are used to calculate cost. This ensures you get the best rate through use of the higher impression pricing tiers.
### Supported Currencies
The following currencies are supported for payment collection:
| Code | Currency |
| ---- | -------------------- |
| AUD | Australian dollar |
| CAD | Canadian dollar |
| DKK | Danish krone |
| EUR | Euro |
| GBP | Pound sterling |
| NZD | New Zealand dollar |
| SEK | Swedish krona |
| USD | United States Dollar |
If your currency is not on the above list, please [reach out](https://resource.contentignite.com/support) to us as manual invoicing is available on request.
## Payout - P\&P
Earnings from the use of Content Ignite demand is paid based on an agreed revenue share. For example 85/15 where the larger amount (85%) goes to you, the publisher. You will see the revenue share applied in reporting for the `Net revenue` and `RPM` fields.
### Supported Currencies
The following currencies are supported for the payout of earnings:
| Code | Currency |
| ------------- | --------------------------- |
| AED | United Arab Emirates dirham |
| AUD | Australian dollar |
| BGN | Bulgarian lev |
| CZK | Czech koruna |
| DKK | Danish krone |
| EGP | Egyptian pound |
| EUR | Euro |
| GBP | Pound sterling |
| GEL | Georgian lari |
| GHS | Ghanaian cedi |
| HKD | Hong Kong dollar |
| HRK | Croatian kuna |
| HUF | Hungarian forint |
| IDR | Indonesian rupiah |
| ILS | Israeli Shekel |
| INR | Indian rupee |
| KES | Kenyan shilling |
| MAD | Moroccan dirham |
| NGN | Nigerian naira |
| NOK | Norwegian krone |
| NZD | New Zealand dollar |
| PLN | Polish złoty |
| RON | Romanian leu |
| SEK IBAN Only | Swedish krona |
| SGD | Singapore dollar |
| THB | Thai baht |
| TRY | Turkish lira |
| USD | United States dollar |
| VND | Vietnamese dong |
We are looking to support the following currencies in the future, if one of these is your currency, please [reach out](https://resource.contentignite.com/support) as we may be able to fast-track its integration!
| Code | Currency |
| ------------------ | ------------------ |
| ARS | Argentine peso |
| CAD | Canadian dollar |
| CHF | Swiss franc |
| CLP | Chilean peso |
| CNY | Renminbi |
| JPY | Japanese yen |
| KRW | South Korean won |
| LKR | Sri Lankan rupee |
| MXN | Mexican peso |
| MYR | Malaysian ringgit |
| NPR | Nepalese rupee |
| PEN | Peru Sol |
| PHP | Philippine peso |
| RUB | Russian Rouble |
| SEK Direct Account | Swedish krona |
| UAH | Ukrainian hryvnia |
| ZAR | South African rand |
## Billing Estimates
For each active billing profile, you will see a running month estimate.
Please note, this is just an estimate and does not take accurately into account exchange rates, as these are calculated at the time of invoice processing.
## Net30
We invoice on Net30 terms. We generate invoices on the 6th of each month, that are due 30 days after the 1st of that month (this allows for ad server deductions).
For example, March's invoice would be generated on the 6th of April and will be paid out on the 30th of April.
## Invoice History
The invoice history table will show all the invoices we have issued, when they are due and the current status.
You can click on an invoices description to view further details including a breakdown by publisher.
For non-GBP currencies, you may see an invoice without an exchange rate, exchange rates are fixed once payment has been initiated, at which point the invoice will be updated to reflect this.
### Invoice Life Cycle
An invoice life cycle consists of many different stages, the explanation for which can be found below. If additional explanatory information is available for any given stage, it will be displayed via a little 'info' icon.
| **Stage Name** | **Description** |
| ------------------------ | -------------------------------------------------------------------------------------------------------------- |
| `GENERATED` | Generated internally, but has not been submitted to bank |
| `MINIMUM_NOT_MET` | The minimum payment threshold has not been met. We will attempt to re-process after the next invoice is issued |
| `MISSING_PAYMENT_INFO` | We don’t have payment details on file to even attempt a payment with |
| `PROCESSING` | Processed and submitted to bank |
| `CONFIRMED` | Confirmed by bank as successful |
| `PAID_OUT` | Monies have been confirmed received |
| `CHARGE_BACK` | Payment was cancelled and returned to you by your bank. We will attempt to set up a new payment request |
| `RESUBMISSION_REQUESTED` | We have resubmitted the payment request after a previous failure |
| `CANCELLED` | The payment was cancelled (see reason). We will attempt to set up a new payment request |
| `FAILED` | The payment failed (see reason). We will attempt to set up a new payment request |
| `REFUNDED` | We have issued a full refund\[1] |
| `VOID` | We have voided the invoice, and it will not be reattempted |
\[1] Partial refunds will be issued via a new invoice.
# Campaign Reporting
Source: https://docs.contentignite.com/reporting/campaigns
Fusion conveniently surfaces your campaign reports
Running ad campaigns helps you reach your audience, boost your brand, and drive results. Campaign reporting gives you the insights you need to see what’s working and where to improve, so you can make smart decisions moving forward.
## Campaign Status
View the campaign status at the top of the page next to the campaign name. Campaigns will be labelled as either 'Live' or 'Complete'.
The date range of the campaign is viewable in the top right of the page. 'Live' campaigns are considered as reports posting data up until the previous day, with an end date shown as ∞. When no data appears for the previous day or beyond, the campaign is marked as 'Complete'.
## Campaign Totals
View key statistics, including total impressions, clicks, click-through rate (CTR), viewability and spend for the entire campaign, in the top row.
The CTR measures the ratio of clicks to impressions, showing how often an ad is clicked compared to how many times it’s displayed (impression). A higher CTR percentage typically indicates a more successful campaign, suggesting the ad was more engaging and relevant to users.
## Filters
You can refine the campaign data for more focused analysis by applying certain campaign filters. These allow you to filter by a specific publisher, individual config units, or a custom date range (within the campaign's start and end dates).
## Campaign chart
A line chart provides a visual representation of campaign impressions and clicks over time, offering a detailed view of the data across the selected date range. This helps you assess trends and compare the campaign’s performance.
## Table data
Each table takes the data and groups it into a view that provides a breakdown of the totals from different metrics. These include grouping by line items, config units, creative size, publishers, or device types.
## Data
The data grid is where you will find all the raw data that make up the tables and charts above it. You can export this data, slice and dice it with filters, grouping, sorting and aggregation however you like.
# Dashboard
Source: https://docs.contentignite.com/reporting/dashboard
Your landing page in Fusion, for quick network insights
Your dashboard provides at a glance information for all publishers in your immediate network, designed to help you keep track of the health of your network as a whole, spot trends and set your baselines & targets.
## Onboarding
If you are new to our platform, the first thing you will see is our onboarding banner. This is designed to take you through the system and all the steps needed to get set up, get live and start earning.
Open up the banner to see all your onboarding steps and instructions on how to complete them. We are here if ever you need us, but between our onboarding flow and our docs site here, you are free to onboard yourself at your own leisure.
Once you have completed the core steps, you can continue on to learn about other areas of the system, or dismiss the banner for good.
## Stats
You will see a number of top line revenue stats and performance metrics followed by your performance graph. On this graph, page impressions and ad impressions have been normalised to the revenue line, keeping them close together so spotting what might be impacting revenue is made easy.
Finally, negative and positive trend tables show you your highlights and the publishers you might want to take a look at, followed by your top earners so you always have eyes on the publishers that move the needle.
## Filtering
Our reporting follows a familiar UX across the whole of Fusion, where you can find a publisher filter in the top right, along with a button to access additional filters. These additional filters include switching between Net and Gross revenue, and filtering by revenue source.
## Diving in deeper
Your dashboard is not meant to answer every question you have, it is there for you to keep your finger on the pulse of your publishers. To dive in deeper, use the powerful tabular data reporting of [Report Builder](/reporting/revenue), or explore your data visually over in the [Insights Hub](/reporting/insights).
# Experiment Reporting
Source: https://docs.contentignite.com/reporting/experiments
What insight will you gain from Fusions powerful experiments?
The reason for running an experiment is to gain insight into configs performance, and the experiment report is where you do just that!
## Status & Actions
View the experiment status at the top of the page next to the experiment name. An experiment can be 'Scheduled', 'Live' or 'Completed'.
The date range of the experiment is viewable in the top right of the page, and if live, will show a progress bar representing how far through the experiment you are (percentage shown on hover).
There are various actions you can take during the life of an experiment, available via the action buttons in the top right of the page. Things such as terminating the experiment (if live), or jumping into the experiment configuration page.
### Winner Activation
A major action is activating the winning config. This is a handy shortcut that will terminate the experiment if it is still live, and activate the winning config while deactivating the losing configs. Your Publisher Tag will be re-built and deployed within 10 minutes.
This is an optional action and picks the winner based on the Experiment RPM. If other metrics such as Viewability or fill rate are a consideration for you, then the data should be reviewed and the winner determined independently.
This button will adapt based on the experiment status and winner uplift. Where a small button is shown in a close running, and a large green button shown when there is a clear winner, as you may want to terminate an experiment early to reap the full reward of the winning config.
### Early Termination
A quick way to terminate an experiment early if you feel things are not going well, or that you have gathered enough data to answer your questions. Find out more about this feature here: [Experiments: Early Termination](/publishers/experiments)
## Config Overview
See an overview of each config (name, id, unit type) and details of the experiment setup (weighting and current RPM). Underneath the top-line information is the all-important configuration differences, this highlights what is different between the configs, and ultimately what changes you are experimenting on.
Each config has an assigned colour, that will mary up with the charts further down the page.
## Experiment RPM
A calculation of revenue per 1,000 Ad Unit Loads.
This is the single most important metric in your experiment report, as it gives you a true gauge of the performance of each config, and ultimately, which did/will make you the most revenue.
Experiment RPM takes into account the weighting of your configs, so if you ran an 80/20 experiment split, values would be normalised allowing you to directly compare configs against one another.
## Gross Revenue (cumulative)
This view shows the gross revenue accumulation for each day. This is a great view to visualize how a small gain can add up over time and start to deviate away from a less performant config.
By default, we adjust all values to 100%, meaning that if two configs were set to 50% traffic share, their values would be doubled to real 100%. This allows for forecasting, and make for a fair comparison if traffic split is uneven (e.g. 40/60).
This can be toggled off to show raw revenue values by clicking the green scales symbol in the top right of the chart.
## Gross Revenue (by day)
Similar to above, this chart is the gross revenue total for each day. This can help visualise how close (or distant) your experiment subjects are to one another.
## Viewability
Viewability is a quality metric, where viewable inventory should hold more value. We say "should" because while it makes sense that advertisers wouldn't want to pay for ads that are loaded out-of-view, we often see that OOV units can and do generate more revenue... It goes against all logic and our idealisms as a company, but digital advertising doesn't always concern itself with these things!
We include this metric to give you the insights that will allow you to make informed decisions. If viewability is a priority, then any dip here should be taken into consideration when deciding on a winning config.
## Fill
Fill is a well-rooted metric in the world of digital advertising, but holds less weight these days where less fill can in fact equal more revenue. We at Content Ignite focus squarely on yield, where increasing floors can drive up the value of your inventory and can lead to lower fill, but higher overall revenue. This needn't mean blank ads mind you, as you can backfill with your own creatives and recirculate your users; a win-win!
That being said, every publisher has their own goals, where decreasing fill despite improving yield might not align with those goals for you. So use this chart to keep an eye on things to help inform your decision on the ultimate winner of the experiment.
## Data
The data grid is where you will find all the raw data that made up the charts above it. You can export this data, slice and dice it with filters, grouping, sorting and aggregation to your hearts content. You can even save your view for other report viewers to see.
Use this to inform your next action upon experiment completion.
# Ads.txt Insights
Source: https://docs.contentignite.com/reporting/insights/ads-txt
Refine your Ads.txt file for optimal performance
Our ads.txt hub allows publishers to gather insights and highlight valuable actionable steps that can be taken to ensure your ads.txt file is healthy and maximising your revenue potential.
## What is ads.txt?
The ads.txt (Authorised Digital Sellers) is a simple, text-based file that is defined by publishers to list all the companies authorised to sell their ad inventory. Introduced by the Interactive Advertising Bureau (IAB) and defined in latest [Ads.txt 1.1](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1.pdf) specification, this initiative aims to increase transparency in programmatic advertising, reduce fraud, and ensure that advertisers are buying legitimate ad impressions from approved sources.
Here's a great analogy to help explain what your ads.txt is for:
> Think of ads.txt as your party invite guest list. If your guest list is too long, it will take ages for the party to actually start and also make it hard to manage uninvited gatecrashers. Some guest names might be duplicated and cause more confusion. So a clean guest list will ensure that the party starts early and only the invited guests are admitted without any problems or delays.
## Relationship Types
There are the two relationship types that publishers are able to sell their ad inventory through programmatic bidding systems: **DIRECT** and **RESELLER**.
A DIRECT relationship means the publisher works directly with the AdTech vendor to sell its inventory, whereas RESELLER indicates that the publisher has authorised another ad network/digital ad agency to sell its inventory on its behalf.
This insight provides an overview of the weighting of these two types, along with the percentage difference between them.
At Content Ignite we understand that RESELLER relationships are required for publishers to operate their ad solutions effectively, but do encourage pushing for greater DIRECT relationships where possible throughout your inventory. This can benefit optimising the supply chain, reducing costs and avoid common pitfalls such as [bidflation](https://www.linkedin.com/pulse/bidflation-phenomenon-costing-publishers-millions-christopher-francia/).
## Exchanges
Each ad exchange line in the ads.txt file contains the authorised name/domain that is selling inventory. This insight demonstrates the correlation between how many of those total exchanges are **unique**.
Explore our [exchange insights](#exchange-insights) section to dive deeper and learn more.
## File Lines
Our tool allows you to review all the lines that exist in your ads.txt, listing them each out by type to form the makeup of the entire file. This insight highlights the count and percentage split of these lines to help drill down where improvements can be made to reduce your file, which not only can increase performance, but can directly boost your revenue.
When we crawl the ads.txt. we look for the following:
#### Required lines
These refer to the required lines provided by the demand sources you’ve included in your ad stack, or via any included third party ads.txt lines added under your [publisher settings](/publishers/settings#third-party-adstxt-requirements).
When working directly with us, these should be all you need to get setup and working with no fuss.
#### Untracked lines
These lines are regarded as exchange or variable declaration lines that fall outside of the required lines derived by Fusion. These may include legacy lines left over from previous inventory that now lay dormant.
**Laying dormant**
Dormant lines can pose a serious risk where former partners that are no longer being worked with can access and resell inventory without your knowledge or permission. [Learn more](#number-of-exchanges-pros-cons)
[Follow our guidance](/publishers/settings#third-party-adstxt-requirements) on how to add **active** third party ads.txt lines so they become tracked through Fusion.
#### Duplicates
These include any exchange or variable declaration lines that appear more than once across the file. There are many factors that might cause this to happen, from unauthorised reselling of seller inventory to simple copy-paste mistakes. Whatever the reason, the presence of duplicates may expose a publisher to risk and is a clear indicator that the file isn’t being properly managed.
Using our validation tool, we make it easy to identify these so that you can start getting your ads.txt ‘ship shape'.
#### Comment lines
Comments are optional lines that are useful to help identify blocks of inventory in your ads.txt. These won’t be crawled, however you should be aware that overuse will bloat your file which if not careful could add to latency or load issues.
#### Empty lines
Although empty lines are valid, it is recommended to use these to break up blocks of inventory when needed. This will help to keep the file shorter and quicker to crawl, avoiding weighty files which can impact latency and performance - which may affect overall revenue.
## Your ads.txt file
The next section allows you to drill down and analyse the areas of your ads.txt file in greater detail. It’s purpose is to provide actionable details covering validation of your file to highlighting what lines are required, missing or untracked.
A replicated version of your ads.txt file is presented in a coded text block, allowing you to explore the individual lines, colour coded to match the validation and requirements throughout.
### Features
* Last crawled date to highlight the last time your ads.txt file was analysed 1
* Scrollable code view 2
* Colour coded validation lines with hoverable chips to indicate corresponding line references (duplicates) 3
* Untracked line indicators (•) 4
* Missing lines button - launching a modal to copy missing lines in one go 5
* Instructions on how to add in third-party requirements through the [publisher settings](/publishers/settings#third-party-adstxt-requirements) to track untracked lines within Fusion 6
* Start from scratch button - launching a modal to copy only the required lines to easily replace your ads.txt content in one hit 7
### Validation
Invalid, duplicate or incorrect lines in an ads.txt file can lead to unauthorised ad sales, increasing ad fraud risk, blocking or misdirecting legitimate ads. All leading to lost revenue for you the publisher, and wasted spend for advertisers.
Our validation tool helps to highlight these issues and provide clear feedback on where to clean up your ads.txt file. We look for the following:
* Duplicated lines
* Duplicate variable declarations
* Invalid relationship types that don’t match either DIRECT or RESELLER
* Lines that don’t correctly include all required parts (ad exchange, account ID, relationship type)
* ID’s that are not correctly formatted (letters and numbers)
### Requirements
Based on the requirements for each publisher, we are able to determine between what lines are required, which are missing and which ones are untracked.
Here we are analysing the lines to check each type, highlighting corresponding lines and providing actions to help fix any issues.
#### Required lines
Lines that are correctly present in the ads.txt, highlighted in green in the code view.
#### Missing lines
Lines that are in the requirements but appear to be missing from the ads.txt lines. To ensure revenue is not lost, it is important to review these and add them as soon as possible.
A "LET’S FIX IT" button will enable you to launch a modal where the missing lines can be easily copied, ready to drop into your ads.txt file.
#### Untracked lines
Highlighting (•) any lines that fall outside of the required lines.
## Exchange Insights
The exchange insights gather together all the found exchange lines from your ads.txt and match them against the required lines determined from our ad demand integrations with various SSPs, or via entered third party ads.txt requirements.
From this, we are able to determine the source of each exchange, the relationship between direct vs reseller lines, along with highlighting all the [untracked](#untracked-lines) lines that fall outside of our known ad demand partners.
This information can be valuable in providing additional details about where your inventory is coming from and what relationships they are. The key information that can be taken from this includes:
* Highlighting potential bloating of ads.txt file through unnecessary inventory.
* Indicating possible multiple paths to the same inventory.
* Exposing multiple direct relationships for the the same exchanges.
**Make a positive impact**
Addressing these key points can have a huge impact not only on improving revenue, but driving a more sustainable pathway to reduce energy consumption, operational overheads and your carbon footprint.
#### Features
* The table is grouped by exchange but can be grouped by other columns.
* Aggregation provides total counts for total/direct/reseller values.
* The table provides filtering, sorting, and pagination.
* Export functionality of the data to .csv, excel or print.
* The "VIEW LINES" button provides insight into the corresponding lines from the ads.txt file.
#### View lines
Under each source row, a "VIEW LINES" link will allow you to open a modal view that shows each direct and reseller line for the selected source.
Each line directly corresponds to the line from your ads.txt file for easy cross-referencing.\*\*Note: Duplicate lines are not excluded and will appear in the total
counts and returned viewed lines.
### Number of exchanges: Pros & cons
Modern ads.txt files can contain anything from a handful to thousands of exchanges, but what are the pros and cons of having more or fewer of these exchanges in the mix?
Benefits of having more unique exchanges include:
* Reducing dependence on any single source by providing a wider range of supply sources and benefiting from a broader reach.
* Increasing competition amongst bidders which can result in driving up CPM’s.
* Reducing ad fraud through careful selection of reputable exchanges and greater transparency of who is selling the inventory.
* Potential of targeting opportunities in more specialised niche markets.
Disadvantages of having too many or duplicated exchanges include:
* Slowing down of the verification processes from duplicated ad exchanges can impact real-time bidding and ad-placements, negatively impacting the effectiveness of the overall supply chain.
* Impact on sustainability, with added resources/processes and lengthy supply chains all leading to unnecessary energy consumption and operational costs.
* Increased likelihood of same exchange partners having both direct and reseller relationships, which can lead to bidflation and adding confusion for publishers to determine the legitimate and true source of the inventory.
* Multiple paths to the same inventory decreases transparency in the ad buying process, whilst creating inefficient bidding as the result of advertisers potentially bidding against themselves through different resellers. This ultimately can impact publisher revenue through lost trust and shift in buyer spend through other cost-effective options.
* Diluting the overall quality of your ad inventory through the presence of possible lower quality exchanges, potentially decreasing CPMs and advertiser interest.
* Increased complexity, with greater time management and resources required, along with introducing a higher risk of mistakes, outdated information and errors which can all lead to revenue loss and reduced trust.
## Common Implementation Errors
Here are some key common implementation errors that can be easily overcome through some simple checks and setup. Ads.txt 1.1 provides in-depth [documentation](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1.pdf) on these.
#### Serving through HTTPS
To ensure all crawlers can crawl your ads.txt, making sure your domain is properly encrypted and served as HTTPS rather than HTTP.
#### Missing ads.txt
There can be a few reasons why your ads.txt might appear missing.
* **Its simply missing**
Make sure your ads.txt is being uploaded to your server.
* **Sub vs Top-domain**
Crawlers will typically only look for your ads.txt on the top domain. Make sure it doesn’t sit in a sub domain such as ‘www’ without proper redirects in place.
* **Wrong file location**
Make sure your ads.txt file location is in the **root** directory of the domain and not nested in other folders.
#### Incorrect file format
In order for your ads.txt to be served as the correct Content-type: `text/plain`, the file needs to be formatted and saved as a .txt file.
All other formats can prevent crawlers and systems from finding it, resulting in lost trust, increased fraud vulnerability and lost revenue.
Causes for incorrect file/content types could include:
* Misconfiguration or default content-types on a server level (e.g. not configured to serve file types such as text/plain).
* Redirection or Rewrite rules incorrectly setup/returning as HTML.
* 404 page served for missing files which will be present as an HTML file.
* Saving the file as a different file type.
* Caching old version of the file after changes are made.
## Further reading
If you’d like to find out more information about what ads.txt is, coding standards, formatting, or general best practices: check out these usual sources:
* [IAB Ads.txt 1.1](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1.pdf)
* [IAB Ads.txt implementation guide](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1-Implementation-Guide.pdf)
* [Forbes - How to avoid the pitfalls and loopholes of ads.txt](https://www.forbes.com/sites/augustinefou/2020/10/15/how-to-avoid-the-pitfalls-and-loopholes-of-adstxt/?sh=56a4ec535346)
* [Bidflation, The Phenomenon Costing Publishers Millions](https://www.linkedin.com/pulse/bidflation-phenomenon-costing-publishers-millions-christopher-francia/)
# Benchmarking
Source: https://docs.contentignite.com/reporting/insights/benchmarking
See how you compare with your cohort and the wider network
The Benchmarking Insights Hub is your go-to resource for understanding how your ad tech setup and performance compare with similar publishers and the wider network. By viewing your data alongside peer averages, you can see where you stand within your cohort and spot areas for growth. Comparing with the wider network also helps reveal broader market trends – helping you identify whether changes in performance stem from your own setup or wider shifts across the industry. Use these insights to make smarter, data-led decisions, optimise your ad operations, and get the most out of Fusion.
## Benchmark Groups
To give meaningful context to your comparisons, all metrics in the Benchmarking Insights Hub are evaluated across three benchmark groups. Each represents a different level of comparison, helping you understand your performance from multiple perspectives.
* **Publisher**
That’s you! This represents data for the selected publisher in each section and always reflects aggregated figures based on your chosen filters.
* **Cohort**
Shows averaged data from comparable industry publishers, giving you a reliable comparison that closely matches your audience and setup.
* **Network**
Displays an average across all other active publishers across the Content Ignite network, helping you benchmark performance at a broader scale and spot wider market trends.
## IAB Categories
To link you with other publishers in the same industry — forming your cohort — we use the IAB Content Taxonomy. This standard method defines what your content is about by tagging your sites or sections with IAB categories (like Sports > Football or Tech > Mobile Phones). Doing this helps ensure your inventory is clearly understood across the industry and allows us to group you with similar publishers for more meaningful benchmarking and insights.
## Key Features
* **Benchmark groups** are colour-coded throughout, making it easy to see which data belongs to which group: PublisherCohortNetwork
* Side-by-side comparisons include a to highlight which benchmark group is performing the strongest.
* As with most of our Insights Hubs, you can fully customise your view using the **Filters** drawer – select data sources, dimensions, and specific segments to drill down exactly what you need.
* Related **Insights buttons** are placed throughout to explore data in more detail, keeping all your filters synced as you navigate onward.
* All data is carefully aggregated for your selected date range, so you can compare performance without getting lost in overly complex views.
To make it easier to explore and compare your data, we’ve organised the data into grouped areas, found within each tab. These include:
## Experience
The Experience section highlights the aspects of your ad setup that influence both how your site performs and how smoothly ads load compared with other benchmarks. These cover:
### Latency
Comparing the main [Latency](/reporting/insights/metrics#latency-stats) metrics we track against your cohort and wider network
### Ad Density
Surfacing benchmarks for [Mobile Ad Density](/reporting/insights/diagnostics#mobile-ad-density-publisher-issue) and [Heavy Ad Intervention](/reporting/insights/diagnostics#heavy-ad-intervention-publisher-issue), including threshold goals
### Core Web Vitals
Highlighting key user-centric [CWV](/reporting/insights/cwv#metrics-we-check) performance metrics and how these stack up in comparison
## Performance
The Performance section shows how effectively your ads deliver results, comparing key monetisation and delivery metrics against peers and the wider network to reveal how your setup performs and where to improve.
### Revenue
The Revenue section focuses on CPMs to provide a fair comparison across benchmarks, and is split into three areas:
#### CPM
CPM is a core revenue metric that provides a level comparison across benchmarks by normalising revenue, allowing you to fairly compare your performance against your cohort and the wider network.
#### Revenue Opportunity
The Opportunity section highlights how differences in CPM can translate into over or underperforming revenue. Using your impressions and benchmark CPMs, it visualises potential revenue gains or losses through clear bar charts – showing how even small CPM improvements can lead to measurable uplift.
#### CPM by dimension
For a deeper dive, this configurable view lets you see how your top-performing dimensions compare. It also surfaces additional dimensions from your cohort and network that may not exist in your setup, highlighting potential growth areas to explore for boosting revenue.
**Included demand**
This section focuses on **Programmatic** ad demand only, excluding Direct and House campaigns. No other exclusion are made on this data (e.g. includes all unit types etc.)
### Ad Delivery
Through clear side-by-side charts, other metrics from your ad delivery performance is presented, including, [Ad Load Rates](/reporting/revenue#ad-unit-loads-vs-ad-requests-vs-ad-responses-vs-ad-impressions), Click Through Rate (CTR), [Fill](/reporting/revenue#unit-fill-vs-ad-server-fill-vs-fill) and [Viewability](/reporting/insights/diagnostics#viewability-publisher-issue).
## Infrastructure Health
The Infrastructure Health section highlights the key systems behind your ad setup, showing how well things like Ads.txt and consent management are configured and how they compare with peers and the wider network.
### Ads.txt
Every Ads.txt file can be uniquely configured, but comparing key metrics can reveal opportunities for improvement. We focus on two main areas:
**Relationship Weighting**
See how your percentage of **Direct** demand compares and if there's room to optimise your ad setup. [Learn more](/reporting/insights/ads-txt#relationship-types)
**Unique Exchanges**
Check whether you have a healthy balance of [unique exchanges](/reporting/insights/ads-txt#exchanges), and how this stacks up against your cohort and the wider network.
Winning here doesn’t necessarily mean your Ads.txt file is optimised and
error-free, so be sure to check out our [Ads.txt Insights
Hub](https://admin.contentignite.com/report/insight/ads-txt) for a full
report.
### CMPs
This view focuses on [CMP Rates](/reporting/insights/diagnostics#cmp-status-graph), showing how your performance compares with both your cohort and the wider network. Since your audience should be similar, outperforming peers with higher consent rates can be a key driver of stronger monetisation.
Further reading on CMPs can be found [here](/getting-started/cmp-guide).
## SSP Partners
The SSP Partners section provides insight into how your SSP partners are performing, including overall [bid rates](/reporting/insights/ssp#glossary) and a detailed SSP-by-SSP breakdown. Comparing these metrics with your cohort and the wider network helps you spot gaps, identify top-performing partners, and uncover opportunities to optimise your bidding strategy.
### Bid Overview
The Bid Overview combines all SSPs in the mix to show how the bid stream flows across each benchmark group, highlighting which performs best based on win rate. The view follows the [bid funnel](/reporting/insights/ssp#the-bid-funnel) from requests through to winning bids, with [revenue efficiency](/reporting/insights/ssp#glossary) plotted for each group to identify the most effective SSP demand setup.
### SSP Rate Distribution
This view uses scatter charts to plot each SSP by bid and win rates, with circle size representing bid volume. It helps you see how individual SSPs perform in your setup compared with your cohort and network, highlighting potential gaps and opportunities.
### SSP Performance
The SSP Performance section takes a closer look at each SSP in your mix, presenting key bid metrics – such as bid rate, win rate, bid value, win value, and revenue efficiency – across the publisher, cohort, and network benchmarks. Each SSP is shown as an interactive card, with bar charts visualising performance for quick comparison.
You can sort the list by the metric that matters most to you, giving a clear, top-to-bottom view of how each SSP performs within your setup. Alongside your own partners, you’ll also see other high-performing SSPs from the cohort and network that aren’t currently in your stack – highlighting potential opportunities to expand and optimise your demand mix.
# Core Web Vitals
Source: https://docs.contentignite.com/reporting/insights/cwv
How do your CWV's stack up?
The Core Web Vitals Insight Hub gives publishers the tools to track and analyse Core Web Vital data over time through clear graphical views.
## What are Core Web Vitals (CWV)?
Core Web Vitals (CWV) are a set of user-centred performance metrics that measure key aspects of a website's experience: how quickly a page loads, how responsive it is, and how stable the content is. The aim is to ensure an engaging and enjoyable user experience.
For publishers in the ad industry, CWVs are crucial as they can directly impact both user experience and search engine rankings, both key factors in driving traffic and maximising revenue. The longer publishers can keep users engaged on their site, the more likely they are to see and interact with more ads.
Fusion tracks these important values on every page load, providing publishers with accurate, actionable insights to enhance site performance and maximise revenue.
## Our focus on CWVs
We take special care to be as minimally impactful of CWVs as possible, however digital advertising is generally going to bring down CWV stats when compared to your site with no advertising at all. Its all about the balance of revenue vs impact.
Learn more about what we do and what you can do to maximise site performance in the context of advertising over on our [Core Web Vitals publisher guide](/publishers/tag-core-web-vitals).
## Metrics we check
* **Cumulative Layout Shift (CLS)**
CLS tracks how much a web page's content unexpectedly shifts while loading. Unexpected movement of a page’s content can disrupt the user experience and lead to annoying and sometimes damaging misclicks. A low CLS indicates a stable page layout, enhancing user satisfaction and trust, and leading to longer site visits.
* **Largest Contentful Paint (LCP)**
LCP reports the time it takes for the largest visible image, video, or text block to render in the viewport when a user first navigates to the page. Quicker load times can create a positive first impression and increase engagement, reducing bounce rates from users.
* **Interaction to Next Paint (INP)**
INP assesses a page’s overall responsiveness by measuring how quickly it responds to user interactions, such as clicks, taps, and keyboard inputs, throughout the user’s visit. The final INP value is determined by the longest interaction found, ignoring outliers.
The less a page lags and the quicker it responds to user interactions, the less frustration there is. This increases the chances of longer engagement and the likelihood of ad viewability and interaction.
* **First Contentful Paint (FCP)**
FCP is the measurement of how quickly the first piece of content (text or images) appears on the screen when the page starts loading.
A quick FCP increases the perceived reliability with the site and reassures users that the page is loading. Both factors likely increase the chances that users will stay and potentially see and interact with ads.
Each graph provides benchmark line indicators for both good and poor to represent the healthy ranges. This allows publishers to monitor performance over time and compare it against industry recommendations.
## Additional Insights
Layered on top of each CWV metric, Fusion offers insights into how the absence of header bidding, execution, and ad requests may impact performance, helping publishers understand how ad serving can influence their Core Web Vitals.
## Date Filtering
Using the date filter functionality, the results can be tailored to display data over a range of preset or custom date ranges, allowing for more precise analysis.
## Useful Resources
* [Core Web Vitals](https://web.dev/explore/learn-core-web-vitals?hl=en) - Web.dev
* [Best Practices: Improve Core Web Vitals](https://docs.sourcepoint.com/hc/en-us/articles/11108155226131-Best-Practices-Improve-Core-Web-Vitals) - Sourcepoint
# Demand Mix
Source: https://docs.contentignite.com/reporting/insights/demand-mix
Analyse your mix of programmatic and direct demand
The Demand Mix Insight offers a detailed breakdown of how your ad inventory is distributed across various demand sources. Whether you're using your own Ad Server setup (SaaS) or leveraging our Fully Managed/Plug & Play Ad Demand, this insight shows the flow of revenue across each source, allowing for easy comparison and deeper analysis. It also provides visibility into how your impressions, fill rate, and viewability are distributed, with the ability to break these down further by different dimensions, helping you monitor performance and make informed decisions for optimising your ad setup.
Here are the key tab views found in the Demand Mix Insight Hub:
## Overview
The Overview tab brings together the demand split of your ad setup into a single view. This includes:
### Splits
Consolidated into a visual breakdown, the Splits section allows you to view the revenue from each of your demand sources, both through a pie chart and detailed breakdowns by revenue and percentage share.
The first division breaks demand into either Publisher or Content Ignite, based on the Ad Server setup. In a P\&P or Fully Managed setup, most demand will flow through Content Ignite, while in a SaaS setup, demand will lean toward Publisher. This split indicates how your ad setup is configured and may show where Content Ignite is included as a second look.
The second-level split breaks down the demand further, showing the proportion of revenue coming through as Direct, Programmatic, or Fallback[^1]. Through the use of colour, we provide a clear visual relationship between these demand sources, which is reflected throughout the various views.
### Charts
The chart views provide a visual representation of the demand mix splits for Revenue, Impressions, Fill Rate, and Viewability across the different tab views. These charts make it easy to identify performance trends, spot patterns, and compare how each demand source is performing. They also highlight potential opportunities that could arise from increasing demand in specific areas.
## Dimension Views
Each dimension view — Partner, Channel, Advertiser, and Platform — allow you to break down the demand mix even further, giving you a clear view of which dimensions are out-performing others across the same four metrics. For even more detailed insights, you can filter by a specific dimension to track performance over time on a specific level.
## Campaigns
The Campaigns tab enables publishers to identify the source of direct campaigns, indicating whether they originated from the Publisher or Content Ignite. It allows you to analyse the spend attributed to each campaign as well as the impressions generated. This insight helps measure the success of campaigns across the two demand sources, providing valuable data for future campaign decisions. A table view further allows you to explore individual [campaigns](/reporting/campaigns) in greater detail.
## Filter Options
As with other Insights Hub pages, the global filters for Publisher and Date will influence the data being viewed. In addition to these, there are several page-specific filters to further refine the data displayed.
### Ad Server Grouping
The demand data is split not only by demand type (Direct, Programmatic, Fallback) but also by the demand source (Publisher or Content Ignite). The Ad Server Grouping filter allows you to combine these two sources into a single view, giving you the option to focus on just the demand types without breaking down the data by Publisher or Content Ignite. This is particularly useful when you want a broader, less granular view of your demand distribution, or when comparing how different types of demand are performing across the entire setup.
### Dimension Filter
For each dimension-specific tab view, a Dimension Filter dropdown lets you select a specific dimension to focus on. This will update the chart to show data split across the selected dimension over the chosen date range, rather than providing a comparison of all dimensions. This feature is useful when you want to track trends for a single dimension over time, helping you identify patterns and changes within a specific area of interest (e.g., a particular partner, channel, or advertiser).
### Further Fine-tuning
Along with global filters for Date and Publisher that influence the data, Demand Mix Insights offers additional flexibility for data presentation. You can toggle between Gross and Net revenue views, depending on your preference. Graphs can also be adjusted to show totals or percentages, allowing you to analyse performance in different ways. Furthermore, filter exclusions allow you to toggle chart overlay lines, providing more control over how the data is displayed, helping you focus on the most relevant insights.
[^1]: Unassigned demand will show as an "Untracked"
# Diagnostics
Source: https://docs.contentignite.com/reporting/insights/diagnostics
A central place to identify common pitfalls in your setup
The Diagnostics Hub is designed to highlight any issues that we know will affect monetisation. Through our years of experience dealing with these issues, we are well-equipped to detect and remedy them alongside you.
When you first land in the diagnostics report, you will see a network-wide view of issues, known as your "Network Health".
By choosing a single publisher via the publisher filter in the top right, you will then see a "Publisher Health" view. This provides a deeper dive into nuanced publisher issues, such as a missing CMP Stub, presented via a simple traffic light tile system.
**Data freshness**
Most data is pulled daily, especially for things like analytics data, CMP, or ads.txt data. However, there are a few exceptions. The following publisher tiles are real-time, where a fix on your side should reflect upon a page refresh of the Diagnostics Hub: Stub Status and Expired Integrations.
## Issues
Depending on whether you've selected an individual publisher or are viewing issues across your network as a whole, you may see a number of different issues highlighted to you:
### Drop-off Issue (Network Issue)
A drop-off issue means a publisher's impressions have dropped off by 75% or more over the past 24-hour period. If unexpected, this could indicate that tags have been removed or there is a configuration issue. Something worth looking into!
### Ads.txt Issue
A missing Ads.txt entry can have big consequences on ad serving and therefore revenue. Always aim for zero reported Ads.txt issues and chase anything highlighted!
Learn more about your Ads.txt file in the [Ads.txt hub](reporting/insights/ads-txt).
### Incomplete Supply Chain (Network Issue)
This refers to a specific missing line in your Ads.txt. While all missing Ads.txt lines will impact ad serving and revenue, this line (typically containing `sid-` in the middle of them) will have an increasingly negative impact.
Ensure your ads.txt is up-to-date to resolve these issues.
### CMP Not Found (Network Issue)
If we cannot detect a CMP in a GDPR or CCPA region, we will default to non-personalised ads, which have a much lower CPM. Ensure you have the CMP 'Stub' in place, directly in the head of your page (not served via a tag manager). Any queries, just reach out to your account manager who look into any potential issues for you. Learn more in our [CMP Guide](/getting-started/cmp-guide).
### Tag Latency
Tag latency measures how long it takes for your site to load our tag onto the page. In advertising, it is key to load ads as quickly as possible, before the user scrolls past the unit target or even navigates away to another page.
The best way to deploy our tag is to have it directly in the head of your site. Any other method, such as using a tag manager or serving via an ad server will introduce latency, impacting your earnings.
### Traffic Stats (Graph)
The traffic stats graph merges your analytics data (if connected) with your Publisher Tag data. Typically, Analytics page views will be lower than Content Ignite Page Impressions due to filtering of bots and invalid traffic by your analytics partner. If Analytics data is higher, it is likely that your Publisher Tag is not deployed to every page on your site, potentially leading to lost opportunities.
### CMP Status (Graph)
It’s important to track consent rates over time. Sudden drops in consent rates often correlate with decreased monetisation. These drops could result from CMP changes, triggering mass re-consent, or issues with CMP implementation.
It’s crucial to note that this consent rate reflects what we as an ad tech vendor are seeing. This provides valuable insight beyond your CMP platform, allowing you to spot issues early with real-world data.
Aim for a consent rate of 80%+, though this can vary by audience type. For example, a tech savvy audience might have lower consent rates.
### CMP Error Rate (Publisher Issue)
If a CMP is implemented correctly, the error rate should be zero. Any higher rate will signal a stub issue or configuration problem with your CMP.
As a reminder, CMP issues cause advertising to default to "Non-personalised", which performs considerably worse in terms of monetisation.
CMPs are a very common failure point; read more over in our [CMP Guide](/getting-started/cmp-guide).
### Stub Status (Publisher Issue)
A 'Stub' is part of your CMP setup, and is the publishers responsibility to implement. It's a small piece of Javascript code, that **must exist** directly in the head of your site.
Missing or incorrectly implemented stubs lead to CMP errors and poorly monetised traffic.
Read more about stubs and common CMP mistakes in our [CMP Guide](/getting-started/cmp-guide).
### Heavy Ad Intervention (Publisher Issue)
HAI is a Google Chrome feature that removes ads from the page if it is found they are making excessive network requests or use too much CPU resource. Once removed, that ad cannot generate any revenue.
While there is little you can do to directly effect this behaviour in the open market, indirectly, a well-built site with healthy user traffic tends to attract higher-quality advertisers, reducing HAI occurrences. Typically, HAI values are around 0.3%.
Source
[https://developer.chrome.com/blog/heavy-ad-interventions](https://developer.chrome.com/blog/heavy-ad-interventions)
### Mobile Ad Density (Publisher Issue)
The measurement for Mobile Ad Density is universally agreed upon, unlike for desktop where there is no single standard.
30% is the cut off here. Anything above this can result in penalties, and will most importantly, impact your sites user experience.
Content Ignite measures both our own contribution to mobile ad density, as well as any third parties. The score displayed in your Diagnostics Hub represents a combination of both, giving you an overview of your total mobile ad density.
### Tag Error Rate (Publisher Issue)
There are a number of possible tag errors that can occur, some of which are less likely to cause notable impact but should still be addressed, while others may indicate more serious issues.
One common error is not serving our tag directly, for example by bundling it into a large JavaScript file via a caching plugin. This not only affects tag behaviour but also violates our terms of service.
Another issue is loading our tag multiple times on a page. Although protections are in place to prevent a secondary tag from loading, it is best to centralise our tag serving in one location to maintain control over your site's ad-serving logic.
### Tag error groups
The Tag Error Breakdown groups similar browser-side errors together so you can see whether an issue is a publisher implementation problem, something Content Ignite should review, or normal user/browser behaviour such as ad blockers and privacy protections.
The impact badge is a guide to how much the error can affect monetisation when it happens often. A low-impact group can still be worth investigating if it is unusually high compared with your network average.
#### Domain mismatch
**Impact:** High **Primary action:** Publisher
* **Description:** The Publisher Tag has detected that it is running on a domain that does not match the publisher or configuration it was expecting. This is common on staging and testing sites, where the production tag is intentionally present outside the live publisher domain.
* **Common causes:** A staging or QA domain is being used, the publisher domain has changed, the tag has been copied to the wrong site, or publisher content has been cloned onto an unauthorised or malicious domain.
* **Actionable takeaway:** If the traffic is from a known staging site, this is usually a non-issue. If the domain is unexpected, the publisher should investigate where the content or tag is being served from and remove it where possible. Content Ignite cannot fix the root cause of cloned or unauthorised sites, but can block tag loading on domain mismatch if malicious activity is suspected. This is not enabled by default because it can also affect normal staging and testing workflows.
#### GPT Load Failed
**Impact:** High **Primary action:** Publisher / user environment
* **Description:** Google's Publisher Tag script did not load or did not become available in time, which can prevent Google Ad Manager ads from being requested.
* **Common causes:** Ad blockers, browser privacy tools, network timeouts, CSP (Content Security Policy) or firewall rules, script optimisation plugins, or delayed/deferred loading of advertising scripts.
* **Actionable takeaway:** If this is above the network average, check CSP, CDN, firewall, consent and optimisation settings to ensure Google Publisher Tag and Content Ignite scripts are not blocked or delayed. Isolated cases are often user behaviour and cannot be fixed directly.
#### GPT PubAds Unavailable
**Impact:** High **Primary action:** Publisher / Content Ignite
* **Description:** GPT is present, but the `pubads` service is not available when the tag tries to use it.
* **Common causes:** GPT has not fully initialised, the `googletag` object has been overwritten, scripts are running out of order, GPT has been bundled or deferred, or another on-page script is interfering with GPT setup.
* **Actionable takeaway:** Keep the Content Ignite tag and GPT loading path unmodified and avoid bundling or deferring them. If the issue starts after a Fusion config or tag change, ask Content Ignite to investigate.
#### Secure Signal Provider Push Failed
**Impact:** Medium **Primary action:** Content Ignite / Publisher
* **Description:** A secure signal provider could not be registered with GPT. This may reduce identity or privacy-safe signal availability for some demand partners.
* **Common causes:** GPT is unavailable, secure signal APIs are blocked, an identity module is not available, or a browser/privacy setting prevents the signal from being used.
* **Actionable takeaway:** Content Ignite should review the relevant identity or ad-tech integration if this is persistent. Publishers should check that GPT and related scripts are not blocked by CSP, consent rules or optimisation tools.
#### Prebid BidsBackHandler Failed
**Impact:** High **Primary action:** Content Ignite
* **Description:** Prebid returned from auction but failed while processing bidder responses, which can stop bid targeting being applied correctly.
* **Common causes:** A bidder adapter error, malformed bid response, incompatible Prebid module, unexpected missing object, a custom Prebid configuration issue, or creative blocking from an integrated security provider. Security providers may block malicious creatives or creatives on a block list, such as gambling creatives, which can interrupt normal ad handling and cause errors further upstream.
* **Actionable takeaway:** Content Ignite should review the Prebid build, bidder configuration, recent ad-demand changes and security-provider blocking activity. Publishers should flag any recent on-page script changes that may interfere with Prebid.
#### Network Request Failed
**Impact:** Medium **Primary action:** Publisher / user environment
* **Description:** A browser network request needed by the tag failed, was aborted, or could not be fetched.
* **Common causes:** User ad blockers, privacy extensions, poor connectivity, browser request cancellation, CSP or firewall rules, CDN interruption, or the user navigating away mid-request.
* **Actionable takeaway:** A small amount is expected and often cannot be fixed. If elevated, check publisher-side CSP, firewall, consent, CDN and script allow-list settings.
#### Window Property Access Denied
**Impact:** Low **Primary action:** User/browser behaviour
* **Description:** The browser blocked access to a `Window` property because the tag or a related script was interacting with a restricted frame.
* **Common causes:** Cross-origin iframes, browser same-origin security rules, sandboxed frames, embedded content, or privacy restrictions.
* **Actionable takeaway:** This is usually normal browser protection and not directly fixable. Investigate only if the rate is unusually high or linked to a specific custom iframe implementation.
#### Prebid Build Load Failed
**Impact:** High **Primary action:** Publisher / Content Ignite
* **Description:** The Prebid build required for header bidding failed to load.
* **Common causes:** Ad blockers, CSP restrictions, CDN/network issues, blocked script domains, an incorrect build reference, or a deployment issue with the requested Prebid bundle.
* **Actionable takeaway:** Publishers should confirm Content Ignite and Prebid script domains are allowed and not rewritten by optimisation tools. Content Ignite should investigate if the build reference or deployment is failing.
#### GPT Slot Definition Failed
**Impact:** High **Primary action:** Publisher / Content Ignite
* **Description:** GPT could not define one or more ad slots, so those units may not request ads correctly.
* **Common causes:** Missing or renamed ad unit containers, invalid unit paths, duplicate unit definitions, page markup changes, GPT not being ready when slots are defined, or an out-of-page format such as an interstitial ad being rejected because Google determines the page does not support that format.
* **Actionable takeaway:** Check that unit containers and mappings still match the Fusion configuration. Content Ignite should review the tag/config if the page markup is correct, especially for out-of-page formats where Google may decide the format is not eligible on the current page.
#### Heavy Ad Intervention
**Impact:** Medium **Primary action:** Content Ignite / market behaviour
* **Description:** Chrome has removed an ad because it exceeded browser limits for network usage, CPU usage, or heavy ad behaviour.
* **Common causes:** Resource-heavy creatives, auto-refreshing creative behaviour, repeated media loading, poor-quality demand, or a user/device under resource pressure.
* **Actionable takeaway:** Content Ignite can investigate demand partners or creatives if this is recurring. Publishers can help by keeping pages performant and avoiding excessive third-party scripts, but some cases are caused by advertiser creative behaviour.
#### Reference Error: Can't Find Variable
**Impact:** Medium **Primary action:** Publisher / Content Ignite
* **Description:** A script expected a JavaScript variable to exist, but the browser could not find it.
* **Common causes:** Script load order issues, blocked third-party libraries, ad blockers, consent gating, deferred scripts, or an integration expecting a module that was not loaded.
* **Actionable takeaway:** Use the detail value to identify the missing variable. Publishers should check site-level blockers and load order; Content Ignite should review any Fusion integration that depends on the missing variable.
#### Type Error: Cannot Read Properties Of Null
**Impact:** Medium **Primary action:** Publisher / Content Ignite
* **Description:** A script tried to read a property from a value that was `null`, usually meaning an expected object or page element was not available.
* **Common causes:** Missing ad containers, dynamic page layouts, lazy-rendered elements, removed DOM nodes, configuration pointing at a unit that no longer exists, or a third-party script returning an unexpected value.
* **Actionable takeaway:** Check whether the affected unit or object exists on the page when the tag runs. Content Ignite should review the Fusion configuration if the page markup is correct.
#### Security Error: Blocked A Frame From Accessing A Cross Origin Frame
**Impact:** Low **Primary action:** User/browser behaviour
* **Description:** The browser blocked a frame from reading another frame because they are from different origins.
* **Common causes:** Standard browser same-origin policy, embedded third-party content, sandboxed iframes, creative iframes, or security-hardened browsers.
* **Actionable takeaway:** This is usually expected browser behaviour and not something to fix. Investigate only if it becomes common after adding a custom iframe, creative wrapper or page integration.
#### Security Error: The Operation Is Insecure
**Impact:** Low **Primary action:** User/browser behaviour / Publisher
* **Description:** The browser blocked an operation because it was considered insecure in the current context.
* **Common causes:** Private browsing, blocked storage, sandboxed iframes, strict privacy settings, mixed or restricted contexts, or browser-level security rules.
* **Actionable takeaway:** Occasional occurrences are normal and usually user/environment driven. If persistent on a specific publisher, check iframe sandboxing, storage restrictions, HTTPS setup and CSP.
#### Unknown or unclassified errors
**Impact:** Low **Primary action:** Content Ignite
* **Description:** The error did not match one of the currently defined groups, so Fusion reports it as either its raw error text or as `Unknown` in live charting.
* **Common causes:** A new browser error format, a newly introduced integration error, or a low-volume edge case that has not yet been mapped.
* **Actionable takeaway:** No immediate publisher action is usually needed. If the same unknown error repeats or grows above the network average, send the detail value to Content Ignite so it can be classified and investigated.
### Viewability (Publisher Issue)
Viewability is a publisher quality metric that measures the ratio of impressions served to those that are viewable, where an ad is considered viewable if 50% or more of it is in view for at least one second.
A high viewability rate is appealing for advertisers, as it assures them that their ads are being seen by users. To help maintain a strong viewability score, utilising features like "In-view" in Fusion is beneficial.
A very low viewability rate could suggest that the "In-view" feature is disabled for certain units or that an element on the page is obscuring the ad unit.
### Expired Integrations (Publisher Issue)
Most integrations in Fusion don't expire unless you explicitly revoke access, but there is one key exception: Amazon's APS integration. This integration expires every three months and cannot be renewed.
If an active integration expires, you may lose access to reporting data or even have the integration removed from your ad stack.
You will receive an email notification two weeks before expiration, but if any integrations lapse, they will appear in this section for your immediate attention.
### Direct Demand Mix (Publisher Issue)
While having direct demand on your site is certainly not an "issue," this tile becomes particularly helpful when reviewing programmatic performance.
If direct spend is taking up a large portion of your inventory, it’s understandable that revenue and performance from programmatic demand will drop.
To better understand where your earnings are coming from, you can refer to the specific report in the [Demand Mix Hub](/reporting/insights/demand-mix).
### Traffic Trend (Publisher Issue)
Ad revenue is directly tied to your traffic. Without traffic, there’s no ad spend (obviously!). Therefore, it’s crucial to monitor how your traffic is performing. If traffic trends downwards, you can expect a corresponding drop in ad revenue.
Our [Revenue Analytics Hub](/reporting/insights/revenue-analytics) does a great job of showing you how we are performing for your given traffic.
# Health Check Report & Score
Source: https://docs.contentignite.com/reporting/insights/health-score
See how the industry sees you!
Each Health Check report (V2) offers a detailed analysis of your website by examining a wide range of metrics, which we combine into an overall publisher health score.
Our Health Score Insight Hub gathers these scores over time, giving you a clear view of your performance trend so you can easily track your progress.
We cover many factors that contribute to good ad technology practices, including performance, implementation, industry risks, and ethical and sustainable practices. We benchmark these against industry best practices, giving you a comprehensive view of your domain's health, along with practical and insightful feedback on how to enhance it - ultimately improving your revenue and monetisation prospects.
Within each individual Health Check Report, explore each section to understand the data, how it's been collected, and what it all means.
The final 'Plan' section, using the Crawl-Walk-Run methodology, will guide you through the next steps, advising you on how to keep improving your health score, with the goal of maximising your site’s revenue potential.
## Exploring the report
As you navigate through our Health Check report you will notice there are a number of handy features that help bring together all the data in both an informative and visual way.
Here’s a little guide to some of these features:
* **Traffic light system**
Throughout each section, we have used a colour-coded system similar to the classic traffic light colours: green, amber, and red.
* **Green** means good (or even perfect).
* **Amber** indicates fair, with some room for improvement.
* **Red** signals poor and in need of improvement.
While thresholds will vary depending on the metric, the colour meanings stay consistent, helping publishers easily spot where they’re doing great and where there may be room for improvement.
* **Benchmarking**
A standout feature of our reports is the graphical charts that visually represent the scores for certain measurements and where the thresholds fall. Additionally, whenever possible, we include the average scores for both the entire network and related cohort publishers, so you can see how your site’s health stacks up.
* **Further links**
Each section will provide a link to the documentation and, in some cases, a link to further insights into the data.
* **Comments**
Our comment blocks are designed to give a quick summary of each section, highlighting what’s going well and what might need a bit more attention. Tied to our traffic light colours, the background of the comments will reflect the section's metrics, making it easy to see at a glance how that section is scoring.
* **“Powered by” badge**
Content Ignite collects and reports as much health data as we can ourselves. However, to make sure we're providing the most thorough report possible, we sometimes use market-leading third-party services. When this happens, you'll see a “Powered by” badge in those sections.
* **Point in time**
Our overall Health Check report, along with each individual report that makes it up, is generated at a specific point in time. This means there may be cases where the data is a bit outdated and doesn’t capture the latest changes or improvements. But no need to worry - new reports can be generated at any time, allowing us to track your progress over time.
* **Save pdf / Print**
We have optimised your report so it can be easily exported as a PDF to save or print at any time.
## Health Score
One of the standout features of the report is the overall Health Score, located at the top of the page. This score is calculated by Content Ignite, taking into account all the metrics throughout the report, and weighting them based on the factors that most impact your setup and performance as a publisher in the ad industry.
Comparing your current Health Score with previous scores (if available) gives you valuable insight into your progress. It shows the points difference and provides an assessment of where your site’s health stands within our network and among your cohort.
By diving into the analysis of each section, you’ll gain further context and identify the factors that might be influencing your score. Plus, you’ll find recommended fixes to help boost your score even further.
## Ads.txt
Your ads.txt file is key to maintaining a trustworthy, secure, and transparent relationship between you as a publisher and the advertisers looking to invest in your valuable ad space. It’s crucial for authorising inventory, protecting your ad revenue, and aligning with industry standards set by the IAB.
In our ads.txt section, we focus on the health of your file, pinpointing where optimisations can be made. This includes flagging any bugs that might be affecting its validity and operation, as well as offering recommendations based on industry standards for direct vs reseller relationships and the number of exchange accounts present.
A clean, concise ads.txt file with only valid exchanges, free from errors, and promoting more direct relationships is the best way to streamline your demand path, ultimately helping you maximise revenue.
**How to improve your score**
1. Start by ensuring your ads.txt file is error-free. Look out for duplicate lines, syntax errors, incorrect formatting, spelling mistakes, and missing fields. Fixing these is a simple but effective way to boost your score.
2. Next, review your inventory for any outdated or unused lines. An ads.txt file cluttered with unnecessary entries can cause various issues, like slowing down the verification process, using up extra computing resources, allowing potential unauthorized reseller access, creating inefficiencies in bidding, and making the file more complex to manage.
3. Finally, optimise your supply path by reviewing your exchanges. Focus on building more direct relationships and using unique exchanges. This approach not only attracts a broader range of supply sources, reducing dependence on a single source, but also increases competition, which can drive up CPMs, reduce ad fraud, and open up access to more specialised markets.
For more detailed insights into your ads.txt file, visit the Publisher Hub (link found in this section) where you’ll find in-depth analysis and further guidance in our [ads.txt documentation](/reporting/insights/ads-txt).
**Useful Resources**
* [IAB Ads.txt 1.1](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1.pdf)
* [IAB Ads.txt implementation guide](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1-Implementation-Guide.pdf)
* [Forbes - How to avoid the pitfalls and loopholes of ads.txt](https://www.forbes.com/sites/augustinefou/2020/10/15/how-to-avoid-the-pitfalls-and-loopholes-of-adstxt/?sh=56a4ec535346)
* [Bidflation, The Phenomenon Costing Publishers Millions](https://www.linkedin.com/pulse/bidflation-phenomenon-costing-publishers-millions-christopher-francia/)
## Core Web Vitals (CWV)
Core Web Vitals (CWV) are a set of user-centred performance metrics that measure key aspects of a website's experience: how quickly a page loads, how responsive it is, and how stable the content is. The aim is to ensure an engaging and enjoyable user experience.
For publishers in the ad industry, CWVs are crucial as they can directly impact both user experience and search engine rankings, both key factors in driving traffic and maximising revenue. The longer publishers can keep users engaged on their site, the more likely they are to see and interact with more ads.
Our CWV section analyses four key metrics graphically to show trends over a two-week period, providing an average and giving publishers insight into where improvements are needed by comparing industry benchmarks through our traffic light system.
**Metrics we check**
* **Cumulative Layout Shift (CLS)**
CLS tracks how much a web page's content unexpectedly shifts while loading. Unexpected movement of a page’s content can disrupt the user experience and lead to annoying and sometimes damaging misclicks. A low CLS indicates a stable page layout, enhancing user satisfaction and trust, and leading to longer site visits.
* **Largest Contentful Paint (LCP)**
LCP reports the time it takes for the largest visible image, video, or text block to render in the viewport when a user first navigates to the page. Quicker load times can create a positive first impression and increase engagement, reducing bounce rates from users.
* **Interaction to Next Paint (INP)**
INP assesses a page’s overall responsiveness by measuring how quickly it responds to user interactions, such as clicks, taps, and keyboard inputs, throughout the user’s visit. The final INP value is determined by the longest interaction found, ignoring outliers.
The less a page lags and the quicker it responds to user interactions, the less frustration there is. This increases the chances of longer engagement and the likelihood of ad viewability and interaction.
* **First Contentful Paint (FCP)**
FCP is the measurement of how quickly the first piece of content (text or images) appears on the screen when the page starts loading.
A quick FCP increases the perceived reliability with the site and reassures users that the page is loading. Both factors likely increase the chances that users will stay and potentially see and interact with ads.
**How to improve your score**
Each CWV metric has its own specific measurements and guidance on how to optimize the factors that contribute to them. We recommend reviewing the Google [web.dev](http://web.dev/) documentation found in the useful resources to improve these metrics and increase your scores.
**Useful Resources**
* [Core Web Vitals](https://web.dev/explore/learn-core-web-vitals?hl=en) - Web.dev
* [Best Practices: Improve Core Web Vitals](https://docs.sourcepoint.com/hc/en-us/articles/11108155226131-Best-Practices-Improve-Core-Web-Vitals) - Sourcepoint
## Implementation
Our one-tag solution simplifies integration and setup for publishers by handling the heavy lifting on our end once on page. To ensure everything runs smoothly and efficiently, there are several key metrics that play a crucial role. Our Implementation section dives into these metrics and highlights factors that could impact your performance, health score, and most importantly - your revenue.
**Metrics we check**
* **Direct vs Non-Direct Tag Placement**
First, we check whether our Content Ignite Publisher Tag is placed directly on your site or through other methods, such as Google Tag Manager (GTM) or Google Ad Manager (GAM). Non-direct placement will undoubtedly introduce extra latency and load times, reduce performance, and add unnecessary complexity, all of which will likely affect your revenue.
* **Tag Latency**
Latency issues tied to non-direct tag implementations, can significantly impact your revenue potential. Minimising latency between the page load and tag firing boosts load times and helps prevent lost revenue due to delays to getting ads to page, reduced exposure to the ads per user visit, decreased viewability and lost user interaction opportunities.
* **CMP issues**
A Consent Management Platform (CMP) is essential for managing user data privacy and consent, which directly affects ad serving. CMP errors can lead to issues such as loss of personalised ads, lower CPMs, unfilled ad slots, limited programmatic bids, compliance risks, lost trust, increased latency, and even financial penalties. Reducing CMP errors is key to maintaining positive ad revenue and a good user experience.
To minimise errors, your CMP must be properly integrated and configured to capture accurate user consent. Opt for a reputable industry platform that is regularly updated, making sure to conduct routine testing to ensure it’s functioning correctly.
We commonly track issues like incorrect execution order and a missing CMP “Stub” during implementation - both of which are essential for the process to run smoothly. Our [integration guides](/getting-started/going-live#notes-on-cmps) are here to help publishers set things up correctly, so you avoid any revenue loss. And remember, Content Ignite is available to deploy CMP integrations directly from the Fusion platform to ensure you have the optimal setup from the get go.
* **Mobile Ad Density**
Mobile Ad Density (MAD) refers to the ratio of ads to content on a mobile screen. Balancing MAD is crucial: while higher rates (typically above 30%) might increase impressions and fill rates, they can also negatively impact user experience by being intrusive, obscuring content, affecting site reputation, and slowing load times. Keeping MAD within a balanced range ensures a good user experience while still meeting your monetisation goals.
**How to improve your score**
Identifying the areas needed for improvement and working with Content Ignite to help optimise these factors will best ensure your implementation and performance is working to your advantage. Alongside our recommendations in the report, the additional resources provided here will offer further insights and guidance on making improvements, helping to boost your health score.
**Useful resources**
* [Coalition for Better Ads](https://www.betterads.org/)
* [Ad Density](https://databeat.io/knowledge-base/ad-density/) - DataBeat
* [PageSpeed Insights](https://developers.google.com/speed)
* [Dialogue: CMP web implementation](https://docs.sourcepoint.com/hc/en-us/sections/1500001157062-Dialogue-CMP-web-implementation) - Sourcepoint
## Risk
Understanding how your website is perceived by audiences and brands in the ad industry is crucial for attracting advertiser spend and maximising your revenue.
With analytics provided from industry leader Pixalate, we provide a comprehensive insight of key risk factors such as ad fraud, viewability, invalid traffic, brand safety, and traffic sources that impact the overall risk health of your website.
Our risk section identifies and categorises these critical areas, helping you focus on actions that can reduce potential risks. By maintaining a low-risk profile, you can build greater trust and credibility with advertisers, attracting high-quality, premium ad creatives. This, in turn, opens up better revenue opportunities. Additionally, delivering high-quality ads can enhance audience retention and engagement, boosting your reputation in a competitive market.
**How to improve your score**
Each risk factor will have its own pathway to creating positive change and improving your risk health score. Our feedback should provide a snippet of the issue at hand, which can then be explored further through additional reading or by using some of the following useful resources.
**Useful resources**
* [Trustworthy Accountability Group (TAG)](https://www.tagtoday.net/)
* [Google Viewability best practices](https://support.google.com/admanager/answer/6199883?hl=en#:~:text=Ad%20placement%3A%20Consider%20placing%20ads,very%20top%20of%20the%20page.)
* [Brand Safety Institute (BSI)](https://www.brandsafetyinstitute.com/)
* [The Media Trust](https://mediatrust.com/)
* [IAB Ads.txt Specification](https://iabtechlab.com/wp-content/uploads/2022/04/Ads.txt-1.1.pdf)
* [Pixalate Blog](https://www.pixalate.com/blog)
## Ethical Media
Ethical Media, as defined by The Goodnet, a leading ethical intelligence company, refers to publishers who operate themselves ethically and create content that promotes ethical living. The goal is to foster content that supports sustainable lifestyles, promotes diversity, encourages collaboration, and ensures ads are delivered in an ethical, sustainable way.
The Goodnet’s data assesses your site across a variety of ethical and sustainable metrics, resulting in an overall Ethical Media Index (EMI) score. This score is based on three key categories: Corporate Systems, Advertising Science, and Content Ethics.
Emphasising ethical practices goes beyond just following laws and guidelines — it’s also key to unlocking revenue potential. By positioning yourself as an ethical partner, you can attract a wider range of advertisers who are keen to work with like-minded businesses. This approach can help build stronger relationships, attract more campaigns, improve ad quality, and contribute to creating a healthy, reputable business with long-term success in mind.
By exploring this data, you'll gain valuable insights into where your site stands in the ethical media landscape, as well as identify areas for improvement to help you operate as ethically and sustainably as possible.
**How to improve your score**
Based on the results for each category, the first step is to explore the areas that might be lowering the score. From there, we can work together with you and The Goodnet to provide a better breakdown and propose the best ways to make improvements.
**Useful resources**
* [The Goodnet](https://wearethegoodnet.com/)
* [The Ultimate Guide to Ethical Advertising](https://www.nued.se/post/the-ultimate-guide-to-ethical-advertising)
* [Understanding Ethical Advertising](https://www.iabuk.com/events-training/understanding-ethical-advertising) - Webinar
## Header Bidding
Our Header Bidding section evaluates how well your site and publishing strategy are optimised for programmatic advertising. We specifically focus on Prebid, an open-source software suite designed to implement header bidding solutions. First, we check if Prebid is part of your ad setup, and if it isn’t, we advise on the benefits it could bring - such as increased competition and revenue through simultaneous ad exchange bidding, greater auction transparency and control, and free open-source access. By introducing this competition among advertisers, you’ll often see a rise in revenue.
If Prebid is already in place, we move on to analyse your setup to ensure it’s working to your advantage.
**Metrics we gather**
* **Prebid Version**
With new versions being released almost every fortnight, it’s common for your Prebid version to fall behind. It’s crucial to stay up to date with these releases to benefit from the latest features and fixes. We’ll check your current version and report how many versions behind you might be.
* **Prebid SSPs**
An auction needs bidders, and the same applies to programmatic bidding. However, the number of Supply-Side Platforms (SSPs) involved needs to be carefully balanced. While more SSPs can increase competition, raise CPMs, and improve fill rates, they can also add pressure on load times, increase latency, and at a certain point, provide diminishing returns.
Conversely, having too few SSPs might reduce latency and benefit from having simplified focussed partnerships, but it can also limit competition, fill rates, demand diversity and introduce instability. This could lead to lower CPMs and reduced revenue opportunities. Our report will review your current setup to help you find the right balance if needed.
* **Prebid Timeout**
When the page first loads and the header auction begins, demand partners (bidders) have a set amount of time to place their bids. This is known as the Prebid Timeout. It’s important to strike a balance: too short a timeout, and SSPs won’t have enough time to bid; too long, and overall ad performance might suffer due to increased latency.
We’ll review your Prebid Timeout settings and provide feedback on whether adjustments are needed to optimise performance.
Beyond Prebid, we also check if you’re benefiting from Amazon’s UAM/TAM platform, a server-to-server solution that complements Prebid to further boost competition. This can be easily configured within Fusion, where we handle all the complex integration for you.
**How to improve your score**
While deciding to integrate programmatic header bidding solutions like Amazon and Prebid requires aligning with business goals, introducing them into your ad ecosystem can have a significant impact.
With Prebid in place, a few simple adjustments such as reviewing your connected SSPs, fine-tuning timeout settings, and ensuring your version is up-to-date, can help you maximise revenue opportunities and achieve a higher score in this area.
**Useful resources**
* [Prebid.js](https://docs.prebid.org/prebid/prebidjs.html)
* [Headerbidding.co](https://headerbidding.co/)
* [Amazon Publisher Services](https://aps.amazon.com/aps/unified-ad-marketplace-uam-vs-transparent-ad-marketplace-tam/)
* [What is Prebid timeout and how to optimize it?](https://headerbidding.co/prebid-timeouts/) - Headerbidding.co
## Sustainability
With the goal of reducing your website’s environmental impact and attracting unique demand from advertisers seeking sustainable publishers, our Sustainability section evaluates your site using the [Website Carbon Calculator](https://www.websitecarbon.com/).
This tool calculates the energy usage and emissions of a web page (based on your site’s homepage) to determine data transfer, energy and carbon intensity, sources, and traffic. With this, we provide a clear picture of your domain’s sustainability health across three key areas:
* **Sustainability Output**
An assessment of how your site compares to the global web landscape, providing an output score that indicates how clean (or dirty!) your site is.
* **CO2 Emissions**
The amount of CO2 (CO2e) produced in grams each time someone visits your website’s homepage.
* **Green Energy/Hosting**
An evaluation of your energy source and whether your hosting provider uses data centres powered by renewable and sustainable sources, as verified by The Green Web Foundation.
**Translating this into real figures**
Using these metrics, along with data on page visits to your site from the previous month, we can deduce real-life figures to showcase your sustainability stats - an eye-opening insight into your website’s impact.
**How to improve your score**
The ultimate aim is to reduce your carbon emissions and ensure your energy sources are green. This not only lessens your environmental impact but also attracts environmentally conscious advertisers, increasing demand for your site.
Simple steps like reviewing your hosting provider, optimising images and videos, and caching content can make a significant difference. Explore some useful resources for more information on how to start reducing your website’s carbon footprint.
**Useful resources**
* [The Web Carbon Calculator](https://www.websitecarbon.com/how-does-it-work/) : Wholegrain Digital
* [Make your technology sustainable](https://www.gov.uk/guidance/make-your-technology-sustainable) : Gov.uk
* [What You Can Do To Reduce the Carbon Footprint of Your Website](https://vwo.com/blog/reduce-website-carbon-footprint/) : VWO
* [The carbon footprint of your website and how to reduce it](https://yoast.com/carbon-footprint-of-website/) : Yoast
* [Reduce the carbon emissions of your website](https://climateaction.tech/actions/reduce-the-carbon-emissions-of-your-website/) : Climate Action
## Plan
Now that we've completed a full health check, what’s next? That’s where our Plan section comes into play.
Using the Crawl-Walk-Run approach, we guide each publisher through a series of strategic tasks and goals. We start with the Crawl stage, where we suggest small but significant changes that will begin to positively impact both your site’s health and revenue potential.
Next, we move on to the Walk and Run stages, offering further recommendations for enhancements and features. These steps are designed to steadily improve your site’s health and keep you on track for long-term revenue success.
# Insights Hub
Source: https://docs.contentignite.com/reporting/insights/index
Welcome to a world of publisher insights like you've never seen before
Welcome to one of the most powerful and exciting sections of Fusion (yes, we are all data nerds!).
The Insights Hub is a visual reporting centre designed to deliver actionable insights into specific aspects of your ad tech setup. From diagnostics and ads.txt deep dives to sustainability metrics, this is where you can truly explore performance and uncover opportunities to maximise your earnings.
## Navigating the Insights Hub
Landing in the Insights Hub you will see all the reports available to you. Simply click on a report to dive straight into the insights.
### Header
Individual reports may initially display a network-wide (all publishers) view of data or prompt you to select a specific publisher via the publisher filter. This filter is located in the Insights Hub header, which remains consistent across reports. At any time, you can adjust the report’s focus by selecting a different publisher.
Another key filter is the date range filter, available in most reports. This allows you to choose from preset date ranges or define a custom start and end date. A particularly useful feature is our grouped date periods; Month-on-Month and Quarter-on-Quarter. These options group data by month or quarter instead of by day, making it easier to identify long-term trends. Above the date field, you’ll see your selection displayed as a start and end date for clarity, especially when using predefined ranges.
Additional controls can be found in the top-right section of the page header. These include a refresh button to fetch fresh data, and a back button to jump back to the main Insights Hub landing page.
#### Advanced Filters
One last button exists in the far-right of the header - the filter button. This appears only on pages where additional filters (beyond publisher and date) are available. Clicking this will toggle the filter drawer, revealing extra filtering options.
These additional filters can significantly alter report behaviour. For example, in the **SSP Hub**, selecting a specific advertising partner transforms the report into a focused view of that partner over time.
Closing the filter drawer provides more screen space for charts, while a badge on the filter button indicates how many filters are available.
To reset all filters to their default values, simply click the bin icon within the filter drawer.
#### Quick Navigation
Once inside a report, you can click the colourful icon button to the left of the report title to open up a quick navigation menu. This allows you to jump into another report with ease, with the added benefit of persistence.
#### Bookmarking & Persistence
Any filters you select within a report are saved to the page URL. This means you can copy the page URL and share it with a colleague, who will see the exact same view, including all selected filters, when they open the link.
We even take this a step further: if you select an individual publisher for a report, that publisher selection persists as you navigate to other reports. This goes for all filters that are consistent across pages, such as date range or net vs gross revenue.
### Charts
Charts are a key part of the Insights Hub, as visualising data is crucial for understanding trends and performance. Charts will typically show a number of metrics that can be controlled by filters.
In cases where a large volume of data is requested (say you choose "Last year" as your date range), charts may group data points to ensure they remain usable both from a performance and UX perspective. For example, too many bars in a bar chart would become compressed, making it difficult to distinguish time periods.
### Tables
Where possible, reports include a data table, typically containing the full dataset used to power the charts and other views on the page.
This is particularly powerful as it gives you the flexibility to export that data and use in your own reporting tools if you so wish.
These tables also come with a range of familiar spreadsheet-like features, including filtering, grouping, pinning, sorting, aggregation, and column hiding. Simply hover over a column header and click the three vertical dots to open the column menu.
## Reports
Each individual report tackles a key area of insight. We have plans for many more, but if you have any ideas, please do [reach out](https://resource.contentignite.com/support)!
* [Ads.txt Insights](/reporting/insights/ads-txt)
* [Core Web Vitals](/reporting/insights/cwv)
* [Demand Mix](/reporting/insights/demand-mix)
* [Diagnostics](/reporting/insights/diagnostics)
* [Health Score](/reporting/insights/health-score)
* [Live](/reporting/insights/live)
* [Metrics](/reporting/insights/metrics)
* [Revenue Analytics](/reporting/insights/revenue-analytics)
* [SSP Insights](/reporting/insights/ssp)
* [Revenue Insights](/reporting/insights/revenue)
* [Benchmarking](/reporting/insights/benchmarking)
* Content Hub (Planned)
# Live
Source: https://docs.contentignite.com/reporting/insights/live
Minute by minute data for the time critical transient moments
Live reporting is a powerful real-time monitoring tool. Imagine you are about to deploy a new site template and want to be sure it hasn't impacted your ad opportunities. This tool provides a second-by-second view of key metrics, as well as latency, so you’ll instantly know where things stand.
The "**Live Metrics**" graph displays key metrics such as ad impressions and page impressions, [more info on these here](/reporting/insights/metrics#ad-metrics).
The "**Bid Rates**" chart shows bid responses from the Ad Server, showing if a request filled or not. Its worth remembering that if you have a house campaign running in the Ad Server, fill will look impressively close to 100%.
The "**Header Bidding**" chart shows data from Prebid (if used). This gives a much more granular breakdown of bid events, showing when a bid request won, lost, didn't bid or got throttled through [bid throttling](/publishers/optimisation#prebid-bid-throttling).
The "**Live Latency**" chart shows tag latency stats, which you can [read more on here](/reporting/insights/metrics#latency-stats).
You can use the filter draw to remove metrics from the charts, helping you focus on what matters most. For example, if ad impressions are overshadowing page impressions, you can hide them for a clearer view.
## What this report is, and what it isn't
This is not a performance report. It does not show revenue (which, unfortunately, is not possible from Google Ad Manager). It's also not a report you keep up on your screen all day - Fusion can alert you to key "drop-off" events, so there’s no need to monitor these charts obsessively.
What this report **is**: a real-time tool for monitoring key metrics while making site changes. The impact of site modifications isn’t always obvious, and unintended consequences can occur. Watching live data can give you peace of mind, or an early warning signal that something's not quite right - allowing you to react quickly before any damage can be done.
# Metrics
Source: https://docs.contentignite.com/reporting/insights/metrics
Dive into the industry standard metrics and even live revenue
This reporting view gives you graphical insight into various core metrics. On top of expected tag metrics and revenue data, you can view live revenue for the day so far, as well as latency stats - helping you understand your site's performance and how it might be impacting earnings.
## Ad Metrics
View 30 days of key tag metrics, such as page impressions and ad impressions. Use this graph to spot anomalies that might help explain publisher performance.
**Page impressions**\
This is the number of pages our tag was loaded on
**Ad unit loads**\
This is the number of times we have found a target match on page, and are ready to serve ads. However, our in-view technology won't load an ad until that unit is scrolled into view. So this metric may be higher than ad impressions. You can think of this as "ad opportunities".
**Ad loads**\
This is the raw count of how many ad requests actually returned an ad (filled).
**Ad misses**\
This represents the number of ad requests that didn't return an ad. This could be due to legitimate reasons, such as yield optimisation, where we push for higher CPMs, reducing fill but increasing revenue. Alternatively, an ads.txt issue could cause decreased ad responses if partners are not authorised to bid.
**Ad impressions**\
This is the number of impressions received on an ad, meaning the ad was successfully returned and fully rendered on the page (all images and scripts downloaded). This will be lower than "ad loads", as users may exit the page between an ad being returned and the ad fully rendering to page.
## Revenue & CPMs
View your revenue trends for the current 30-day period, the previous 30-day period, and 30 days offset by a week. This provides solid comparisons to your current revenue performance. Along with the ad metrics graph above, trends should be easily identifiable.
The same can be seen in a "CPM" view, offering a slightly different take on earnings.
## Live Hourly Revenue
View today’s hourly revenue in comparison to yesterday and the same time last week. We extrapolate today’s data to provide a revenue prediction. Use this graph for a quick visual on how today is shaping up.
Note: Revenue is reported from Google Ad Manager, which is typically 2-3 hours behind "live" data.
## Latency Stats
An important part of advertising is latency. Ads won't be effective if they take 10 seconds to load on the page, as the user might have finished reading the article by then!
This is where our latency stats come in. Some stats are completely under the control of the publisher, while others are controlled by the Content Ignite Publisher Tag but are heavily impacted by general page performance.
The top stat in this section is "Page to Ad Load," which measures the time from when your page is first delivered to the user's browser to when the user sees an ad. As you’ll see below, several factors impact latency, many of which relate to general page performance. We aim for this value to be around 3,000ms (3 seconds), bearing in mind that the page itself is loaded within that time period before our tag.
**Page Latency**\
This is an important metric. It measures how long it takes to load our script on the page, from the point of page load to tag load. Completely under the control of you, the publisher, this is often the biggest cause of latency issues. Direct tag-on-page integrations will typically see the smallest latencies here, followed by setups like Google Tag Manager, and lastly, serving via an ad server. Introducing delays in this process will have a direct impact on earnings.
Other contributors to poor latency can include heavy use of JavaScript, which may cause competition between scripts and slow down your Publisher Tag.
We'd typically expect page latency to be under **250ms**.
**Tag Latency**\
This measures how long it takes for our tag to be downloaded by the user's browser and to be ready to start setting up ads. Our tag is served via a global CDN, typically taking around 40ms to be delivered. Therefore, the rest of this portion of latency is likely caused by either:
* User Internet Speed: Slow internet or low bandwidth can take longer to download resources
* Site Resource Use: If your site requests many different resources (images, scripts, etc.), those resources may be queued up, as browsers can only download so many at one time, causing a delay
We'd typically expect tag latency to be under **1000ms**.
**Unit Latency**\
This measures the time it takes for us to find the ad unit targets on the page, load in the ad unit, and be ready to request ads.
This is typically only effected by general page performance, such as other scripts trying to execute.
We'd typically expect unit latency to be under **500ms**.
**Ad Latency**\
Ad latency represents the time from when we call the ad server to request an ad, until we receive a response. Ad server response times can be affected by the user's internal speed, as well as other page resource requests and the number of bid partners.
Content Ignite continuously scores our bid partners to ensure they are performing well. Any partners that are not are removed, helping to keep the number of partners to a minimum and balancing speed and revenue performance.
We typically see ad latency around **700ms**.
# Revenue Insights
Source: https://docs.contentignite.com/reporting/insights/revenue
Learn where revenue is flowing in from and how it is performing
The Revenue Insights Hub gives you a clear, all-in-one view of your publisher earnings, helping you explore performance from every angle – see what’s working, what’s not, and where the biggest opportunities are. With visual breakdowns and flexible filters, it’s never been easier to uncover insights, spot gaps, and maximise your earning potential.
Here are the key tab views found in the Revenue Insights Hub:
## Overview
The Overview tab (default view) pulls together the total revenue data into a single view. You’ll get top-level stats showing overall revenue, plus fixed-period comparison figures to give you a broader picture of how things are trending.
A revenue chart then break this down further, showing date trends for a deeper look into revenue performance over the selected date range. And finally, there’s a fully exportable table that brings together a range of metrics – giving you the tools to filter, sort, and analyse the data however suits you best.
## Dimension Views
Each dimension view lets you break things down even further, showing exactly where your revenue is coming from. TThese views pull out the top ten performers (by gross revenue) in each dimension category, highlighting both the best and worst performers so you can spot any weak areas and make smart, data-backed decisions to optimise your setup.
The graphs show revenue and eCPM by day, so you get a full picture of how things stack up over time – and you’ll still have access to the same exportable data table for deeper analysis across all dimensions.
For even more detailed insights, you can filter by a specific dimension from all results to provide a detailed breakdown and help track performance over time on a specific level.
## Filter Options
As with other Insights Hub pages, the global filters for Publisher and Date will shape the data you see. On top of that, you’ll find a few extra filters on this page to help narrow things down even more.
### Dimension Filter
When you’re viewing a specific dimension tab, you’ll get a Dimension Filter dropdown to pick a particular dimension to focus on. This updates the charts to show just that dimension across the date range, instead of gathering all results together. It’s a handy way to follow trends and spot shifts in a single area – whether that’s a specific publisher, device type, or geo.
### Further Fine-tuning
Along with global filters for Date and Publisher that influence the data, Revenue Insights offers additional flexibility for data presentation. You can toggle between Gross and Net revenue views, depending on your preference. Graphs can also be adjusted to show totals or percentages, allowing you to analyse performance in different ways. Furthermore, filter exclusions allow you to toggle chart overlay lines, providing more control over how the data is displayed, helping you focus on the most relevant insights.
## Publisher Filtering
In some cases, depending on your organisation setup or if a global publisher filter is applied, the Publisher tab won’t show anything beyond what’s already available in the Overview tab.
When a global publisher filter is in place, you’ll see a message letting you know that the same view can be found in the Overview, along with a tip on how to adjust filters to access a broader breakdown of publisher revenue.
If the Publisher tab is completely inaccessible, it’s likely because your organisation only has a single publisher – in which case, there’s no additional comparison data to show you beyond what you see in the Overview.
# Revenue Analytics
Source: https://docs.contentignite.com/reporting/insights/revenue-analytics
Spot trends easily by plotting your analytical data against revenue
The Revenue Analytics Insights Hub combines direct publisher revenue data with integrated on-site Google Analytics metrics to offer a comprehensive view of earnings performance across a range of views.
By looking at Revenue Per Mille (RPM) alongside key analytic metrics - particularly users, page views, and sessions — Fusion offers a clear and balanced measure of monetisation performance. This helps publishers get a better handle on user engagement, spot profitable traffic sources and audience behaviours, and identify underperforming areas, revealing valuable insights to fine-tune their revenue strategy.
Publishers can explore a range of views accessible through top-level tabs, from a broad overview of key data points to with more detailed breakdowns of individual metrics for a deeper dive.
## Overview
The Overview tab (default) consolidates key revenue analytics data with both statistical and graphical views. High-level stats provide a quick snapshot of RPM against each analytic metric, giving you an at-a-glance look at date-related totals. The RPM chart then break this down further, showing date trends for a deeper look into performance over time. Finally a fully exportable tabular view allows you to filter, sort, and analyse the data however you'd like.
## Single Views
Each single view breaks down the data further by each analytics metric. These include:
* **Page Views**: The total number of times a page on a website was viewed, including multiple views by the same user.
* **Total Users**: The unique number of individuals who visits a site during a specific time period.
* **Sessions**: The total number of visits to a site, where each session includes all user interactions within a specified time window (typically 30 minutes).
* **Ad Requests**: The total number of times an ad gets requested from an ad server to be displayed on a page.[^1]
* **Unit Loads**: The number of times an ad successfully loads on a page after being requested.[^1]
[^1]: Not directly linked with analytics
Fixed-period comparison statistics are displayed at the top of the view (limited), followed by a chart showing the selected date range RPM and total. This breakdown enables publishers to gain a full understanding of revenue distribution across a range of analytical data points.
## Filter options
In addition to the date filters that apply to the page, there are some page filters that enable some further customisations to the views. These include:
**Revenue Type Toggle**\
Switch between Gross and Net figures for RPM to view earnings in the preferred format.
**Metric Toggle**:\
Easily turn chart metrics on or off to customise the graphical view in the Overview.
These filter options make it easy to refine the data and focus on the insights that matter most.
## Getting Connected
In order for Fusion to track a publisher's analytics data, an analytics partner first needs to be connected in the [Integrations section](/integrations/analytics). A check for this is done initially, and if setup is required, publishers can simply follow the steps to get connected and start pulling in data right away.
## GA Reporting
When viewing data by month, quarter, or other larger date ranges that dynamically group daily data (charts only), you may notice that User and Session totals appear higher than expected. This is not a bug — it’s due to how GA4 calculates unique users and sessions across longer periods.
At a daily level, a user is counted once per day, even if they visit multiple times. When GA4 aggregates data over a longer period, it applies deduplication using internal user identifiers to calculate “unique” totals. This ensures the official totals in GA4 reflect the actual number of distinct users and sessions across the range.
### How Fusion handles this
Fusion pulls GA4 data daily, which avoids duplication at the day level. For charts that display trends over time, we sum these daily totals. This means that a user who visits on multiple days will be counted once per day, but multiple times when totals are summed for a week, month, or quarter.
For aggregated totals across a custom date range (e.g., “Total users last 30 days”), Fusion fetches data directly from GA4 in real time. This ensures GA’s deduplication is preserved, giving you the most accurate totals without inflating numbers.
### What this means
* Summing daily figures manually may show higher User and Session counts than GA4’s official totals.
* This can result in slightly lower RPM values when calculated from summed daily data versus totals pulled directly from GA4.
* For fully accurate totals and calculations (especially for grouped date ranges), it’s best to query GA4 directly and use the resulting revenue figures for RPM calculations.
* Figures are never 100% final, as GA can adjust totals after the data is fetched. Always refer to GA reports for completely accurate numbers.
# SSP Insights
Source: https://docs.contentignite.com/reporting/insights/ssp
How hard are your SSP demand connections working for you?
The SSP Insights hub offers a detailed view of how SSP partners are performing within the programmatic bidding process. With clear statistical and graphical insights, you can visualise the bidding pathway, identify revenue streams, and analyse bid efficiencies at a granular level — helping you fine-tune your bidding strategy and maximise revenue.
## SSPs and Programmatic Header Bidding
In the Prebid ecosystem, Supply-Side Platforms (SSPs) connect publishers with demand sources, facilitating real-time bidding (RTB) to maximise competition for ad inventory. When a page loads, Prebid.js sends bid requests to multiple SSPs, which evaluate the opportunity and return bids. Prebid.js then processes these bids, passing the highest eligible one to the ad server (typically Google Ad Manager) for the final auction.
By tracking key metrics like bid rate, win rate, and revenue, we are able to present this data on SSP performance and inform how to better optimise their setup. This could include prioritising high-performing SSPs or removing underperforming ones, refining demand strategies or adjusting floor prices.
## The Bid Funnel
The top-level view shows how ad requests flow through each stage, from the total bid requests through to winning bid amounts, highlighting both the value and percentage at each step. With publisher and date filters applied, you can easily track the progression of your bid requests down the funnel.
Additionally the highest and lowest performers are highlighted, helping you identify which SSPs, or specific dates for a single SSP, could benefit from making strategic adjustments.
## Bid Rates
The first graphical view breaks down each bid metric per SSP, alongside bid and win rates, allowing you to spot trends and compare performance.
Understanding these metrics helps you identify which SSPs are driving the most engagement, where bid opportunities may be underperforming, and how efficiently bids are converting into wins.
## Revenue
Revenue is plotted for each SSP, showing win revenue against total bid revenue — both as an amount and percentage. An overlay of revenue efficiency helps publishers assess how well an SSP converts bid requests into actual revenue. This could be key to understanding the profitability of each SSP in the auction and reveal which partners are delivering the highest returns.
## Data table view
Alongside the graphical insights, the SSP Insights provides a fully exportable tabular view, allowing you to filter, sort, and analyse the data however you need.
## Filter Options
### Single SSPs
In addition to viewing the overall and comparable SSPs together, our tool allows you to break down the data for a single SSP using the filter dropdown list. When viewing the SSP dimension, each graph will represent a breakdown of the bidding information by date, helping you spot trends for the selected SSP over time.
### Multiple Dimensions
Beyond breaking down data for SSPs, our Insights tool lets you explore bidding performance by device and country. This helps identify regions or platforms with the most potential, and highlights areas where filtering out underperforming configurations could be beneficial.
### Include Throttled Bids
[Bid Throttling](/publishers/optimisation#prebid-bid-throttling) is a brilliant optimisation tactic, used to reduce bidders in the auction whist maintaining revenue. However, if working correctly, bids being sent to a bidder will reduce, but other metrics such as bid rate or win rate should improve.
There are two ways to look at data in this case;
1. Using bid opportunity as the base (bid requests + throttled bids)
2. Using bid requests as the base
Both are valid in different circumstances. Using option 2 should show the positive impact that bid throttling is having, but if you are reviewing the performance of a bidder, option 1 would show you that perhaps a high throttle rate could indicate minimal value to your ad stack.
The "Include Throttled Bids" filter allows you to toggle between the two options, adjusting charts and the splitting out the bid funnel accordingly.
### Further Fine-tuning
Along with global filters for date and publisher, the SSP Insights also provides flexibility in presenting data. As with most revenue-based insights, you can view totals in both Gross and Net revenue. Additionally, you can switch between total values for the selected date range and average values.
The total values provide a full picture of revenue generation, while average values highlight trends and performance stability, helping to identify areas for improvement or optimisation.
## Glossary
**Bid Requests**\
The number of requests sent to SSPs for ad inventory.
**Bids**\
The number of bids received by SSPs in response to a bid request.
**No Bids**\
The number of bid requests where no bid was submitted. This is the difference between the total bid requests and the number of bids received.
**Won Bids**\
The number of bids that won the auction on the highest amount and were selected to display the ad.
**Lost Bids**\
The number of bids that were not selected in the auction. This is the difference between the total bids made and the won bids.
**Throttled Bids**\
The number of bid requests that were *not* sent to bidders due to [bid throttling](/publishers/optimisation#prebid-bid-throttling).
**Bid Rate**\
The percentage of bid requests that received at least one bid. (Bids / Bid Requests) \* 100.
**Win Rate**\
The percentage of bids that resulted in a win. (Won Bids / Bids) \* 100.
**Throttle Rate**\
The percentage of bids that were throttled. (Throttled Bids / Bid Requests + Throttled Bids) \* 100.
**Bid Revenue**\
The total amount of revenue generated from all bids submitted.
**Won Bid Revenue**\
The total amount of revenue generated from bids that were won.
**Bid Value**\
The amount of revenue associated with a single bid.
**Win Value**\
The amount of revenue associated with a winning bid.
**Revenue Efficiency**\
A percentage of the won bid revenue over the total amount of bid requests. (Won Bid Revenue / Bid Requests) \* 100,000.
## Useful Resources
* [About Prebid.js](https://prebid.org/about/)
* [Prebid Server: Understanding Prebid’s Server-side Header Bidding](https://www.mile.tech/blog/prebid-server)
* [How to optimize header bidding setup](https://docs.prebid.org/overview/how-many-bidders-for-header-bidding)
* [The perfect mix of SSPs for Publishers](https://www.pubstack.io/topics/perfect-ssp-mix-for-publishers)
# Revenue Report
Source: https://docs.contentignite.com/reporting/revenue
Build completely custom report, and even visualise the data in chart form!
The revenue report is your main insight into publisher performance. Giving you a highly transparent breakdown of costs and even the viewability of impressions.
These reports are designed to be built for your needs, allowing complete customisation over date ranges, fields and filters.
**GAM integration without reporting**
If you chose to use your own Google Ad Manager account, and connect it in without reporting, or opt for the manual integration option, you will see substantially less in this report.
You will get a basic impressions report (which is what your billing is based on) broken down by ad unit.
## Building your report
Clicking "New report" will take you to the report build view, where you can select you data range, fields and filters.
If you give your report a title you can save it for re-use later, or to just generate a one off report, you can simply click "Run" after you have made your selections.
## Available Fields
There is a large amount of data available via this report, explanations of each column can be found by hovering over the field in the report builder interface, or over the column header if you have already ran the report.
Due to the complexities of advertising, you will likely come across a column that doesn't make sense against another column like "How can ad responses be higher than ad impressions?" or columns that sound similar where the differences aren't immediately clear. These are valid and common questions, so to help we have listed answers to common questions in the help modal accessible from the info icon in the top right, or via [Field Nuances](#field-nuances) further down this page.
Got a question we haven't answered? [Reach out](https://resource.contentignite.com/support) and lets us know, as it could help others too!
| **API Field Name** | **Corresponding UI Name** | **Field Description** |
| ---------------------- | ------------------------- | -------------------------------------------------------------------------------------------- |
| account\_name | Integration Name | Account name of the connected integration e.g. account name of your ad server |
| account\_owner | Integration Owner | The organisation that owns of the connected integration |
| ad\_impressions | Ad Impressions | Total impressions served by the ad server |
| ad\_requests | Ad Requests | Total number of requests sent to the ad server |
| ad\_responses | Ad Responses | Total number of ad requests that successfully returned an ad |
| ad\_unit\_loads | Ad Unit Loads | Number of times a target match was found on page (not necessarily number of ads requested) |
| ag\_video\_clicks | AG Video Clicks | Number of recirculation click on an auto-generated video |
| ag\_video\_ctr | AG Video CTR | Percentage of auto-generated video views that clicked through to the article |
| ag\_video\_impressions | AG Video Imps | Number of impressions on an auto-generated video |
| campaign | Campaign | The name assigned to the campaign |
| channel | Channel | The method buyers used to access your inventory via the ad server |
| clicks | Campaign Clicks | Total campaign clicks |
| config\_id | Config ID | The ID of the config that matched and served the ad request |
| config\_name | Config Name | The name assigned to the config (if available) |
| cost | Const | Total cost in revenue share and SaaS fees (gross revenue - net revenue) |
| creative\_size | Creative Size | The creative size served |
| ctr | Campaign CTR | Percentage click through rate for the given campaign |
| date | Date | Date revenue is attributed to |
| month | Month | The year and month revenue is attributed to |
| device | Device | Device category (desktop,mobile or tablet) |
| ecpm | eCPM | Average cost per 1,000 impressions |
| fill | Ad Server Fill | The percentage of ad requests that returned an ad |
| geo | Geo | Country iso-code |
| gross\_revenue | Gross Revenue | Total revenue |
| imp\_fill | Fill | The percentage of ad requests that became an ad impression |
| line\_item | Campaign Name | This is the campaign name for your direct sold |
| month | Month | Month and year, for easy grouping |
| net\_revenue | Estimated Net Revenue | Estimated publishers share of revenue |
| oid | Organisation ID | Organisation ID |
| organisation | Organisation | Organisation name |
| partner | Partner | Name of the ad network that sent the winning bid |
| platform | Platform | Name of the primary platform e.g. your ad server or demand partner connection |
| publisher | Publisher | Publishers domain plus optional label |
| q1\_impressions | Video Q1 Imps | Number of times that a video plays to 25% of its length |
| q1\_percent | Video Q1 % | Percentage of views that played to 25% of videos length |
| q2\_impressions | Video Q2 Imps | Number of times that a video plays to 50% of its length |
| q2\_percent | Video Q2 % | Percentage of views that played to 50% of videos length |
| q3\_impressions | Video Q3 Imps | Number of times that a video plays to 75% of its length |
| q3\_percent | Video Q3 % | Percentage of views that played to 75% of videos length |
| q4\_impressions | Video Q4 Imps | Number of times that a video plays to completion |
| q4\_percent | Video Q4 % | Percentage of views that played to video end |
| region | Region | Continent iso-code |
| revenue\_source | Revenue Source | Either P\&P (we pay you) or SaaS (you get charged) |
| rpm | eRPM | Estimated publisher revenue per 1,000 ad requests |
| uid | Publisher UID | The internal unique ID for the publisher |
| unit | Unit Type | Unit type e.g. In-image |
| unit\_fill | Unit Fill | The percentage of ad unit loads that returned an ad (can be over 100% if refresh is enabled) |
| viewability | Viewability | Ad impressions that were deemed "viewable" |
| viewable\_impressions | Viewable Impressions | Ad impressions that were deemed "viewable"; 50% in-view for 1 second |
## Field Nuances
### (Estimated) Net Revenue
If you are using only Content Ignite ad demand (P\&P) then net revenue
is straight forward, it will be the gross earnings with your revenue
share applied, and outside of the 4 day reconciliation period, can be
relied upon and will match your invoiced payout.
However, things get a little more complex for SaaS customers, as fees
are calculated from ad usage, which has a tiered pricing structure
applied, so with greater volumes, discounted rates apply. Meaning that
as you progress through a month, the RPM value may decrease. Net
revenue will also rarely match your invoice amount because ad usage is
calculated from all units across your entire network for the month as
a whole, so pulling reports for single publishers or over varying date
ranges means we have to estimate the billable impressions accordingly.
This is why the fields are labeled as "estimate".
### Ad unit loads vs Ad requests vs Ad responses vs Ad impressions
The lifecycle of an ad request starts with an ad unit load, this means
we found a target match on the page, and our unit was loaded, ready to
request an ad, however, our in-view technology may not make that
request if the unit is out of view of the user. Therefore Ad unit
loads can be higher than ad requests.
Ad requests are just that, requests to the ad server to ask for an ad.
We typically aim for the highest yield for our publishers meaning the
most revenue, and with that comes fill that is under 100%. If ad
refresh is enabled, then ad request may be a lot higher than ad unit
loads which only loads once per page load.
Ad responses mean the ad server has successfully returned an ad. As we
don't aim for 100% fill, this will typically be less than ad requests.
Next, we have ad impressions. This means that we have taken the ad
returned from the server, placed it on the page and all the images
have been downloaded to the users' browser allowing the ad creative to
be viewed by the user. This will typically be slightly lower than ad
responses as users could navigate away from the page between receiving
the ad response and rending the ad creative to the page.
Finally, we have viewable impressions. This is counted as having at
least 50% of the ads area visible on the users' screen for at least
one second. This is typically less than ad impressions, again as the
user could navigate or scroll away before this threshold is met.
### Unit Fill vs Ad Server Fill vs Fill
Fill is the common ad reporting metric of ad impressions divided by ad requests, to give you a percentage of how many ad requests actually led to an ad impressions. It is worth noting that Content Ignite does not aim for 100% fill, but instead aims for the highest yield, boosting the value of your inventory and maximising your revenue. Therefore, seeing blank ads is normal.
Ad Server fill is similar to fill, but compares ad requests to ad responses, removing user behaviour form the equation. This gives you a picture of overall bidding and win rate. Low fill here might signal that floor prices are too high for example.
Unit fill is by contrast, a measurement of opportunity. It is calculated from ad responses divided by ad unit loads, which as detailed above, is when the intended target is found on page but has not necessarily triggered an ad request. This value can go above 100% if ad refresh is enabled.
## Results Table Features
What may at first seem like a simple reporting table actually contains several powerful features that allow you to dice up and drill down into your data.
Clicking the three vertical dots next to any column header will give you several options:
### Column Visibility & pinning
Clicking the "Show columns" option will allow you to hide fields you don't need in that moment, in order to achieve a focused view.
You can even pin or "freeze" columns to keep them in view as you scroll across large data sets.
### Sorting
Click any column header to sort by that column, click again to reverse the sort or even hold down `cmd` (Mac), `ctrl` (Windows) and click multiple headers to achieve a multi-column sort!
### Filtering
Filter any field with various options for comparison operators, and view a single ad unit's performance across a subset of your publishers for example.
### Grouping
Reports are broken out into a granular view by default. Want to see a single daily summary by publisher instead? Use grouping to achieve just that.
### Aggregation
Select from various aggregation functions such as average, count or sum to populate the summary footer with values. These are set to values that make sense for the given column by default but can be changed to suit your needs.
### Saving and resetting table state
If you have reordered columns and adjusted sizes and sorting (among other things) you can save that layout for next time you (or anyone else) uses that report. Great for those dynamic date range reports that will get used time and time again.
You can of corse play around with filters etc and not save, to get the data you need in that moment.
You can also reset the table state back to how it started at any time with the "Reset" button.
### AI Assistant
All of the above can be magically applied through a natural language request (text or voice) using the built in AI assistant. Click the little speech bubble icon and type (or talk) your filtering requirements and let AI do the rest!
## API Reporting
You can pull all the same data you see in our UI, via our REST API. For more information, got to [API Reporting](/reporting/api)
# User Management
Source: https://docs.contentignite.com/users/index
Manage users and their roles
You can manage users across your organisations through your user management section. From here you can control user details, preferences and organisation associations.
Speak to your account manager about enabling organisational hierarchy if it is not currently available on your account.
## Features
From your user management pages, you can:
1. Set user name preferences
2. Set display preferences
3. Reset user password
4. View and revoke user API access token
5. Manage organisation access. More details over on the [Organisation page](/organisations#user-roles)