Skip to main content

Attribute Sync

Introduction

Attribute sync allows associating users with attributes which can be used for inventory, campaign insights, and targeting.
These associations are retrieved on ad-request.

Because the data is associated with a userId consent is needed. When you push data to adhese via the attribute-sync, we assume the sender validated the consent. Do not push userdata for which no consent was given.

On the ad-request side we do validate consent. An ad-request without a userId or consent will not get linked with the data that was pushed via attribute-sync.

Pushing data

Authentication

The first step of pushing data, is retrieving a valid JWT token from our keycloak. We use the ROPC flow, this exact flow may change in the future. You will be provided with the login credentials for an account specifically used for the attribute-sync.

An example request to retrieve a JWT token

curl --location 'https://auth.we.adhese.org/realms/user-sync/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=user-sync-app' \
--data-urlencode 'username=[username]' \
--data-urlencode 'password=[password]' \
--data-urlencode 'grant_type=password'

This token can be re-used multiple times until it expires.

IP-filtering

If requested we can enable IP-filtering on the attribute-sync endpoint. If enabled we will only accept data coming from a predefined list of IP-Addresses.

Uploading data

Actually uploading data happens via the https://ads-[customer].adhese.com/usersync/attributesync endpoint (POST with json payload).

Be sure to pass the access_token from the previous steps as a bearer token in the Authorization header

{
  "reportDateTimeValid": "2026-02-11T17:11:00Z",
  "entries": [
    {
      "identifier": {
        "name": "DIGIMON_ID",
        "value": "userId1"
      },
      "attributes": [
        {
          "name": "firstAttribute",
          "value": [
            "known_app_user",
            "example_value"
          ]
        },
        {
          "name": "secondAttribute",
          "value": [
            "known_app_user2",
            "known_test_trait_pageview_less_then_2"
          ]
        }
      ]
    },
    {
      "identifier": {
        "name": "DIGIMON_ID",
        "value": "foobar"
      },
      "attributes": [
        {
          "name": "firstAttribute",
          "value": [
            "known_app_user",
            "another_example_value"
          ]
        }
      ]
    }
  ]
}

Above you can see an example payload.

reportDateTimeValid Optional How long we can/should store the data from this request. If absent we default to 7 days in the future. By default we limit the validity to a maximum of 30 days in the future.
entries Mandatory

Each user is represented by an entry. We accept up to 500 entries per request.

To store data for more than 500 users, please use multiple requests instead.

entries.identifier.value Mandatory

This field represents the userId of this entry.

entries.identifier.name Mandatory

Some customers have different types of userIds (eg an actual userId and a deviceId) and want to be able to store different data for the same userId if the userId came from a different source. You can think of this as a namespace for your userIds. These can be arbitrary but need to be used consistently.

Inform our support agents which ones you plan to use.

 

Even if you only use a single source of userIds, a value still needs to be chosen.

entries.attributes Mandatory but can be empty

Can be left empty for deleting data. See below.

entries.attributes.name Mandatory

The attribute for which you want to store values for the specific userId.

entries.attributes.values Mandatory

The values you want to store with the attribute for the specific userId.

Each time we receive data via the attribute-sync for a specific user, it overwrites the data from previous requests regarding that user, even if certain attributes are not included in the latest request but were in the first request.
This has as a side effect that you can delete all (attribute-sync) data associated with a user by leaving the entries.attributes empty. 

Because attribute-sync is meant for textual data, we may reject data that contains Unicode control characters. 

Using the data

Cooperate with support to configure which target(s) represent userId(s), and which attribute corresponds with which target. When done ad-requests with consent and a userId will automatically get additional targets from the data you pushed, even if the push happened less than a second ago.

What data to store

Because all the data pushed via the attribute-sync needs to be accessible without delay, this data is stored in memory. For this reason we ask to be mindful of what data you store:

  • Only store attributes you actually plan on using.
  • Do not make attributes/attribute values overly verbose (they do not need to be human readable)
  • Keep userIds to a reasonable length