Apply a preview to selected ads
Queues the selected set ads from a preview of the saved config. The preview must be published (journal_ready: true), under 24 hours old, and match the saved config's generation, revision and fingerprint. A published truncated preview may be applied to its listed ads. Processing starts right away; ads go one at a time and what is left continues every 5 minutes, up to 4 minutes at a time. Follow the run with GET /meta/runs/{id}. Delivering ads may return to learning. In-review ads have no delivery or learning history yet, but tagging restarts review. A swapped ad can be IN_PROCESS at the next scan. Correct tags are skipped unless a destination still needs shortening. Before both creative creation and the ad swap, Mythic freshly checks the account, effective ad status, campaign rules and original creative. Changed or missing eligibility data leaves the ad stale. A failed read never authorizes a write.
Before swapping, a read-only verification compares every created, shared or recovered copy against a fresh original read, including the full story content (text, media, calls to action and carousel content), links, post identity where applicable, creative settings and planned URL parameters. Missing or changed content/settings fail closed with creative_copy_mismatch. No swap follows failed verification.
Unconfirmed writes are read back before considering at most one write retry. Retryable reads have a budget of three failures, with increasing backoff (5 then 10 minutes before the next attempt). Permanent read failures exhaust it immediately. Exhausted unresolved writes remain uncertain with read_retry_exhausted, stop automatic retries and leave the run partial when other work finishes. Manual intervention in Ads Manager is required. One apply or auto run per account at a time, including a cancelled run whose worker has not yet quiesced or whose lease plus grace period has not expired.
curl -X POST "https://mythic-analytics.gulp.workers.dev/client/v1/ad-tagging/meta/apply?location_id=example_string" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"preview_id": "123e4567-e89b-12d3-a456-426614174000",
"ad_ids": [
"120200000000000001"
],
"acknowledge_creative_swap": true
}'
import requests
import json
url = "https://mythic-analytics.gulp.workers.dev/client/v1/ad-tagging/meta/apply?location_id=example_string"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"preview_id": "123e4567-e89b-12d3-a456-426614174000",
"ad_ids": [
"120200000000000001"
],
"acknowledge_creative_swap": true
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://mythic-analytics.gulp.workers.dev/client/v1/ad-tagging/meta/apply?location_id=example_string", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"preview_id": "123e4567-e89b-12d3-a456-426614174000",
"ad_ids": [
"120200000000000001"
],
"acknowledge_creative_swap": true
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"preview_id": "123e4567-e89b-12d3-a456-426614174000",
"ad_ids": [
"120200000000000001"
],
"acknowledge_creative_swap": true
}`)
req, err := http.NewRequest("POST", "https://mythic-analytics.gulp.workers.dev/client/v1/ad-tagging/meta/apply?location_id=example_string", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://mythic-analytics.gulp.workers.dev/client/v1/ad-tagging/meta/apply?location_id=example_string')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"preview_id": "123e4567-e89b-12d3-a456-426614174000",
"ad_ids": [
"120200000000000001"
],
"acknowledge_creative_swap": true
}'
response = http.request(request)
puts response.body
{
"success": true,
"data": {
"run_id": "123e4567-e89b-12d3-a456-426614174000",
"run": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"kind": "preview",
"status": "completed",
"location_id": "example_string",
"ad_account_id": "example_string",
"config_generation": "123e4567-e89b-12d3-a456-426614174000",
"config_auto_approval_epoch": 42,
"config_revision": 42,
"config_fingerprint": "example_string",
"run_slot": "2024-12-25T10:00:00Z",
"journal_ready": true,
"ad_statuses_snapshot": [
"ACTIVE"
],
"rules_snapshot": {
"version": 42,
"operator": "AND",
"conditions": [
{
"type": "campaign_name_contains",
"value": "example_string",
"case_sensitive": true
}
]
},
"template_snapshot": "example_string",
"overwrite_snapshot": "fill_missing",
"short_links_snapshot": true,
"resolve_names_snapshot": true,
"attempts": 42,
"source_preview_id": "123e4567-e89b-12d3-a456-426614174000",
"truncated": true,
"truncation_reason": "example_string",
"campaigns_scanned": 42,
"campaigns_matched": 42,
"ads_scanned": 42,
"ads_planned": 42,
"ads_applied": 42,
"ads_failed": 42,
"ads_uncertain": 42,
"ads_skipped": 42,
"ads_stale": 42,
"expires_at": "2024-12-25T10:00:00Z",
"error_code": "unauthorized",
"error_message": "example_string",
"requested_by": "example_string",
"created_at": "2024-12-25T10:00:00Z",
"started_at": "2024-12-25T10:00:00Z",
"finished_at": "2024-12-25T10:00:00Z"
}
}
}
{
"error": "Bad Request",
"message": "The request contains invalid parameters or malformed data",
"code": 400,
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
{
"error": "Forbidden",
"message": "You don't have permission to access this resource",
"code": 403
}
{
"error": "Not Found",
"message": "The requested resource was not found",
"code": 404
}
{
"error": "Conflict",
"message": "The request conflicts with the current state of the resource",
"code": 409,
"details": "Resource already exists"
}
{
"error": "Service Unavailable",
"message": "The service is temporarily unavailable. Please try again later",
"code": 503
}
/client/v1/ad-tagging/meta/apply
Target server for requests. Edit to use your own host.
Agency key (ak_) or location secret key (sk_, reads of the config and runs only). Scoped keys (mcp_) are accepted too and need ad_tagging:read or ad_tagging:write. See Using an mcp_ key over HTTP.
ak_) or location secret key (sk_, reads of the config and runs only). Scoped keys (mcp_) are accepted too and need ad_tagging:read or ad_tagging:write. See Using an mcp_ key over HTTP.Location to scope to. Required for ak_ keys or send X-Location-Id. Ignored for sk_.
The media type of the request body
Must be true: a new creative is created and swapped onto each ad.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Agency key (ak_) or location secret key (sk_, reads of the config and runs only). Scoped keys (mcp_) are accepted too and need ad_tagging:read or ad_tagging:write. See Using an mcp_ key over HTTP.
Query Parameters
Location to scope to. Required for ak_ keys or send X-Location-Id. Ignored for sk_.
Body
Must be true: a new creative is created and swapped onto each ad.
true