How to Use GPT-6 Sol for Ad Copy Variants at Low Cost
Your brand guidelines are 1,500 tokens long, and you are about to pay to send them 200 times. Don't. By the end of this guide you will have a script that generates ad copy variants with GPT-6 Sol, reuses a cached brand-voice prefix, and prints what each batch cost. The rates below come from OpenAI's pricing page and API changelog, where GPT-6 Sol (gpt-6-sol) shipped on September 29.
What GPT-6 Sol costs for ad copy
Standard pricing for prompts up to 272K input tokens is $2 per million input tokens and $10 per million output tokens. Cached input is billed at a fraction of the input rate, and the Batch API takes 50% off. Ad copy is short, so output tokens are the bill you can't cache away.
The changelog and the pricing page disagreed on the cached input rate when I checked ($0.10 versus $0.20 per million). The cost script below uses $0.20, the higher figure, and keeps the rate in one variable. Check the pricing page before you trust any estimate.
Build the cached brand-voice prefix
Prompt caching matches on the start of your request. Put everything that never changes first: voice rules, banned words, example ads, character limits. Put the per-product details last.
For GPT-5.6 and later models, the prompt caching guide says the minimum cacheable prefix is 1,024 input tokens and that implicit caching is automatic. A 1,500-token brand prefix clears that bar.
BRAND_VOICE = """You write ad copy for Acme Outdoor.
Voice: dry, confident, never shouty. No exclamation marks.
Banned words: revolutionary, game-changing, ultimate.
Limits: headline max 30 characters, body max 90 characters.
Examples of approved ads:
- Headline: Boots that outlast the trail | Body: Waterproof leather, resoleable, built for a decade of mud.
(... paste your full guidelines and 8-10 approved examples here ...)
"""
Paste your real guidelines in. If the prefix is under 1,024 tokens, nothing caches and you pay full price every call.
Generate ad copy variants with the API
Ask for several variants per call, as structured JSON, so you can load results straight into a spreadsheet or ad platform. The prompt_cache_key groups related requests so they share cache accounting.
import json
from openai import OpenAI
client = OpenAI() # reads OPENAI_API_KEY
schema = {
"type": "object",
"properties": {
"variants": {
"type": "array",
"items": {
"type": "object",
"properties": {
"headline": {"type": "string"},
"body": {"type": "string"},
},
"required": ["headline", "body"],
"additionalProperties": False,
},
}
},
"required": ["variants"],
"additionalProperties": False,
}
def make_variants(product, angle, n=5):
return client.responses.create(
model="gpt-6-sol",
instructions=BRAND_VOICE, # static prefix first
input=f"Product: {product}\nAngle: {angle}\nWrite {n} variants.",
prompt_cache_key="acme-brand-voice-v1",
text={"format": {"type": "json_schema", "name": "ad_variants",
"schema": schema, "strict": True}},
)
resp = make_variants("Trail Runner 2 boots", "durability")
print(json.loads(resp.output_text)["variants"][0])
The schema forces every variant to have a headline and body. Validate the character limits in code afterward, because a schema can't count characters for you.
Check the cache is working
The first call writes the cache, so judge from the second call onward. Read the usage field, as described in the caching guide.
u = resp.usage
cached = u.input_tokens_details.cached_tokens
print(f"input={u.input_tokens} cached={cached} output={u.output_tokens}")
If cached stays at 0 on repeat calls, something in your prefix is changing between requests. A timestamp or product name inside BRAND_VOICE is the usual culprit.
Estimate the cost of 1,000 variants
At 5 variants per call, 1,000 variants is 200 calls. Assume a 1,500-token prefix, 100 unique input tokens and 400 output tokens per call.
IN, CACHED_IN, OUT = 2.00, 0.20, 10.00 # USD per 1M tokens, verify on pricing page
calls, prefix, unique, out = 200, 1500, 100, 400
uncached = (calls * (prefix + unique) * IN + calls * out * OUT) / 1e6
cached = (calls * prefix * CACHED_IN + calls * unique * IN + calls * out * OUT) / 1e6
print(f"no cache: ${uncached:.2f} with cache: ${cached:.2f} per 1,000 variants")
That prints about $1.44 without caching and $0.90 with it, assuming every call after the first hits the cache. Output tokens are $0.80 of both totals, which is why a longer prefix is cheap and chatty output is not. Keep variants short and don't ask for explanations.
If nobody needs the copy this hour, the Batch API is billed at 50% of standard rates. Don't assume the cached discount stacks on top of that.
Where GPT-6 Sol fits versus pricier models
Ad variants are a short-output, high-volume job with a style guide, which suits a mid-priced model. GPT-6 Sol is positioned in the changelog as a lower-cost option than GPT-6 Astra for complex work. Start on Sol, have a human score 50 outputs against your guidelines, and only move up if the failures are about voice, not formatting. If you want to send easy jobs to a cheaper tier automatically, see our piece on routing between Sol and Luna by cost.
Gotchas
- Prefix drift: one changed character early in the prefix invalidates the cache from that point on.
- Cache lifetime: the guide lists a 30 minute TTL for GPT-5.6 and later, so a slow overnight trickle of calls won't benefit.
- Long prompts: above 272K input tokens the whole request moves to higher long-context rates.
- Promotional pricing: the pricing page mentions promotional pricing through at least November 21, 2026. Re-run your estimate after that.
- Compliance: variants are still your brand speaking. Run claims and legal checks before anything goes live.
Cache the part that never changes, pay for the part that does, and your ad copy budget stops scaling with the length of your style guide, which is what keeps this affordable when a campaign goes from 50 variants to 5,000.