Identifier contract

Identifier contract

A profile is keyed by (app_id, user_key). Context merges last-write-wins per trait. user_key is opaque and is never expanded onto a landing URL.

Serve request

Each decision is { placement, user_key, context }. The public app key prefix travels in X-App-Key, not in the JSON body. Placement is the placement name on the authenticated app.

JSON
{
  "placement": "home",
  "user_key": "user-42",
  "context": {
    "plan": "pro",
    "country": "US",
    "locale": "en-US",
    "device": "desktop"
  }
}

user_key

user_key is an opaque publisher identifier. Meridian Ads does not assume it is PII. If the value looks like an email, it is hashed at rest with SHA-256 of the lowercase string. Other keys are stored as given (trimmed).

Frequency caps and profile lookup use the normalized key. GDPR or publisher delete (DELETE /api/v1/apps/{appId}/profiles/{userKey}) removes the Redis hot copy and the Postgres durable copy.

context

context is a JSON object of traits. Max size is 8KB. On each decision the request map is merged into the stored profile with last-write-wins per trait key, then segments run on the merged profile. There are no first-class geo, device, or daypart objects in v1. Send those as traits if you have them.