Skip to main content
POST
Submit a server-side conversion to Plainrouter with a Signals workspace secret. A new event returns 202; a retry of the same event ID returns 200 with duplicate: true. Neither receipt alone confirms Meta delivery.

Before sending a purchase

  • Use the Signals workspace secret on your server. MCP execution tokens and OAuth management credentials cannot authenticate this endpoint.
  • Connect the intended Meta dataset for eligible destination delivery.
  • Read the actual paid order and its recorded advertising consent. The example assumes all three grants; setting these fields does not obtain consent.
  • Choose one purchase sender. Do not also send the same checkout through a browser purchase or Stripe settlement flow.
This endpoint uses Plainrouter’s request shape, not Meta’s Graph API data envelope. For synthetic payload checks without production writes, use the sandbox.

Example: an immediate, consented purchase

Replace the order ID, source URL, amount and currency with the actual purchase. This immediate-event example omits event_time, so Plainrouter uses receipt time. For queued events, supply the original Unix timestamp or ISO-8601 payment time from your order record and preserve it on retries. Do not replace an old payment time with the current time.
Use a stable, non-personal event_id for the logical purchase. You can use Idempotency-Key instead; if you supply both, they must match. Reuse the original payload after an uncertain timeout, subject to continued consent eligibility. A duplicate receipt does not update the accepted event or replay a failed Meta delivery.
New-event acknowledgements include warnings. If you supply identity data without a valid consent capture time, read the consent warning guidance before treating the event as linked. Duplicate acknowledgements retain the response shape shown above.

How do I verify the result?

Follow the returned Location header or retrieve the event and delivery trace. A delivery with status: "accepted" confirms Meta acceptance. Queued or retrying delivery remains pending, and an empty delivery list is not acceptance. See delivery statuses for failed and skipped outcomes. Acceptance does not establish ad attribution or better performance. For a complete backend integration, use the Node.js and TypeScript recipe, Python recipe, or Ruby recipe. The parameter and response schemas below come from the signed OpenAPI contract.

Authorizations

Authorization
string
header
required

Per-workspace bearer secret. It authenticates only the Signals workspace represented by the credential.

Headers

Idempotency-Key
string

Optional idempotency key. When event_id is omitted, Plainrouter uses this value as event_id. If both are supplied, they must match.

Body

application/json

Authenticated secret-key server callers may supply client_ip_address and client_user_agent in user_data; publishable-key browser traffic takes those fields only from the trusted edge.

event_name
string
required

Signal event name; maximum 100 characters.

Legal basis for processing. Legitimate-interest revenue lifecycle events are rejected; use an authenticated server adapter.

Allowed value: "consent"
event_id
string

Caller-supplied idempotency key; maximum 128 characters.

parent_event_id
string

Optional parent event id; maximum 128 characters.

event_time

Unix timestamp or ISO-8601 date-time. Defaults to receipt time.

event_source
string<uri>

Optional absolute source URL.

action_source
string

Optional action source; defaults to website and is limited to 50 characters.

visitor_id
string

Optional visitor identifier; maximum 255 characters.

Consent state supplied with the event.

Consent Mode v2 signal values supplied with the event.

tcf
object

TCF v2 data containing string and optional captured_at.

user_data
object

Identity fields accepted by the tracker.

click_ids
object

Advertising click identifiers.

value_data
object

Optional commerce data. Contents accepts at most 50 items and 16 KB serialized.

Response

Duplicate event accepted idempotently.

event_id
string
required
duplicate
boolean
required