Skip to content

Event validation & schema

An event that is malformed does not produce an error you will see. It is dropped, and your reported conversions are quietly lower than they should be. This page covers what makes an event valid and what happens when it is not.

On a scheduled source such as a file, a CRM or a warehouse, an event that fails validation is dropped and everything else in the same batch is processed and delivered normally. One bad row in a large upload does not cost you the upload. It also means a steadily rising drop rate produces no error, so the only way to notice is to compare what you sent with what arrived.

On the API the request is validated as a unit, and one invalid event rejects every event sent with it. The response says so explicitly rather than dropping the bad one quietly.

The Datahash API for offline conversions is RESTful, accepts HTTP POST only, and returns JSON. The Datahash API reference carries the endpoint, the headers and every field it accepts. What follows is the part that decides whether an event is valid.

The body carries a top level event_type and an events array, so a single request can carry a batch. Each event has four blocks: event.general, event.monetary, user.general and user.pii.

FieldFormat
event_timeUNIX timestamp, integer
event_nameString, for example Purchase
action_sourceString
event_source_urlString beginning http:// or https://, matching the verified domain
currencyString, ISO 4217 three letter code
content_valueDouble

Optional fields in event.general include content_category, content_ids, content_type, content_name, delivery_category, number_items, transaction_id, predicted_ltv, search_string, status, and contents as an array of objects.

FieldWhat it carries
statusSuccess or Error
messagesAn array of human readable strings naming any problem. There are no error codes.
events_receivedThe number of events in the request. It counts what arrived, not what was accepted, so read status rather than this.

The interface accepts these, all hashed unless noted. Apply SHA-256 hashing to PII covers how to produce the hashed values.

GroupFields
Email and phoneemail_1_hashed to email_3_hashed, phone_1_hashed_format_a and _format_b through to phone_3_
Namefirst_name_hashed, last_name_hashed
Demographicsgender_hashed, date_of_birth_hashed, doby_hashed, dobm_hashed, dobd_hashed
Geographycity_hashed, state_hashed, country_hashed, zipcode_hashed
Sent unhashedmobile_ad_id, external_id
Meta identifiersclick_id_fb, lead_id_fb, fb_login_id_fb

These are Meta rules. They apply to what Meta accepts, not to what Signals does.

  • action_source on all events. The permitted values are email, website, app, phone_call, chat, physical_store, system_generated and other.
  • event_source_url and client_user_agent on all website events.
  • value on purchase events, as a monetary amount, and currency as a valid ISO 4217 code.
  • contents as an array of JSON objects, where id and quantity are required within each object.

This is the rule that silently destroys entire CRM integrations. Meta treats an event as invalid where the customer information consists only of:

  • city plus country plus state plus postcode plus gender plus user agent
  • date of birth plus user agent
  • first name plus gender
  • last name plus gender
  • or any subset of those

The consequence is that whole event streams are discarded. The usual cause is a CRM export that maps only geography, gender and date of birth, because those are the fields that were easy to map. Always include email or phone.

event_time can be up to 7 days in the past. If any event in a request is older than that, Meta returns an error for the entire request and processes none of it.

  • Meta: use Test Events in Events Manager, with real test data. Meta may discard events carrying fake personal data that does not match an account. The Payload Helper is also useful. Receipt takes around 20 minutes.
  • Signals Gateway: allow up to 30 minutes. If nothing appears, check the pixel connection and the subdomain setup.
  • Disable the ad platform’s in-page event setup tool during testing, since it interferes with Conversions API events firing.