Passer au contenu

API des tags d'objet (bêta)

Les tags d’objet stockent des données structurées sur un utilisateur dans un seul tag. Un tag de type Object contient un objet avec des champs nommés, comme la dernière commande order avec son amount et son status. Un tag de type ObjectList contient un tableau de tels objets, comme toutes les commandes orders. Vous définissez les champs une seule fois, écrivez et lisez les valeurs via l’API des tags, et créez des segments selon les valeurs des champs.

Fonctionnement des tags d’objet

Anchor link to

Un tag d’objet possède un schéma et une valeur. Le schéma est le nom du tag et une liste de champs, chacun avec son propre type scalaire. La valeur est stockée dans les champs, séparément pour chaque utilisateur.

  • Champ. Chaque champ est un tag nommé <object>.<field>, par exemple order.amount. Vous segmentez selon les champs, et vous pouvez écrire un champ d’un tag Object par ce nom.
  • Valeur Object. Un objet par utilisateur, par exemple "order": {"amount": 120, "status": "paid"}.
  • Valeur ObjectList. Un tableau d’objets avec les mêmes champs, par exemple "orders": [{"amount": 120, "status": "paid"}, {"amount": 50}].

Les tags d’objet sont toujours User-specific : la valeur appartient à l’utilisateur, et non à un seul appareil, et elle est copiée sur tous les appareils de l’utilisateur. Consultez l’API de Tags pour les tags classiques.

Règles du schéma

Anchor link to

Pushwoosh vérifie ces règles lorsque vous créez un tag d’objet ou ajoutez un champ :

  • Les noms d’objets et de champs ne contiennent que des lettres latines, des chiffres et _.
  • Le nom complet du champ <object>.<field> comporte 64 caractères au maximum.
  • Un tag d’objet comporte de 1 à 20 champs. Les noms de champs ne sont pas sensibles à la casse : Amount et amount désignent le même champ.
  • Un champ a l’un de ces types : INTEGER, STRING, LIST, DATE, BOOLEAN, PRICE, VERSION. Les champs de fuseau horaire et les objets imbriqués ne sont pas pris en charge.
  • Un champ ne peut pas prendre un nom déjà porté par un autre tag. Si un tag order.note existe, l’ajout du champ note à order échoue avec tag order.note already exists.
  • Un tag d’objet ne peut pas perdre son dernier champ. Supprimez plutôt le tag d’objet.
  • Un champ ou un tag d’objet en cours d’utilisation ne peut pas être supprimé. L’erreur indique où il est utilisé, par exemple field is in use: segment Big buyers, in-app Spring sale. Les segments, les in-apps, les campagnes Customer Journey en cours, les presets, les modèles d’e-mail et les autres éléments qui font référence au tag comptent comme des utilisations.

Gérer le schéma

Anchor link to

Créez et modifiez les tags d’objet avec les méthodes REST ci-dessous. Utilisez /json/1.3/addTag uniquement pour les tags classiques, car cette méthode ne peut pas définir de champs.

URL de base

Anchor link to
https://rpc-api.svc-nue.pushwoosh.com

Authentification

Anchor link to

Chaque requête doit inclure un en-tête Authorization avec votre jeton API Serveur. Un jeton API Appareil reçoit HTTP 403 a device API token cannot call this method, use an account API token.

Authorization: Api YOUR_API_TOKEN

Points de terminaison

Anchor link to

Ces méthodes gèrent le schéma des tags d’objet :

MéthodeCheminDescription
POST/api/tagsCréer un tag d’objet avec ses champs
GET/api/tags/{name}Obtenir un tag d’objet avec ses champs
GET/api/tagsLister les tags. Un tag d’objet est renvoyé avec ses fields, et les champs ne sont pas listés comme des tags distincts
POST/api/tags/{name}/fieldsAjouter un champ
DELETE/api/tags/{name}/fields/{field}Supprimer un champ
DELETE/api/tags/{name}Supprimer un tag d’objet avec tous ses champs

POST /api/tags et les deux méthodes de champs renvoient le tag d’objet après la modification, encapsulé dans {"tag": {...}}. DELETE /api/tags/{name} renvoie {}.

Si les tags d’objet ne sont pas activés pour votre compte, POST /api/tags avec un type objet et les deux méthodes de champs échouent avec HTTP 403 object tags are not enabled for the account. GET /api/tags/{name} et DELETE /api/tags/{name} renvoient HTTP 404 tag not found, et GET /api/tags ne liste pas les tags d’objet. Sans les tags d’objet activés, vous ne pouvez pas en créer, il n’y a donc rien dans quoi écrire des valeurs.

Créer un tag d’objet

Anchor link to

POST /api/tags

Corps de la requête
Anchor link to
NomTypeDescription
name*stringNom du tag d’objet.
type*stringOBJECT pour un objet ou OBJECT_LIST pour une liste d’objets.
fields*arrayChamps de l’objet, de 1 à 20.
fields[].name*stringNom du champ. Le champ devient le tag <name>.<fields[].name>.
fields[].type*stringType du champ : INTEGER, STRING, LIST, DATE, BOOLEAN, PRICE ou VERSION.
Exemple
{
"name": "orders",
"type": "OBJECT_LIST",
"fields": [
{ "name": "amount", "type": "INTEGER" },
{ "name": "status", "type": "STRING" }
]
}
Réponse
{
"tag": {
"name": "orders",
"type": "OBJECT_LIST",
"system": false,
"user_specific": true,
"has_right_ace_modify": true,
"fields": [
{ "name": "amount", "type": "INTEGER" },
{ "name": "status", "type": "STRING" }
]
}
}

Le tag est créé comme User-specific, quelle que soit la valeur de user_specific. GET /api/tags/{name} renvoie le même objet sans l’enveloppe tag. Les champs sont triés par nom.

Ajouter un champ

Anchor link to

POST /api/tags/{name}/fields

Exemple : POST /api/tags/orders/fields
{
"field": { "name": "note", "type": "STRING" }
}

Vous pouvez écrire le nouveau champ immédiatement dans le cadre de la valeur complète du tag. L’ajout d’un champ échoue si le tag d’objet a déjà 20 champs ou si un tag portant le nom complet du champ existe, voir Erreurs.

Supprimer un champ

Anchor link to

DELETE /api/tags/{name}/fields/{field}

Par exemple, DELETE /api/tags/orders/fields/note supprime le champ orders.note. Vous ne pouvez pas supprimer le dernier champ ni un champ en cours d’utilisation, voir Erreurs.

Les erreurs sont renvoyées au format {"code": <n>, "message": "...", "details": [...]}. Lorsque vous créez un tag d’objet, les messages 400 commencent par validate: .

Statut HTTPMessageCause
400object tag and field names must contain only letters, digits and underscoresUn nom contient un autre caractère.
400an object tag needs 1 to 20 fieldsAucun champ ou plus de 20 champs à la création.
400an object tag has at most 20 fieldsLe tag d’objet a déjà 20 champs.
400field <name> is given twiceDeux champs portent le même nom, sans tenir compte de la casse.
400<object>.<field>: object and field names together cannot be longer than 64 charactersLe nom complet du champ est trop long.
400<object>.<field>: field type must be INTEGER, STRING, LIST, DATE, BOOLEAN, PRICE or VERSIONType de champ non pris en charge.
400an object tag needs at least one field; delete the object tag insteadVous avez tenté de supprimer le dernier champ.
400field is in use: ..., tag is in use: ...Le champ ou le tag d’objet est utilisé dans des segments, des in-apps, des campagnes Customer Journey ou d’autres éléments.
403object tags are not enabled for the accountLes tags d’objet ne sont pas activés pour le compte.
403a device API token cannot call this method, use an account API tokenLa requête utilise un jeton API Appareil.
404tag not foundGET ou DELETE /api/tags/{name} : ce tag n’existe pas, le nom est un champ, ou les tags d’objet ne sont pas activés.
404object tag not found, field not foundMéthodes de champs : ce tag d’objet ou ce champ n’existe pas.
409tag already existsUn tag portant le nom du tag d’objet existe.
409tag <object>.<field> already existsUn tag portant le nom complet du champ existe.

Écrire des valeurs

Anchor link to

Écrivez les valeurs des tags d’objet avec /setTags et /bulkSetTags. Ces méthodes conservent leur propre authentification : /setTags prend un jeton API Appareil dans l’en-tête Authorization: Token, et /bulkSetTags prend le jeton d’accès API dans auth. Envoyez une valeur Object sous forme d’objet JSON et une valeur ObjectList sous forme de tableau d’objets :

Exemple : /json/1.3/setTags
{
"request": {
"application": "XXXXX-XXXXX",
"userId": "user_42",
"tags": {
"order": { "amount": 120, "status": "paid" },
"orders": [
{ "amount": 120, "status": "paid" },
{ "amount": 50 }
]
}
}
}

Si vous définissez la valeur par HWID, elle est stockée sur l’utilisateur de cet appareil.

Chaque champ prend une valeur au format de son type :

Type de champExemple de valeur
INTEGER120
STRING"paid"
LIST["gift", "express"]
DATE"2026-10-02 22:11" (UTC), "2026-10-02" ou un timestamp Unix en secondes
BOOLEANtrue ou false
PRICE19.95
VERSION"1.0.0"

L’écriture remplace toute la valeur

Anchor link to

Chaque écriture remplace la valeur stockée du tag d’objet :

  • Un champ absent de la nouvelle valeur est supprimé. Un champ envoyé avec null est également supprimé.
  • null, [] ou "" supprime toute la valeur.
  • {} supprime tous les champs d’un tag Object.
  • Une clé qui n’est pas un champ de l’objet est ignorée.
  • Si la valeur d’un champ ne correspond pas au type du champ, toute la valeur du tag est rejetée et la valeur stockée reste inchangée.

/setTags ne signale pas une valeur rejetée dans sa réponse. Vérifiez le résultat avec /getTags ou utilisez /bulkSetTags, qui renvoie un résultat pour chaque tag.

Écrire un champ d’un Object

Anchor link to

Écrivez un seul champ d’un tag Object par son nom complet. increment et les autres opérations de /setTags fonctionnent sur les champs :

"tags": {
"order.status": "shipped",
"order.amount": { "operation": "increment", "value": 5 }
}

Un champ d’un tag ObjectList ne peut pas être écrit seul, car on ne sait pas quel élément modifier. /setTags ignore une telle valeur. Envoyez plutôt la liste entière.

Les tags d’objet ne sont pas créés automatiquement

Anchor link to

Une valeur contenant un objet ou un tableau d’objets pour un tag qui n’existe pas est ignorée. La création automatique de tags ne crée pas de tags d’objet : créez donc d’abord le schéma avec POST /api/tags.

Résultats de bulkSetTags

Anchor link to

Avec detailed=true, le statut de /bulkSetTags renvoie l’un de ces résultats pour un tag d’objet, en plus de ok, tag not found et wrong value. expect :<type> :

RésultatCause
object tags are stored on the user onlyLe tag d’objet n’est pas User-specific.
cannot load the fields of the objectPushwoosh n’a pas pu lire les champs du tag d’objet.
wrong value. expect an object (a map) or, for a list of objects, an array of mapsLa valeur ne correspond pas au tag d’objet, ou la valeur d’un champ ne correspond pas à son type.
a field of a list of objects cannot be set on its own, set the whole listLa valeur est définie sur un champ d’un tag ObjectList.

Lire des valeurs

Anchor link to

/getTags renvoie une valeur Object sous forme d’objet JSON et une valeur ObjectList sous forme de tableau d’objets :

Réponse
{
"status_code": 200,
"status_message": "OK",
"response": {
"result": {
"order": { "amount": 120, "status": "paid" },
"orders": [
{ "amount": 120, "status": "paid" },
{ "amount": 50 }
]
}
}
}

Les valeurs des champs sont renvoyées de la même manière que les valeurs des tags classiques dans /getTags : un Date sous forme de timestamp Unix en secondes, un Price sous forme de chaîne, par exemple "120.00", et un Boolean sous forme de 1 ou 0.

Segmenter selon les champs

Anchor link to

Définissez les conditions de segment sur les champs, et non sur le tag d’objet lui-même. Dans le langage de segmentation, un champ est un tag dont le nom contient un point, et il accepte les opérateurs de son propre type :

AT("XXXXX-XXXXX", "order.amount", gte, 100)

Une condition sur le tag d’objet lui-même échoue avec object tag has no value of its own, use one of its fields.

Conditions sur un ObjectList

Anchor link to

Une condition sur un champ d’un tag ObjectList correspond à un utilisateur lorsqu’au moins un élément de la liste remplit la condition. Les conditions sur des champs de la même liste reliées par AND doivent correspondre au même élément :

AT("XXXXX-XXXXX", "orders.amount", gte, 100) * AT("XXXXX-XXXXX", "orders.status", eq, "paid")

Ce segment contient les utilisateurs ayant au moins une commande à la fois d’un montant de 100 ou plus et payée. Un utilisateur avec une grosse commande non payée et une petite commande payée ne correspond pas. Les conditions reliées par OR n’ont pas à correspondre au même élément. Les conditions sur deux listes différentes sont vérifiées sur chaque liste séparément.

Certains opérateurs fonctionnent différemment sur un champ d’un tag ObjectList :

  • notset. Aucun élément de la liste n’a de valeur dans ce champ. Un utilisateur sans la liste correspond également.
  • noteq. Au moins un élément a une valeur dans ce champ, et cette valeur diffère de celle indiquée. Les éléments sans ce champ ne comptent pas. Un utilisateur avec des commandes aux statuts paid et new correspond à noteq "paid".
  • notin sur un champ List. Aucun élément ne contient l’une des valeurs indiquées.
  • notin sur un champ d’un autre type. Au moins un élément a dans ce champ une valeur qui ne figure pas parmi les valeurs indiquées.

notset et notin sur un champ List ne sont pas liés au même élément que les autres conditions reliées par AND.

Exporter des segments avec des tags d’objet

Anchor link to

/exportSegment exporte les champs des tags d’objet :

  • CSV. Chaque champ est une colonne distincte nommée <object>.<field>, et les tags d’objet eux-mêmes n’ont pas de colonne. Un champ d’un ObjectList contient toutes les valeurs distinctes des éléments sous forme de tableau JSON, de la même manière qu’un tag List : ["120","50"].
  • json et json_each_line. Les champs d’un tag Object sont renvoyés comme des tags distincts nommés <object>.<field>. Un tag ObjectList est renvoyé comme une seule entrée dans tags, avec les éléments dans object_list.items. Chaque élément liste ses champs avec leurs noms courts, et chaque champ porte sa valeur sous une clé nommée d’après son type : integer, string, list, date, boolean, price ou version. Les valeurs entières sont renvoyées sous forme de chaînes :
{
"name": "orders",
"object_list": {
"items": [
{ "fields": [{ "name": "amount", "integer": "120" }, { "name": "status", "string": "paid" }] },
{ "fields": [{ "name": "amount", "integer": "50" }] }
]
}
}

Si tagsList nomme un tag d’objet, tous ses champs sont exportés.