Implementação Segura da CAPI no OpenAI Ads: Chaves de API e Limites de Servidor
O erro mais grave é chamar a API a partir do navegador. Saiba como testar seu site em 2 minutos, usar o padrão exclusivo de servidor e agir se houver vazamento.
When developers build their first server-side Conversions API integration, security is often treated as an afterthought.
That is a dangerous mistake.
Unlike client-side pixel IDs (which are public by design), your OpenAI Ads CAPI token is a secret administrative credential. If an engineer accidentally hardcodes an API key into a frontend JavaScript bundle, commits it to a public GitHub repository, or exposes it through an unauthenticated proxy endpoint, malicious actors can hijack your ad account telemetry or spam your pixel with fraudulent conversion data.
Security also extends to customer privacy. Sending unhashed emails, raw phone numbers, or cleartext customer addresses to third-party endpoints directly violates GDPR, CCPA, and OpenAI platform terms.
Here is how to securely architect your server-side CAPI pipeline, manage secrets safely, and enforce bulletproof SHA-256 data sanitization.
Why this happens: client-side habits copied into a server integration
The OpenAI Ads measurement pixel is designed to run in the browser. You add a script tag, initialize it with a public Pixel ID, and it fires events as visitors interact with your site. That pattern (a snippet that lives in your frontend and just works) is how most teams first encounter OpenAI Ads tracking.
The Conversions API shares the same Pixel ID and general concept of sending conversion events, but its architecture requires different handling. CAPI requires an Authorization: Bearer <API-KEY> header carrying a private credential with write access to your event stream instead of a public client token. When teams treat CAPI like a browser pixel and paste API calls directly into client scripts, private credentials risk exposure in frontend JavaScript.
It's an easy mistake to make and a genuinely risky one. Anyone who opens their browser's developer tools on your site can read every request your page sends, including the headers. A leaked CAPI key lets someone send fabricated conversion events under your Pixel ID, or simply use the credential elsewhere without your knowledge.
How to check your own site in two minutes
You don't need backend access to verify this, it's checkable from the same browser tab a visitor would use.
- Open your site in a browser and open developer tools (F12, or right-click → Inspect).
- Go to the Network tab and reload the page. Complete whatever action would normally trigger a conversion event (add to cart, submit a form, complete a test purchase in a sandbox environment).
- In the network request list, search or filter for
bzr.openai.com. The public measurement pixel calls this domain too, so seeing requests here isn't automatically a problem, you're looking specifically for requests going tobzr.openai.com/v1/events(the CAPI endpoint) that originate from the page itself, not from your server. - Click into any matching request and check its Request Headers. If you see an
Authorization: Bearer ...header on a request the browser itself is sending, your API key is exposed to anyone who runs this exact same check. - Separately, use your browser's View Page Source or search the rendered JavaScript bundles (Sources tab) for the string
Beareror for a key-shaped string near any reference tobzr.openai.com. Keys sometimes end up in client-side code without an active request ever firing, for example, hardcoded in a script that's currently unused but still shipped to the browser.
If either check turns up a key, treat it as already leaked (see the rotation steps near the end of this guide) and fix the implementation using the pattern below.
The correct pattern: browser, backend, CAPI
There is exactly one safe shape for a CAPI integration, and it's worth internalizing as a simple rule: the browser never talks to the CAPI endpoint directly.
Browser (visitor action)
|
| event happens: purchase, lead form submit, signup
v
Your backend (server you control)
|
| POST https://bzr.openai.com/v1/events?pid=<PIXEL-ID>
| Authorization: Bearer <API-KEY>
v
OpenAI Ads (event recorded)
Concretely: a purchase completes, and your order confirmation logic (running on your server, in code that never ships to a browser) is what calls CAPI. A lead form is submitted, and your form-handling backend calls CAPI after saving the lead. The visitor's browser is never the thing making that request.
Contrast that with the browser-side pixel, which follows a completely different and entirely appropriate pattern: the browser does talk directly to bzr.openai.com, but using a public Pixel ID with no secret involved, that's what the pixel SDK is built for. The distinction that matters is not "does my browser talk to OpenAI's domain" (the pixel is supposed to) but "does my browser hold or transmit the secret API key" (it never should).
If you're setting up CAPI for the first time instead of fixing an existing implementation, our complete CAPI setup guide walks through the payload schema and a working example from scratch, built around this same server-only boundary from the start.
Key storage best practices
Once the key is confirmed server-side only, how you store it on the server still matters:
- Use environment variables or a secrets manager: not a config file that lives in your codebase. An environment variable injected at deploy time, or a proper secrets manager (your cloud provider's, or a dedicated tool), keeps the key out of anywhere it could be committed by accident.
- Never commit it to source control: not in a
.envfile that gets added by mistake, not in a comment "for reference," not in a commit message. If it's ever been committed, even in a private repository, treat it as exposed and rotate it; git history is not a safe place to bury a secret you've since removed from the current file. - Scope access to who actually needs it. If your CAPI-calling code runs in one backend service, only that service's environment needs the key, not every developer's local
.env, not a shared team wiki, not a general-purpose config file that half your engineering org can read. - Rotate periodically, and immediately after any suspected exposure. A key that's been in place for a long time with broad access is a bigger blast radius if something goes wrong. Rotation is a normal part of key hygiene, not just an incident response step.
- Keep the key separate from the Pixel ID in how you think about risk. The Pixel ID is meant to be public, it's in your browser pixel's initialization call, visible to anyone who views your page source. The API key is not, and conflating the two ("well, the Pixel ID is already public, so..") is how teams talk themselves into being casual with the key.
Logging and access-boundary hygiene
Key exposure isn't the only way sensitive data leaks out of a CAPI integration. Two habits worth building in from the start:
- Don't log full request payloads that include user data. It's tempting to log the entire body of every CAPI call for debugging, but if your
dataobject includes anything tied to a real person, order details, contact information passed via the optionaluserfield, that data now lives in your logging system too, often with looser access controls and longer retention than your primary database. Log enough to debug (status codes, eventid, eventtype, timestamps) without logging the full payload by default. - Apply least privilege to whoever and whatever can trigger a CAPI call. If your CAPI integration lives inside a shared backend service, make sure the code path that calls it doesn't also have broader permissions than it needs, and that access to view or export logs isn't wider than access to the systems those logs describe.
Neither of these is specific to OpenAI Ads (they're standard practice for any server-side integration handling conversion or customer data) but they're easy to skip when a CAPI integration gets built quickly to hit a launch date.
Catching unsafe implementations automatically
Manually checking your own network tab, as described above, works fine for a one-time audit of your own site. If you're managing tracking across multiple client sites, or want an ongoing check instead of a manual one, our free OpenAI Ads Pixel Helper Chrome extension flags unsafe browser-side CAPI calls automatically as you browse, the same pattern described in the two-minute check above, run continuously instead of by hand. It's a lightweight way to catch a regression (a future code change that accidentally reintroduces a browser-side CAPI call) before it turns into an actual leak.
If a key leaked: rotate first, audit second
If you've confirmed (through the check above, a code review, or any other means) that your API key has been exposed in browser-side code at any point, treat it as compromised even if you've since removed the exposing code. The sequence that matters:
- Rotate the key immediately in the conversions tab of OpenAI Ads Manager. Generate a new key before you do anything else; the exposed one should be treated as unusable from this point forward.
- Update every place the old key was stored, environment variables, secrets manager entries, any deployed service still referencing it , with the new key, and confirm the old one is no longer active anywhere in your infrastructure.
- Audit for how it got there. Was it a one-off mistake in a script that's since been fixed, or a pattern that could recur, for example, a shared code template that other integrations were copied from? Fix the root cause, not just the immediate instance.
- Re-run the two-minute browser check described earlier, on the live site, after deploying the fix, to confirm the new implementation is actually server-side only and not just moved to a different client-side location.
Rotating the key is not optional caution, it's the only way to actually close the exposure, since simply removing the code that leaked it doesn't invalidate a key that's already been seen.
Getting the CAPI boundary right the first time is simpler than fixing it after a launch, mostly because a security review is much easier to build into a setup than to bolt on afterward. If you want that boundary verified as part of the build instead of checked after the fact, that's what a security-conscious CAPI setup should include from day one.