Generate ad prompts
Writes 1-5 ad briefs from the client's brand and its competitors' working ads (running 30+ days, weighted by days running; ads under 30 days are never evidence), plus the client's own top creatives when that feature is available. Runs on the agency's own model key (BYOK, the same key as scouts); Mythic pays for no model call. The answer is checked against the prompt schema, the E.P.I.C. rules and the grounding ids, repaired once, then refused. 20 per client per rolling 24 hours. Agency keys or competitor_ads:write. Can take a few minutes.
curl -X POST "https://mythic-analytics.gulp.workers.dev/client/v1/competitor-ads/ad-prompts?location_id=example_string" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"brand": {
"product": "example_string",
"audience": "example_string",
"benefits": [
"example_string"
],
"angles": [
"example_string"
],
"proof": [
"example_string"
],
"offers": [
"example_string"
],
"must_avoid": [
"example_string"
],
"compliance": "example_string"
},
"angles": [
"example_string"
],
"count": 10,
"rewrite_ad_id": "123e4567-e89b-12d3-a456-426614174000",
"formats": [
"copy"
],
"include_own_creatives": true
}'
import requests
import json
url = "https://mythic-analytics.gulp.workers.dev/client/v1/competitor-ads/ad-prompts?location_id=example_string"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"brand": {
"product": "example_string",
"audience": "example_string",
"benefits": [
"example_string"
],
"angles": [
"example_string"
],
"proof": [
"example_string"
],
"offers": [
"example_string"
],
"must_avoid": [
"example_string"
],
"compliance": "example_string"
},
"angles": [
"example_string"
],
"count": 10,
"rewrite_ad_id": "123e4567-e89b-12d3-a456-426614174000",
"formats": [
"copy"
],
"include_own_creatives": true
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://mythic-analytics.gulp.workers.dev/client/v1/competitor-ads/ad-prompts?location_id=example_string", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"brand": {
"product": "example_string",
"audience": "example_string",
"benefits": [
"example_string"
],
"angles": [
"example_string"
],
"proof": [
"example_string"
],
"offers": [
"example_string"
],
"must_avoid": [
"example_string"
],
"compliance": "example_string"
},
"angles": [
"example_string"
],
"count": 10,
"rewrite_ad_id": "123e4567-e89b-12d3-a456-426614174000",
"formats": [
"copy"
],
"include_own_creatives": true
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"brand": {
"product": "example_string",
"audience": "example_string",
"benefits": [
"example_string"
],
"angles": [
"example_string"
],
"proof": [
"example_string"
],
"offers": [
"example_string"
],
"must_avoid": [
"example_string"
],
"compliance": "example_string"
},
"angles": [
"example_string"
],
"count": 10,
"rewrite_ad_id": "123e4567-e89b-12d3-a456-426614174000",
"formats": [
"copy"
],
"include_own_creatives": true
}`)
req, err := http.NewRequest("POST", "https://mythic-analytics.gulp.workers.dev/client/v1/competitor-ads/ad-prompts?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/competitor-ads/ad-prompts?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 = '{
"brand": {
"product": "example_string",
"audience": "example_string",
"benefits": [
"example_string"
],
"angles": [
"example_string"
],
"proof": [
"example_string"
],
"offers": [
"example_string"
],
"must_avoid": [
"example_string"
],
"compliance": "example_string"
},
"angles": [
"example_string"
],
"count": 10,
"rewrite_ad_id": "123e4567-e89b-12d3-a456-426614174000",
"formats": [
"copy"
],
"include_own_creatives": true
}'
response = http.request(request)
puts response.body
{
"success": true,
"data": {
"generation_id": "123e4567-e89b-12d3-a456-426614174000",
"prompts": [
{
"title": "example_string",
"concept": {
"angle": "example_string",
"hook": "example_string",
"primary_text": "example_string",
"headline": "example_string",
"cta": "example_string",
"landing_page": "example_string",
"sources": {
"competitor_ad_ids": [
"123e4567-e89b-12d3-a456-426614174000"
],
"own_creative_ids": [
"example_string"
]
}
},
"image_prompt": {
"layout": "example_string",
"subject": "example_string",
"text_overlay": "example_string",
"aspect_ratio": "1:1",
"prompt": "example_string"
},
"video": {
"duration_s": 42,
"beats": [
{
"t_start": 3.14,
"t_end": 3.14,
"stage": "E",
"visual": "example_string",
"voiceover": "example_string",
"on_screen_text": "example_string"
}
],
"shot_list": [
{
"shot": 42,
"framing": "example_string",
"description": "example_string"
}
]
},
"ugc_brief": {
"creator": "example_string",
"setting": "example_string",
"talking_points": [
"example_string"
],
"dos": [
"example_string"
],
"donts": [
"example_string"
]
},
"rewrite": {
"source_ad_id": "123e4567-e89b-12d3-a456-426614174000",
"original_structure": {
"format": "example_string",
"length": "example_string",
"stage_order": "EPIC"
},
"sections": [
{
"part": "headline",
"stage": "E",
"original": "example_string",
"rewrite": "example_string",
"change_note": "example_string"
}
]
}
}
],
"grounding": {
"competitor_ad_ids": [
"123e4567-e89b-12d3-a456-426614174000"
],
"own_creative_ids": [
"example_string"
],
"rewrite_ad_id": "123e4567-e89b-12d3-a456-426614174000",
"own_creatives": {
"available": true,
"reason": "creative_analysis_not_in_plan"
},
"working_ads": 42,
"new_tests": 42,
"dropped_for_size": 42
},
"provider": "openrouter",
"model": "example_string",
"key_scope": "location",
"repaired": true,
"usage": {
"model_calls": 42,
"input_tokens": 42,
"output_tokens": 42,
"cost_usd": 3.14,
"cost_usd_known": 3.14,
"usage_complete": true
},
"record": {
"saved": true,
"prompts_saved": true
}
}
}
{
"error": "Bad Request",
"message": "The request contains invalid parameters or malformed data",
"code": 400,
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
{
"error": "Error",
"message": "Error. The code names the cause, e.g. `invalid_page`, `feature_not_in_plan`, `agency_required`, `not_found`, `scraper_failed`, `no_model_key`, `no_working_ads`, `grounding_too_large`, `generation_invalid`.",
"code": 402
}
{
"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": "Unprocessable Entity",
"message": "The request was well-formed but contains semantic errors",
"code": 422,
"details": [
{
"field": "password",
"message": "Password must be at least 8 characters long"
}
]
}
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Please try again later",
"code": 429,
"retryAfter": 3600
}
{
"error": "Error",
"message": "Error. The code names the cause, e.g. `invalid_page`, `feature_not_in_plan`, `agency_required`, `not_found`, `scraper_failed`, `no_model_key`, `no_working_ads`, `grounding_too_large`, `generation_invalid`.",
"code": 502
}
/client/v1/competitor-ads/ad-prompts
Target server for requests. Edit to use your own host.
Agency key (ak_), location secret key (sk_, reads only) or a scoped mcp_ key with competitor_ads:read or competitor_ads:write. See Using an mcp_ key over HTTP.
ak_), location secret key (sk_, reads only) or a scoped mcp_ key with competitor_ads:read or competitor_ads: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
Angles to focus on.
Competitor ad id to rewrite in place on the first prompt. Default when rewrite is in formats: the top working ad.
Parts to write. copy is always included. Default: all but rewrite, or all when rewrite_ad_id is set.
Ground on the client's own top ads by spend. Needs the creative analysis plan feature, and creative_analysis:read on an mcp_ key.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Agency key (ak_), location secret key (sk_, reads only) or a scoped mcp_ key with competitor_ads:read or competitor_ads: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
Angles to focus on.
Competitor ad id to rewrite in place on the first prompt. Default when rewrite is in formats: the top working ad.
Parts to write. copy is always included. Default: all but rewrite, or all when rewrite_ad_id is set.
Ground on the client's own top ads by spend. Needs the creative analysis plan feature, and creative_analysis:read on an mcp_ key.