Skip to main content

Artifacts

An artifact is a unit of content adjacent to an ad placement. When evaluating brand suitability, you’re asking: “Is this artifact appropriate for my brand’s ads?”

What Is an Artifact?

Artifacts represent the content context where an ad appears:
  • A news article on a website
  • A podcast segment between ad breaks
  • A video chapter in a YouTube video
  • A social media post in a feed
  • A scene in a CTV show
  • An AI-generated image in a chat conversation
Artifacts are identified by property_id + artifact_id - the property defines where the content lives, and the artifact_id is an opaque identifier for that specific piece of content. The artifact_id scheme is flexible - it could be a URL path, a platform-specific ID, or any consistent identifier the property owner uses internally.

Structure

Schema: artifact.json
{
  "property_id": {"type": "domain", "value": "reddit.com"},
  "artifact_id": "r_fitness_post_abc123",
  "assets": [
    {"type": "text", "role": "title", "content": "Best protein sources for muscle building", "language": "en"},
    {"type": "text", "role": "paragraph", "content": "Looking for recommendations on high-quality protein sources...", "language": "en"},
    {"type": "image", "url": "https://cdn.reddit.com/fitness-image.jpg", "alt_text": "Person lifting weights"}
  ]
}

Required Fields

FieldDescription
property_idWhere this artifact lives - uses standard identifier types (domain, app_id, apple_podcast_id, etc.)
artifact_idUnique identifier within the property - the property owner defines their scheme
assetsContent in document order - text blocks, images, video, audio

Optional Fields

FieldDescription
variant_idIdentifies a specific variant (A/B test, translation, temporal version)
format_idReference to format registry (same as creative formats)
urlWeb URL if the artifact has one
metadataArtifact-level metadata (Open Graph, JSON-LD, author info)
published_timeWhen the artifact was published
last_update_timeWhen the artifact was last modified

Variants

The same artifact may have multiple variants:
  • Translations - English version vs Spanish version
  • A/B tests - Different headlines being tested
  • Temporal versions - Content that changed on Wednesday
Use variant_id to distinguish between them:
// English version
{
  "property_id": {"type": "domain", "value": "nytimes.com"},
  "artifact_id": "article_12345",
  "variant_id": "en",
  "assets": [
    {"type": "text", "role": "title", "content": "Breaking News Story", "language": "en"}
  ]
}

// Spanish translation
{
  "property_id": {"type": "domain", "value": "nytimes.com"},
  "artifact_id": "article_12345",
  "variant_id": "es",
  "assets": [
    {"type": "text", "role": "title", "content": "Noticia de última hora", "language": "es"}
  ]
}

// A/B test variant
{
  "property_id": {"type": "domain", "value": "nytimes.com"},
  "artifact_id": "article_12345",
  "variant_id": "headline_test_b",
  "assets": [
    {"type": "text", "role": "title", "content": "Alternative Headline Being Tested", "language": "en"}
  ]
}
The combination of artifact_id + variant_id must be unique within a property. This lets you track which variant a user saw and correlate it with delivery reports.

Asset Types

Assets are the actual content within an artifact. Everything is an asset - titles, paragraphs, images, videos.

Text

{"type": "text", "role": "title", "content": "Article Title", "language": "en"}
{"type": "text", "role": "paragraph", "content": "The article body text...", "language": "en"}
{"type": "text", "role": "description", "content": "A summary of the article", "language": "en"}
{"type": "text", "role": "heading", "content": "Section Header", "heading_level": 2}
{"type": "text", "role": "quote", "content": "A quoted statement"}
Roles: title, description, paragraph, heading, caption, quote, list_item Each text asset can have its own language tag for mixed-language content.

Image

{
  "type": "image",
  "url": "https://cdn.example.com/photo.jpg",
  "alt_text": "Description of the image"
}

Video

{
  "type": "video",
  "url": "https://cdn.example.com/video.mp4",
  "transcript": "Full transcript of the video content...",
  "duration_ms": 180000
}

Audio

{
  "type": "audio",
  "url": "https://cdn.example.com/podcast.mp3",
  "transcript": "Today we're discussing...",
  "duration_ms": 3600000
}

Metadata

Artifact-level metadata describes the artifact as a whole, not individual assets:
{
  "metadata": {
    "author": "Jane Smith",
    "canonical": "https://example.com/article/12345",
    "open_graph": {
      "og:type": "article",
      "og:site_name": "Example News"
    },
    "json_ld": [
      {
        "@type": "NewsArticle",
        "datePublished": "2025-01-15"
      }
    ]
  }
}
This is separate from assets because it’s about the artifact container, not the content itself.

Secured Asset Access

Many assets aren’t publicly accessible - AI-generated images, private conversations, paywalled content. The artifact schema supports authenticated access. For ongoing partnerships, configure access once during onboarding rather than per-request:
  1. Service account sharing - Grant the verification agent access to your cloud storage
  2. OAuth client credentials - Set up machine-to-machine authentication
  3. API key exchange - Share long-lived API keys during setup
This happens during the activation phase when the seller first receives content standards from a buyer.

Per-Asset Authentication

When pre-configuration isn’t possible, include access credentials with individual assets:
{
  "type": "image",
  "url": "https://cdn.openai.com/secured/img_abc123.png",
  "access": {
    "method": "bearer_token",
    "token": "eyJhbGciOiJIUzI1NiIs..."
  }
}
Note on token size: For artifacts with many assets, per-asset tokens can significantly increase payload size. Consider:
  1. Pre-configured access - Set up service account access once during onboarding
  2. Shared token reference - Define tokens at the artifact level and reference by ID
  3. Signed URLs - Use pre-signed URLs where the URL itself is the credential
The url field is the access URL - it may differ from the artifact’s canonical/published URL. For example, a published article at https://news.example.com/article/123 might have assets served from https://cdn.example.com/secured/....

Access Methods

MethodUse Case
bearer_tokenOAuth2 bearer token in Authorization header
service_accountGCP/AWS service account credentials
signed_urlPre-signed URL with embedded credentials (URL itself is the credential)

Service Account Setup

For GCP:
{
  "access": {
    "method": "service_account",
    "provider": "gcp",
    "credentials": {
      "type": "service_account",
      "project_id": "my-project",
      "private_key_id": "...",
      "private_key": "-----BEGIN PRIVATE KEY-----\n...",
      "client_email": "verification-agent@my-project.iam.gserviceaccount.com"
    }
  }
}
For AWS:
{
  "access": {
    "method": "service_account",
    "provider": "aws",
    "credentials": {
      "access_key_id": "AKIAIOSFODNN7EXAMPLE",
      "secret_access_key": "...",
      "region": "us-east-1"
    }
  }
}

Pre-Signed URLs

For one-off access without sharing credentials:
{
  "type": "video",
  "url": "https://storage.googleapis.com/bucket/video.mp4?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=...&X-Goog-Signature=...",
  "access": {
    "method": "signed_url"
  }
}
The URL itself contains the credentials - no additional authentication needed.

Property Identifier Types

The property_id uses standard identifier types from the AdCP property schema:
TypeExampleUse Case
domainreddit.comWebsites
app_idcom.spotify.musicMobile apps
apple_podcast_id1234567890Apple Podcasts
spotify_show_id4rOoJ6Egrf8K2IrywzwOMkSpotify podcasts
youtube_channel_idUCddiUEpeqJcYeBxX1IVBKvQYouTube channels
rss_urlhttps://feeds.example.com/podcast.xmlRSS feeds

Artifact ID Schemes

The property owner defines their artifact_id scheme. Examples:
Property TypeArtifact ID PatternExample
News websitearticle_{id}article_12345
Redditr_{subreddit}_{post_id}r_fitness_abc123
Podcastepisode_{num}_segment_{num}episode_42_segment_2
CTVshow_{id}_s{season}e{episode}_scene_{num}show_abc_s3e5_scene_12
Social feedpost_{id}post_xyz789
The verification agent doesn’t need to understand the scheme - it’s opaque. The property owner uses it to correlate artifacts with their content.