Rozwiązywanie problemów z OpenAI Ads CAPI: Błędne ładunki, znaczniki czasu i typy zdarzeń
Diagnoza i naprawa błędów API Konwersji OpenAI Ads: błędy 400 Bad Request, limity 7 dni dla znaczników czasu i walutowe jednostki mniejsze.
Client-side pixels fail silently. You miss a parameter, and the browser simply shrugs.
The Conversions API is not so forgiving.
When your backend sends an invalid JSON payload to https://bzr.openai.com/v1/events, OpenAI does not silently ignore it. The server immediately returns an explicit HTTP 400 Bad Request error. If your UNIX timestamp is off by more than seven days, the event is rejected. If your currency code is lowercase (usd instead of USD), the payload fails validation. If your customer email is not lowercased before SHA-256 hashing, match rates collapse.
Diagnosing CAPI failures requires understanding exactly what OpenAI ingest API expects down to the byte.
Here is the complete reference guide to debugging CAPI error codes, resolving payload rejection issues, and enforcing timestamp integrity.
1. Quick Reference: Common CAPI HTTP Status Codes
When sending POST requests to https://bzr.openai.com/v1/events?pid=<PIXEL-ID>, the API responds with standardized HTTP status codes:
| HTTP Status | Meaning | Typical Root Cause | Immediate Action |
|---|---|---|---|
| 200 OK | Success / Validated | Valid payload accepted or validation check passed | If validate_only: true, switch to false for production |
| 400 Bad Request | Schema / Parameter Failure | Missing required fields, invalid timestamp, float amounts | Inspect response body error details and validate payload shape |
| 401 Unauthorized | Authentication Failed | Invalid, revoked, or missing Bearer token in header | Re-issue CAPI key in Ads Manager; verify header format |
| 403 Forbidden | Access Denied | Pixel ID mismatch or ad account permissions revoked | Verify pid query parameter matches the pixel owning the key |
| 429 Too Many Requests | Rate Limit Exceeded | Burst requests exceeded account throughput thresholds | Implement exponential backoff and batching (up to 1,000 events) |
| 500 / 503 | Server Error | Temporary endpoint degradation or gateway timeout | Retry with jittered exponential backoff; check OpenAI status |
2. Diagnosing 400 Bad Request: Root Causes & Solutions
A 400 Bad Request indicates that your JSON body violates the expected CAPI contract. Below are the most frequent causes observed in production implementations.
Issue A: Floating-Point Amounts Instead of Integer Minor Units
OpenAI Ads strictly adheres to ISO 4217 minor units for all monetary fields (amount). Sending floats such as 89.99 triggers a validation error.
// INCORRECT (Triggers 400 Bad Request)
{
"amount": 89.99,
"currency": "USD"
}
// CORRECT (Integer Minor Units: 89.99 USD = 8999 cents)
{
"amount": 8999,
"currency": "USD"
}
Rule: Multiply standard decimal currency by 100 for currencies with 2 decimal places (USD, EUR, GBP, CAD, AUD). For zero-decimal currencies like JPY, use the exact integer value without multiplication.
Issue B: Expired or Future Timestamps (timestamp_ms)
OpenAI Ads requires every event to supply a timestamp_ms representing milliseconds since the Unix epoch (e.g., Date.now()).
- Maximum Past Age: 7 days (604,800,000 ms). Any event with a timestamp older than 7 days is rejected.
- Future Timestamps: Events timestamped more than 5 minutes into the future (due to server clock skew) will be rejected.
// Validating timestamp before dispatch
const now = Date.now();
const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
if (event.timestamp_ms < (now - SEVEN_DAYS_MS)) {
console.error("Event rejected: Timestamp is older than 7 days allowed window.");
return;
}
Issue C: Unrecognized or Misspelled Event Types
OpenAI Ads supports designated standard events. Using non-standard casing or invalid names will trigger a schema error unless explicitly declared as a custom event.
Supported Standard Event Types:
page_viewedcontents_vieweditems_addedcheckout_startedorder_createdlead_createdappointment_scheduledregistration_completedtrial_startedsubscription_activatedapp_installed(Server CAPI only)app_opened(Server CAPI only)
If you are tracking an action outside standard events, you must set "type": "custom" and include a custom event identifier in the data payload.
3. The Correct CAPI Payload Architecture
To eliminate schema validation errors, format your batch request exactly as shown below:
{
"validate_only": false,
"events": [
{
"id": "evt_order_108429_1725148800",
"type": "order_created",
"timestamp_ms": 1725148800000,
"action_source": "website",
"event_id": "shopify_order_601928374",
"user_data": {
"em": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a",
"ph": "94212953e5e49f579d479cb2c9f417f7b15d914d33a682ff9341496695222718",
"client_ip_address": "198.51.100.42",
"client_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)..."
},
"data": {
"amount": 14500,
"currency": "USD",
"order_id": "108429",
"contents": [
{
"content_id": "SKU-9921",
"quantity": 1,
"item_price": 14500
}
]
}
}
]
}
4. Testing with validate_only: true
Before pushing new backend event handlers or queue workers to production, test them with a curl command using validate_only: true:
curl -X POST "https://bzr.openai.com/v1/events?pid=YOUR_PIXEL_ID" \
-H "Authorization: Bearer YOUR_CAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"validate_only": true,
"events": [
{
"id": "test_evt_001",
"type": "order_created",
"timestamp_ms": '"$(date +%s%3N)"',
"action_source": "website",
"event_id": "test_order_dedup_001",
"data": {
"amount": 2500,
"currency": "USD",
"order_id": "TEST-101"
}
}
]
}'
If the payload is valid, OpenAI returns {"success": true} with HTTP 200. If any property is invalid, the response body details the exact JSON pointer and validation rule that failed.
5. Ensuring Deduplication Across Browser and Server
When firing both the browser pixel (oaiq) and server-side CAPI for the same user event (such as order_created), deduplication is mandatory to avoid double-counting conversions.
- Shared Event ID: Generate a unique identifier on your server or checkout session (e.g.,
checkout_tokenororder_id). - Client-Side Emission: Pass the identifier into the browser pixel payload as
event_id. - Server-Side Emission: Pass the exact same string into the CAPI event object as
event_id. - Attribution Engine Deduplication: OpenAI Ads de-duplicates matching events received within a 48-hour window, merging server match quality data with browser session context.
For an end-to-end guide on deduplication mechanics, refer to our guide on deduplicating OpenAI Ads pixel and CAPI events.
6. Resolving Persistent Payload Errors
If your server continues to experience dropped events or unexplained payload rejections:
- Verify that user data fields (
em,ph) are strictly SHA-256 hashed and lowercase (see our user data hashing guide). - Confirm your server clock is synchronized via NTP to eliminate clock drift errors.
- Ensure your worker queues do not re-try failed events after the 7-day timestamp threshold has elapsed.
If your team needs guaranteed zero-loss server tracking with full schema validation and deduplication, explore our Conversions API Setup service or book a Tracking Audit.