Contextual ad targeting on VibeFree
Short answer: VibeFree targets ads on the conversation, not the person. Each new message is labelled by an automated classifier on VibeFree's own infrastructure - what the developer is doing, the languages and frameworks named, what the project needs and its stage - and an ad group can require those labels, exclude them, or let its own description raise its ranking. Only the labels are kept, for 30 minutes, and you never see a message: reporting is totals per label, from 50 views up.
This page is the conversation half of targeting: the label taxonomy, the controls in the ad group form, brand safety, the targeting simulator and topic reporting. Country, language, OS, editor, time of day and the rest of standard targeting are listed on advertising inside an AI chat; what the person on the other side is told is on ads and your chat.
How a message becomes labels
- Keyword screens first. A crisis and sensitive-topic screen, then a deterministic read of the languages, frameworks, databases and platforms the message names -
tsconfig,go.mod,wrangler,prisma. - Then a small model. An instruct model on Cloudflare Workers AI reads the first 1,500 characters of the message and answers in JSON only: one intent, up to three needs and a stage. Anything outside the fixed list is dropped, and if the model does not answer within five seconds the message keeps its keyword labels alone.
- Then similarity. For ad groups with Smart targeting, the labels plus the first 300 characters of the message are embedded and compared with each group's own embedded description, keywords and approved copy.
- Then the text is gone. What is kept, against the account and for that conversation only, for 30 minutes: the labels, a similarity score per ad group, and a keyword-hit count per ad group. Never the message.
Labels are worked out while the reply is being written. End-of-response units and follow-up chips use the current message's labels; the loading slot shown while a reply is written uses the previous message's labels in the same conversation, or none.
The label taxonomy
| Dimension | Values | Read by |
|---|---|---|
| Intent (one per message) | Building something, fixing a bug, deploying, refactoring, learning, designing, working with data, other | The model |
| Needs (up to four) | authentication, databases, payments, email, hosting and deployment, file storage, monitoring and logging, testing, AI and LLMs, analytics, search, content management, background jobs and queues, realtime features, security, CI/CD, mobile apps and UI design | The model and keywords |
| Stack (up to six) | 43 languages, frameworks, databases and platforms: TypeScript, JavaScript, Python, Go, Rust, Java, Kotlin, Swift, C#, PHP, Ruby, React, Next.js, Vue, Nuxt, Svelte, Angular, Express, Django, Flask, FastAPI, Rails, Laravel, Spring, Tailwind CSS, React Native, Flutter, Electron, Postgres, MySQL, MongoDB, Redis, SQLite, Supabase, Firebase, Prisma, Docker, Kubernetes, AWS, Google Cloud, Azure, Vercel, Cloudflare | Keywords only, so it is deterministic |
| Stage | Idea, prototype, running in production, maintenance - or unknown | The model |
| Error kind (error-moment units only) | A build, tests, a type check, a lint check, a package install, a command or a deploy failed | The coding agent reports the kind; the error output is never read |
The controls in an ad group
| Control | What it does | Effect |
|---|---|---|
| Taxonomy picks ("Only when they are…", "about…", "use…", "at stage") | Within one dimension any pick matches; across dimensions, every dimension you used must match | A hard filter. A group with picks never serves on a message without usable labels |
| Keywords | Up to 50 words or short phrases (2-40 characters), matched as whole words, ignoring case | Raises relevance: 0.1 per keyword found, up to 0.2 |
| Negative keywords | Up to 50; a message containing one rules the group out | Exclusion |
| Never beside | Intents and needs your ad must never appear beside - debugging, security, payments | Exclusion, for brand safety |
| Smart targeting | A switch, plus a plain description of what you offer (up to 500 characters) or some keywords. The description is embedded and never shown to anyone | Raises or lowers relevance by up to 0.4, by similarity to the conversation |
| Error kinds | Error-moment units only: which kinds of failure | A hard filter; empty means any |
Relevance changes your ranking, never your price. Each eligible ad is ranked on bid times predicted click rate times relevance, with relevance held between 0.5 and 1.5, and you pay exactly your own bid when you win. Using taxonomy picks adds 0.1 of its own.
Use negatives sparingly: Negative keywords and "Never beside" are absolute: one match and the group sits the turn out. They are the right tool for brand safety, not for narrowing - a broad negative such as "test" quietly removes you from every conversation about testing. Narrow with a pick or Smart targeting, and exclude with a negative.
When a message is never targeted
- A crisis. A message that reads as self-harm, abuse or an emergency, and the next few, run untargeted: contextually targeted groups do not serve on them, nor does any sensitive-tier campaign.
- A sensitive topic. A message about the writer's own health, sexuality, ethnicity, religion, politics, money worries, addiction or legal trouble is not labelled for targeting: groups with picks cannot serve beside it, other groups run untargeted, and campaigns in the sensitive business tier are kept off it. Software merely about such a topic - a booking app for clinics - is not sensitive.
- People who objected. Anyone can switch contextual ads off. Their messages are never labelled, so groups with picks do not reach them; untargeted groups still can.
- Expired or elsewhere. Labels last 30 minutes and belong to one conversation.
So contextual picks narrow who can see your ad, and some messages are never eligible at all. That is deliberate: the classifier exists to make ads relevant, not to profile anyone.
Test it before you pay: the targeting simulator
In the free sandbox, type a prompt the way a developer would, pick the surface, placement and a mock context - country, OS, editor, mode, how far into the session - and the simulator runs it through the live classifier and every one of your ad groups, drafts included. For each group it shows the labels the prompt got and whether the model or the keywords alone produced them, each check passed or failed (placement, surface, the crisis and sensitive rules, standard targeting, contextual targeting, an option card's need), the similarity and relevance, whether the ad would serve, and the exact "Why this ad?" text the person would see. The prompt is your own test text and is not stored. Budget, pacing and frequency caps are not simulated, because they depend on delivery rather than on the prompt.
What "Why this ad?" tells the person
Every first-party unit has a "Why this ad?" menu built from the same checks that chose it, so it cannot say something the auction did not do. A contextual match reads like "Your conversation is about authentication" or "You're working with Next.js", and ends: "Picked partly by topic labels from this conversation (never its text), which are deleted after 30 minutes. Not based on a profile of you. Ads never change what the AI says." Choose your targeting expecting the person to read it.
Reporting by conversation topic
The campaign report has a By conversation topic table: views and clicks per label - need:auth, stack:nextjs, intent:debug - totalled over the flight. Any label under 50 views is folded into "Other (fewer than 50 views each)", so no row describes a handful of people. Sensitive and crisis messages carry no labels, so they never appear. The same totals are available over a reporting API key.
What you never see
- The message. Not in reports, the reporting API, webhooks, or the simulator for anyone else's turn.
- Any one person's labels. Only totals per label, from 50 views up.
- Who objected, or who is in an audience. Profile-based audiences - retargeting, lookalikes, a developer profile - are a separate setting in the same form and reach only people who switched personalised ads on; you never learn who they are.
Frequently asked questions
What is contextual targeting in an AI chat?
Choosing an ad from what the current conversation is about rather than from a profile of the person. On VibeFree each new message is turned into a few labels - the task, the languages and frameworks named, what the project needs and its stage - and ad groups can require or exclude those labels. Only the labels are kept, for 30 minutes.
Can I target developers by programming language or framework?
Yes. Stack picks cover 43 languages, frameworks, databases and platforms, from TypeScript and Python to Next.js, Postgres, Docker and Cloudflare. The stack is read deterministically from what the message names - a tsconfig, a go.mod, an import - not guessed by a model.
Do advertisers see what developers type?
No. Advertisers never receive messages or any one person's labels. The campaign report shows views and clicks per label, totalled over the flight, and any label under 50 views is folded into "Other".
How do I keep my ad away from certain conversations?
Two exclusions: negative keywords, which rule your ad group out of any message containing one, and "Never beside", which excludes intents and needs such as debugging, security or payments. Both are absolute, so use them for brand safety rather than for tuning.
Why did my contextually targeted ad group not serve?
A group with taxonomy picks only serves on a message with usable labels. There are none on the loading slot of the first message in a conversation, after 30 minutes, on a sensitive or crisis message, and for anyone who switched contextual ads off. Run a sample prompt through the targeting simulator to see which check failed.
Start a campaign, see every placement in the conversation, or measure conversions with a signed postback.
Related pages
- Conversion tracking with postbacks - Signed postbacks, webhooks, the CPA hybrid and the anomaly pause.
- The conversational brand agent - A side chat answered from your reviewed docs, billed per first message.
- Sponsored installs and follow-up chips - Pinned packages and MCP servers, dry runs, and every safeguard.
- Or browse every VibeFree guide.