Send events from your application
Events are sent server to server. Adding the MCP connection does not install a website pixel, connect your CRM, or start a data feed.- Select the owning advertiser. A buyer account’s
/mcp/v3connection or V3 HTTP API credential can do every step below. - Register the source with
save_event_source. Use a stableeventSourceId; each entry creates the source if it is new and updates it if it exists, so other sources are left alone. - Inspect the returned
setupobject. The current setup isserver_only: your backend sends the events; the response does not contain a browser snippet to install. - Send events with
log_event: theadvertiserId, the registeredeventSourceId, anidempotencyKey, and up to 10,000 events in the AdCPEventshape. Give each event a stableevent_idand include the event time and supported identity fields. Each event must be a valid AdCPEvent. When an event hasuser_match, it must name at least one identifier:uids,hashed_email,hashed_phone,click_id, or bothclient_ipandclient_user_agent, anduids, when sent, must hold at least one entry. Awatch_milestoneevent must carrycustom_data.progress_percentorcustom_data.progress_seconds. Events must also pass two more rules: no raw email address or phone number inuser_match,surface, orcustom_data.content_name,content_categoryandsearch_string(sendhashed_emailorhashed_phoneinuser_match), and eachevent_typeandevent_idpair once per call.content_name,content_categoryandsearch_stringare limited to 256 characters. The whole call is refused if any event is invalid, if the source is not registered on that advertiser, or if the source does not accept an event’s type. A resend in a later call is deduplicated. If an event carries AdCP fields Apostra does not store yet, such assurface, the call still succeeds and the response’singestion.warningsnames them. - Send a fixture with
testEventCode. The code is forwarded to the tracking service to mark the call as test traffic. Check the response’s received and processed counts and warnings. - Enable production sending and check the source’s health with
get(kind: "event_source"). Keep the upstream event ID on retries so an event is not counted twice.
measurement-data/sync as documented in the measurement guide. Do not turn an
aggregate into invented individual events. Ingestion creates evidence only for
the data actually submitted; it does not make seller delivery equivalent to
conversion measurement.
Import an approved creative
Your application can create content with its own provider, retain the approved version, and bring that finished asset into Apostra.- Select the advertiser and campaign that will own the work.
- Read the selected inventory’s accepted creative formats before choosing a final rendition.
- Use the supported HTTPS asset URL, inline data URL, or finalized upload
reference in the current
save_creativeschema. Upload references have ownership and format constraints; use the documented upload flow for the asset you have. For a VAST tag or inline VAST XML, set the asset’svastVersion: a managed ad server cannot take a tag whose version is neither declared nor readable when it is saved. See Declare a VAST tag’s version. - For a third-party display tag from an ad server, send an AdCP
display_tagasset inassets, not anHTMLasset. The next section shows the three delivery forms. - Read the saved creative, associate it with the intended buying work, and inspect destination review and readiness before launch.
sourceAssetRef is write-only. A creative read returns the durable asset it
resolved to as sourceAssetId and slotId on the existing flat assets
entry, never the private reference. To save that source again, pass those
values as a sourceAssets entry with kind: "asset_id" and slot. The read
also returns its durable format selection as formatKind with formatParams
and/or formatOptionRef; use that selection on the re-save rather
than preserving creativeFormatId.
get with kind: "creative" also returns assetsBySlot when the creative
has URL-addressable image, video, or click-URL slots. Its keys are the stored
slot IDs and its values use AdCP asset fields such as asset_type, url,
file_size_bytes, and duration_ms. The existing flat assets list remains
available unchanged. A slotted inline HTML asset is returned there as AdCP’s
html asset with its content, and a slotted HTML5 bundle as AdCP’s zip
asset with its public delivery url. HTML larger than 256 KiB, or that
Apostra cannot read, keeps its entry in the flat assets list and is not
returned as html. A third-party tag is read as a display_tag asset in
assets; see Read a third-party display tag.
The exact import and association examples are in
Buyer workflows and
Bring your own creative.
Saving a creative imports content; it does not generate or revise it.
Creative Engines has separate availability
limits, and its discovery and connection tools do not themselves start a
generation session.
Save a third-party display tag
A tag an ad server such as Campaign Manager 360 gave you is an AdCPdisplay_tag asset. save_creative takes it in assets, with AdCP’s own
snake_case fields, in one of three delivery forms set by delivery_type:
Each form can also carry
macro_declarations, AdCP’s list of the macros in the
tag, such as [APIFRAMEWORKS] or ${GDPR}. Apostra stores them as sent. The
creative’s format is display_tag, so formatKind can be left out.
formatParams with width and height, as above, or declare
a responsive range.
Apostra stores all three forms. A paired_redirect can be sent only where the
seller’s chosen display_tag option declares paired_redirect in
supported_delivery_types and the seller negotiates AdCP 3.2. Apostra sends
the ad-request URL and click-through URL together, byte for byte; it does not
wrap, split, or revise either one. tag_url delivery is not available yet, so
saving one returns a tag_not_sendable entry in readinessWarnings.
A save that sends formatKind: "display_tag" with an HTML asset is refused,
and the error names the display_tag asset. An HTML asset sent without
formatKind: "display_tag" is still inline HTML. Creatives already saved the
old way are not changed. A creative holds one display_tag asset, and it cannot
sit beside an HTML asset or sourceAssets.
Read a third-party display tag
get with kind: "creative" returns a tag in assets as the same AdCP
display_tag asset save_creative takes, with its delivery_type,
markup_type, URLs and macro_declarations as they were saved. An
inline_markup tag carries its markup byte for byte. Saving that asset back
as a new creative stores the same tag.
display_tag asset only for a creative that has a saved
tag record. A tag saved before save_creative took display_tag assets has a
record only if Apostra could place its markup type, from the Campaign Manager
360 column of a tag sheet or from the markup’s structure. Campaign Manager 360
uses the same <ins> markup for its “Iframes/JavaScript” and “JavaScript”
tags, so Apostra does not guess which one a tag is. A tag without a record is
read as it was before: an HTML entry in assets with its assetId,
contentType, size and slot, and no markup, delivery type or markup type.
AdCP’s inline_markup form requires a markup_type, so a tag without a
recorded type cannot be returned as display_tag. It stays that way until
someone classifies it.
Connect seller inventory
From the intended Seller Account, readget_status and search
inventory_source to inspect existing setup. Use save_inventory_source for
the source’s typed, non-secret configuration. Complete credentials or OAuth in
the relevant interactive Page rather than passing provider secrets to a model.
A sales agent is added only as one of your organization’s agents or a
certified partner’s, never from an endpoint alone; see
Connect to a partner agent.
Read the source with get, requesting include: ["diagnostics"] where
supported. For modular sources, include: ["modularReadiness"] shows the
attached modules and lifecycle coverage. A configured connection is not proof
of a successful live call: get returns recorded state and does not probe the
ad server.
Follow Add and diagnose inventory
for the appropriate connection test and readiness steps. Then use the
own-supply sandbox workflow
to verify the transaction path without spending. Configuring an inventory
source does not automatically publish it or satisfy live campaign readiness.
Add seller materials
Usesave_material to register a URL, site, upload, crawl manifest, inline
text, or historical source. For an upload, follow its preparation, byte upload,
and finalization lifecycle; submitting metadata alone does not upload a file.
For rate-card metadata, send kind: "buyer_scoped_rate_card" when supplying a
buyer scope, otherwise send kind: "unscoped". A scoped buyerScope likewise
uses kind: "operator" or "brand"; send only the fields for that scope.
When an upload create request has the same SHA-256 bytes as a non-archived
Material in the same Seller Account, save_material returns that Material
instead of creating a second copy. The response includes alreadyExisted: true,
materialName, and materialState (draft or live). A matched Live
Material is not changed. A matched Draft receives only the reviewNote and
explicit displayName supplied by that request; an attachment filename used as
a fallback does not rename it. Identical bytes in another Seller Account are
not a match.
Read the Material until processing reaches a terminal state, then inspect the
extracted candidates and provenance. Review each candidate through the typed
tool that owns its destination. Material-owned decisions use save_material;
inventory, playbook, or other business records use their returned owner tools.
An uploaded rate card is source evidence, not automatic approval to change
published prices.
See Add and inspect seller material
for exact upload requests, processing states, and candidate decisions. Some
library actions require the sales-library rollout; use the tools and
capabilities your account advertises.
Delete a connected document from Apostra (beta)
For the betasave_material preview, delete, and Undo calls, including their
exact inputs and the destructive-effect warning, see
Delete from Apostra. That page is the Storefront
deletion guide for connected Library documents.
Once your data is arriving, use Build a reporting pipeline
to read the appropriate results back into your product.