API Reference


Below you will find all routes and parameters of the Masslytics API.
If you do not have an API token yet, see API Access.

Getting started

All routes are relative to the base URL:

https://app.masslytics.io/api

Every request must contain your API token as a bearer token. Send and accept JSON:

curl https://app.masslytics.io/api/brands \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

A token belongs to a user, and has access to the same brands as that user has in the Masslytics interface.
You can verify your token with GET /user, which returns the user the token belongs to.

Most routes refer to a brand by its identifier. This is the code that is also part of your tag, for example ML-123456.

Errors

Status Meaning
400 A query parameter has an invalid value.
401 The API token is missing or invalid.
403 Your user has no access to this brand or item.
404 The brand or item does not exist.
422 The request body did not pass validation. The response lists the errors per field.

Dates and timezones

Routes that return results accept the same two query parameters:

Parameter Description
startDate First day of the period, for example 2026-10-13. Defaults to 7 days before yesterday.
endDate Last day of the period. Defaults to yesterday.

Results are calculated overnight, so the most recent day available is always yesterday. A later endDate is moved back to yesterday.

Broadcast times in responses are shown in the timezone of the user the token belongs to, in the format YYYY-MM-DD HH:MM:SS.

Brands

Method Route Description
GET /brands List all brands you have access to.
GET /brands/{identifier} Show one brand.
POST /brands Create a brand.
PUT /brands/{identifier} Update a brand.
DELETE /brands/{identifier} Delete a brand. Returns 204.

Body parameters for creating and updating

Parameter Type Required Description
name string Yes Name of the brand, at most 255 characters.
base_url string No Base URL of the website, for example https://example.com.
disabled boolean No Disables the brand. Defaults to false.
advertiser_id integer No Only when creating: the advertiser the brand belongs to. Defaults to your own organization.

Response

{
    "id": 12,
    "name": "Example",
    "identifier": "ML-123456",
    "base_url": "https://example.com",
    "disabled": false,
    "install_check": "success",
    "last_visitor_at": "2026-10-13T10:15:00.000000Z",
    "script_tag": "<script>...</script>"
}

The script_tag field contains the tag that must be placed on the website. See Installing the pixel.

Installation check

Method Route Description
GET /installCheck/{identifier} Check whether the tag of a brand is installed.

Response

{
    "status": "success",
    "last_visitor_at": "2026-10-13T10:15:00.000000Z"
}
Status Meaning
failed No data has been received for this brand.
success_no_calculation Data is coming in, but no results have been calculated yet.
success_no_baseurl Data is coming in, but from a different URL than the base URL of the brand.
success The tag is installed and results are available.

{info} Every status that starts with success means the tag is installed. Check for the prefix instead of the exact value.

Conversion URLs

A conversion URL is a piece of text. Every page view with a URL that contains this text counts as a conversion.

Method Route Description
GET /brands/{identifier}/conversionUrls List the conversion URLs of a brand.
POST /brands/{identifier}/conversionUrls Add a conversion URL.
PUT /brands/{identifier}/conversionUrls/{id} Update a conversion URL.
DELETE /brands/{identifier}/conversionUrls/{id} Delete a conversion URL. Returns 204.
GET /brands/{identifier}/conversionUrls/aiSuggestions List suggested conversion URLs for a brand.

Body parameters for creating and updating

Parameter Type Required Description
string string Yes The text a URL must contain, for example /thank-you. At most 255 characters.

Broadcasts

A broadcast is one moment at which your advertisement aired.

Method Route Description
GET /broadcasts List the broadcasts of all brands you have access to.
GET /broadcasts/{id} Show one broadcast.
POST /broadcasts Create a broadcast.
PUT /broadcasts/{id} Update a broadcast.
DELETE /broadcasts/{id} Delete a broadcast. Returns 204.
POST /broadcasts/bulkStore Create or update several broadcasts at once.
POST /broadcasts/bulkDestroy Delete several broadcasts at once. Returns 204.

Query parameters for listing

Parameter Description
dateRange today, week, month or custom. Without this parameter all broadcasts are returned.
startDate Start of the period. Required when dateRange is custom.
endDate End of the period. Required when dateRange is custom.

Body parameters for creating and updating

Parameter Type Required Description
brand_identifier string Yes Identifier of the brand.
time datetime Yes Moment the advertisement aired, for example 2026-10-13 14:30:00.
timezone string Yes Timezone of time, for example Europe/Amsterdam.
name string No Name of the commercial. Needed for AB-testing.
channel string No Name of the channel. Needed for channel optimization.
impact_type string No What the impact score measures: grp, impressions or price.
impact_score number No The reach or price of this broadcast.
external_id string No The ID of this broadcast in your own system.

Response

{
    "id": 3401,
    "brand_id": 12,
    "name": "Spring commercial",
    "channel": "Radio One",
    "time": "2026-10-13 14:30:00",
    "end": "2026-10-13 14:35:00",
    "impact_type": "grp",
    "impact_score": 2.4,
    "external_id": "A-1001"
}

Sending several broadcasts at once

POST /broadcasts/bulkStore accepts a broadcasts array. Every item has the same parameters as a single broadcast, except that timezone is optional and defaults to UTC.

{
    "broadcasts": [
        {
            "brand_identifier": "ML-123456",
            "time": "2026-10-13 14:30:00",
            "timezone": "Europe/Amsterdam",
            "name": "Spring commercial",
            "channel": "Radio One",
            "external_id": "A-1001"
        }
    ]
}

If a broadcast with the same external_id already exists, it is updated instead of created again. This makes it safe to send a revised schedule more than once.

The response is the list of broadcasts that were created or updated.

{info} Items that do not pass validation are skipped without an error. Compare the number of broadcasts in the response to the number you sent.

POST /broadcasts/bulkDestroy accepts an ids array with the IDs of the broadcasts to delete.

Campaigns

A campaign is a period in which your advertisements ran. See Managing Campaigns.

Method Route Description
GET /campaigns List the campaigns of all brands you have access to.
GET /campaigns/{uuid} Show one campaign.
POST /campaigns Create a campaign.
PUT /campaigns/{uuid} Update a campaign.
DELETE /campaigns/{uuid} Delete a campaign. Returns 204.

Body parameters

Parameter Type Required Description
name string Yes Name of the campaign, at most 255 characters.
start datetime Yes Start of the campaign.
end datetime Yes End of the campaign. Must be after start.
uuid string When creating A unique UUID that you generate yourself. You use it to refer to the campaign afterwards.
brand_identifier string When creating Identifier of the brand.

Results

Method Route Description
GET /results/{identifier}/daily Results per day.
GET /results/{identifier}/hourly Results per hour.
GET /results/{identifier} Results per day, or per broadcast when type is instant.

Query parameters

Parameter Description
startDate See Dates and timezones.
endDate See Dates and timezones.
type The attribution method: extended (default) or instant.

Response

The response is an object with one entry per day (2026-10-13) or per hour (2026-10-13 14:00:00):

{
    "2026-10-13": {
        "broadcasts": 12,
        "visitors_in": 340,
        "visitors_out": 5120,
        "total_visitors": 5460,
        "average_in": 5.6,
        "average_out": 3.7,
        "uptick": 114,
        "regular_visitors": 5346,
        "conversions_total": 41,
        "conversions": 3,
        "conversions_out": 38,
        "conversions_ratio": 0.07
    }
}
Field Description
broadcasts Number of broadcasts.
visitors_in Website visitors during the time windows of your broadcasts.
visitors_out Website visitors outside those time windows.
total_visitors All website visitors.
average_in Average visitors per minute during broadcasts.
average_out Average visitors per minute outside broadcasts.
uptick Extra website visitors caused by your broadcasts.
regular_visitors Website visitors that are not attributed to your broadcasts.
conversions_total All conversions.
conversions Conversions attributed to your broadcasts.
conversions_out Conversions that are not attributed to your broadcasts.

When you request GET /results/{identifier} with type=instant, the response has one entry per broadcast. Each entry also contains a broadcast field with the broadcast itself.

Top pages

Method Route Description
GET /topPages/{identifier} The 10 most visited pages in the period.

Accepts startDate and endDate.

[
    {
        "domain": "https://example.com",
        "path": "/pricing",
        "total": 812
    }
]

Channel optimization

Method Route Description
GET /channel-optimization/{identifier}/table Performance per channel over the whole period.
GET /channel-optimization/{identifier}/graph Performance per channel per day.

Both accept startDate and endDate.

Response of the table

{
    "impactTypes": ["grp"],
    "showImpactScoreRatio": true,
    "tableData": [
        {
            "channel": "Radio One",
            "visitors": 214.5,
            "broadcasts": 38,
            "impact_score": 91.2,
            "visitors_per_broadcast": 5.64,
            "visitors_per_impact_score": 2.35
        }
    ]
}

The channels are sorted from best to worst performing. visitors_per_impact_score is only meaningful when all broadcasts in the period use the same impact type, which is the case when showImpactScoreRatio is true.

The graph route returns the same fields in graphData, with a data list per channel that holds one entry per day.

Creative studio

Method Route Description
POST /creative-studio/{identifier}/ab-test Compare the impact of two commercials.

Body parameters

Parameter Type Required Description
startDate date Yes First day of the period.
endDate date Yes Last day of the period.
commercialA string Yes Name of the first commercial, as used in name of your broadcasts.
commercialB string Yes Name of the second commercial.
attributionMethod string Yes extended or instant.

Response

{
    "commercial_names": { "commercialA": "Spring", "commercialB": "Summer" },
    "uptick_sums": { "commercialA": 120, "commercialB": 96 },
    "average_upticks": { "commercialA": 4.8, "commercialB": 3.2 },
    "num_broadcasts": { "commercialA": 25, "commercialB": 30 },
    "winner": "Spring",
    "winner_label": "A",
    "percentage_difference": 50
}

winner_label is A, B or DRAW. The winner is the commercial with the highest average number of extra visitors per broadcast.

Reach & ROI

Method Route Description
GET /roi/{identifier}/onTraffic Regular visitors and extra visitors per day.
GET /roi/{identifier}/returnOnConversions Regular conversions and mass media conversions per day.
GET /roi/{identifier}/reachToConversions Conversions and summed impact scores per day.
GET /roi/{identifier}/mediaPressure Broadcasts, reach and assumed conversions per channel.

Query parameters

Parameter Description
startDate See Dates and timezones.
endDate See Dates and timezones.
attributionMethod extended or instant. When left out, the method last used by the user is applied.

The first three routes return a dates list, with lists of values in the same order:

Route Fields
onTraffic dates, regularVisitors, uptick
returnOnConversions dates, regularConversions, massMediaConversions
reachToConversions dates, conversions, impactScores (one list per impact type)
{
    "dates": ["2026-10-12", "2026-10-13"],
    "regularVisitors": [5346, 5102],
    "uptick": [114, 98]
}

mediaPressure returns one row per channel in tableData. Reach is based on broadcasts with impact type grp.

{
    "tableData": [
        {
            "source": "Radio One",
            "broadcasts": 38,
            "reach": 91.2,
            "avg_reach": 2.4,
            "assumed_conversions": 11.5
        }
    ]
}

Indirect impact

Method Route Description
GET /indirectImpact/{identifier} Compare a campaign period to a period without a campaign.

Query parameters

Parameter Description
brand The id of the brand.
campaign The id of the campaign. Defaults to the most recent campaign of the brand.
compare Start date of the period to compare with. Defaults to a period of the same length right before the campaign.

Response

{
    "indirectVisitors": 1840,
    "indirectVisitorPercentage": 12.4,
    "indirectConversions": 22,
    "indirectConversionPercentage": 9.1,
    "conclusion": "positive"
}

conclusion is positive when there were more regular visitors than expected during the campaign, neutral when there were not, and invalid when there is no campaign or no period to compare with.