# $1,100 in Ads, 0 Paid Orders: How Khue Tran ran OpenAI's ad beta with Claude Code and found the feed was what paid

Khue Tran gave Claude Code standing authority to build the tooling and run OpenAI Ads (beta) for the three US wholesale nail-supply Shopify stores he runs, through the Ads Management API. He keeps the budget policy and signs off on anything that moves money. The agent built a product feed pushed over SFTP every 12 hours and an hourly server-side conversions (CAPI) sync. It also pauses stray campaigns, checks landing URLs and sends him a daily return-on-ad-spend report on Telegram. After roughly $1,100 of beta spend he reports 0 cleanly-attributable paid orders, while the same feed brought in free organic ChatGPT orders, and he says the agent reached two confident conclusions that the raw numbers later contradicted.

| | |
|---|---|
| **Who** | Khue Tran, ecom operator from Hanoi with 15+ years in performance marketing. He runs three US wholesale nail-supply Shopify stores, called Store A, Store B and Store C in the build log. LinkedIn: [/in/khuetran](https://www.linkedin.com/in/khuetran) (verified 2026-11-08: linked from khuetran.com header/footer) |
| **Problem** | Testing OpenAI's new ad platform across three stores without operating it by hand, and measuring whether it pays |
| **Stack** | Claude Code, OpenAI Ads Management API, OpenAI Conversions API (CAPI) on an hourly cron on a cheap VPS, Shopify, a .jsonl.gz product feed over SFTP, Telegram, a curl user-agent to get past Cloudflare |
| **Confidence** | Medium (first-person, first-party numbers; paid zero is partly an attribution gap; beta changing week to week) |
| **Last verified** | 2026-11-08 |

## The problem
Khue runs performance marketing for three wholesale nail-supply Shopify stores aimed at the US market. He works in Google Ads, Meta, Klaviyo and Shopify every day. He writes, "I am not a trained developer." He vibe-codes small tools with AI to run his own stack. When OpenAI opened its Ads Manager beta with an Ads Management API, he wired it up himself. This time he did not operate it by hand. He handed day-to-day operation to an agent and kept the decisions that cost money for himself.

## The blueprint (as he describes it)
1. **Split the work between agent and human.** Claude Code has standing authority to build the tooling and run all three accounts. He keeps the budget policy and signs off before any change that moves money. His budget policy is $100/day/store to start, scaling up only when return on ad spend clears a real threshold. He writes, "Turning on spend is not, so that stays a human decision." He also writes that the agent "is not a substitute for a human reading the results with suspicion."
2. **Pause what you did not build.** New accounts auto-create a starter campaign that can start spending. On two stores those defaults burned $255 and $253 at about $3.50 to $4.00 per click, with zero orders and zero tracking, before he paused them. The fix is two calls: `GET /v1/campaigns?limit=50` and `POST /v1/campaigns/{id}/pause`. The agent now does this automatically before it creates anything.
3. **Get past Cloudflare.** Calling the API from Python with the default user-agent gets blocked by Cloudflare with Error 1010 before the request reaches OpenAI. The fix is to use curl or set a browser or curl user-agent. Account timezones are fixed to America/Los_Angeles, so his reports read in Pacific time.
4. **Wire conversions.** He attaches the order_created event (30-day attribution window, tied to a pixel) to each campaign at create time. CAPI uses a separate conversion key on a different host from the Ads Management key. Amounts go in cents. He dedups on the Shopify numeric order id and hashes the email with sha256 of the lowercased address. A validate_only mode lets him test without polluting real data. The agent runs this as a small cron on a cheap VPS. Once an hour it reads new Shopify orders, hashes the email and posts the events, with incremental state, a 30-minute overlap and a 7-day window. The initial backfill sent 614 orders for the first store. He has a Shopify custom pixel too but does not let it fire order_created, because CAPI and the pixel would then double-count the same purchase.
5. **Build the product feed.** The feed is a full-catalog .jsonl.gz file, one product-variant per line. For the first store that is about 19,700 products and 27,100 variants. It is pushed over SFTP to OpenAI's ingest host, overwriting the same filename. A status.json at the SFTP root is the health check. The agent's builder writes only in-stock variants as is_ads_eligible, so restocked items turn back on at the next refresh. It marks items is_eligible_search, the flag for ChatGPT's free organic shopping surface. It also appends UTMs, which he later found futile. A cron rebuilds and re-uploads the snapshot every 12 hours.
6. **Build two campaign types.** Chat cards are a single card with an image, headline and URL inside a ChatGPT conversation. The image is uploaded by URL, and each ad group carries context_hints that steer where the card shows. He built one ad group per collection theme, six per store, each with its own UTM. Feed campaigns generate ads from feed products automatically. Only the title is his to write. In the beta both types are impression-billed only.
7. **Let the agent run the daily plumbing.** The agent lists and pauses stray campaigns, HEAD-checks every landing URL before it builds an ad and spaces out ad creation. It resubmits wrongly rejected ads and pulls insights. It sends him a return-on-ad-spend report to Telegram at 8am his time, every day.
8. **Handle rejected ads as infrastructure.** In one batch, 13 rejected ads broke down as 9 robots_txt, 3 crawler_502 and 1 crawler_503. Every one was a heavy collection page (1.76 to 3.1 MB of HTML). He reads the ad's review status and reason before assuming a broken URL. His fixes are to HEAD-check that every URL returns 200, space ad creation 10 to 30 seconds apart and resubmit rejects with the identical creative. He also avoids collections whose titles contain "Dup" or "Do not DELETE", because they 301 to the homepage.
9. **Check the agent against the raw numbers.** He reversed three conclusions in roughly ten days:
   - Reversal 1: on day one the feed campaign delivered zero impressions while a chat card delivered 1,641. Two days later a feed campaign ran: 4,762 impressions, 123 clicks, $81.43, 2.58% click-through and $0.66 per click over two days. His takeaway: "Re-test before you trust an old finding."
   - Reversal 2: a small chat-card sample at a $7 CPM and 4.8% click-through worked out to $0.145 per click. At scale, click-through fell from 4.8% on 1,641 impressions to about 0.45% on 12,000. At that rate a $15 CPM works out to roughly $3 per click.
   - Reversal 3: OpenAI overwrites UTMs. Every ChatGPT order in 30 days of Shopify data showed utm_medium as feed or empty, never cpc. His paid report bucket "will read $0 forever, even while ads are spending." He writes, "That zero is a measurement artifact, not proof the ads failed."

## Stated results
- Total beta spend: about $1,100. That is roughly $508 on the two auto-created default campaigns, about $524 on the three chat-card campaigns and $81 on the feed test.
- Paid orders: 0 cleanly attributable. About 292 paid clicks over two days produced no attributable purchase across all three stores.
- Chat cards at a $15 CPM, 2-3 day window:
  - Store A: 11,977 impressions, 51 clicks, $176.70, 0.43% CTR, $3.46 per click.
  - Store B: 11,530 impressions, 56 clicks, $170.00, 0.49% CTR, $3.04 per click.
  - Store C: 11,971 impressions, 62 clicks, $177.00, 0.52% CTR, $2.85 per click.
- Feed campaign (Store B, 2 days): 4,762 impressions, 123 clicks, $81.43, 2.58% CTR, $0.66 per click.
- Organic ChatGPT orders via the feed, 30 days: Store A 14 and Store B 10. Store C, which is newer and smaller, had "fewer." He reports 24+ free organic ChatGPT orders in 30 days, with single orders up to $155.
- His old insights script reported $0 for a week. The API had switched from POST to GET and returns spend in dollars, not micros. He says that is fixed now.
- Pending decision, not yet executed because it needs his sign-off: pause the three chat-card campaigns and consolidate budget into the feed campaigns across all three stores at $100/day/store. He also plans to measure blended Shopify revenue with source = ChatGPT and keep one store organic-only as a control.

## Caveats
- All numbers are self-reported and first-party from his own accounts.
- He says "0 paid orders" is "partly a real result and partly an attribution gap I cannot fully close from my side." CAPI validates for all three stores, but OpenAI has to match a ChatGPT user to a checkout email to credit a conversion.
- OpenAI Ads is a beta, and he says the platform is changing week to week. The feed placement turned on mid-test, and the insights API changed method. Specific endpoints and behaviors may already differ.
- He sells advisory work. His site is billed as "Ecom Advisor" and has a Work With Me page. His author bio offers operator advisory for founders and says he helps operators wire Claude into their ops.
- This is Claude-centric: Claude Code runs the build and the daily operation.
- He keeps the store names out of the post and calls them Store A, B and C.
- Handles: LinkedIn /in/khuetran (verified 2026-11-08: linked from khuetran.com header/footer). No X, Bluesky, Threads, Instagram, TikTok or Mastodon account was found on his site.

## FAQ
### Does the agent spend money on its own?
No. Claude Code has standing authority to build the tooling and run all three accounts, but Khue keeps the budget policy and signs off before any change that moves money. His decision to pause the chat cards is waiting on that sign-off.

### Did the paid ChatGPT ads produce orders?
He reports 0 cleanly-attributable paid orders after roughly $1,100 of beta spend. He says this is partly an attribution gap, because OpenAI overwrites UTMs and has to match a ChatGPT user to a checkout email.

### Why keep the product feed if the paid ads did not pay?
Items marked is_eligible_search can show on ChatGPT's free organic shopping surface. Through the feed, Store A had 14 and Store B had 10 organic ChatGPT orders in 30 days.

### Do you need to be a developer to build this?
He says no, but you need to read scripts and debug when a cron fails. He describes himself as a marketer, not a developer. The agent wrote the code, and his job was to understand it well enough to know when it was wrong.

## Sources
- https://khuetran.com/openai-ads-api-ai-agent-build-log/ (primary: first-person build log by Khue Tran, July 23, 2026)
- https://khuetran.com/about/ (identity and background)

---
*Want agents like these working your distribution? [Get It Built](/get-it-built). Get new teardowns weekly: [subscribe](/subscribe) (double opt-in).*