# Objekt-Tags API (Beta)

Objekt-Tags speichern strukturierte Daten über einen Benutzer in einem einzigen Tag. Ein Tag vom Typ `Object` enthält ein Objekt mit benannten Feldern, zum Beispiel die letzte Bestellung `order` mit ihren Feldern `amount` und `status`. Ein Tag vom Typ `ObjectList` enthält ein Array solcher Objekte, zum Beispiel alle Bestellungen `orders`. Sie definieren die Felder einmal, schreiben und lesen Werte über die Tag-API und erstellen Segmente nach Feldwerten.

<Aside type="caution" title="Beta">
Objekt-Tags befinden sich in der Beta-Phase und sind auf Anfrage verfügbar. Wenden Sie sich an den [Pushwoosh Support](https://help.pushwoosh.com/hc/en-us/requests/new), um sie für Ihr Konto zu aktivieren. Während der Beta-Phase funktionieren Objekt-Tags nur über die API:

- Das Control Panel hat keinen Bildschirm für Objekt-Tags.
- Felder von Objekt-Tags können nicht in Nachrichteninhalte eingefügt werden.
- Customer Journey unterstützt keine Objekt-Tags.
</Aside>

## Funktionsweise von Objekt-Tags

Ein Objekt-Tag hat ein Schema und einen Wert. Das Schema besteht aus dem Tag-Namen und einer Liste von Feldern, jedes mit seinem eigenen skalaren Typ. Der Wert wird in den Feldern gespeichert, für jeden Benutzer separat.

- **Feld.** Jedes Feld ist ein Tag mit dem Namen `<object>.<field>`, zum Beispiel `order.amount`. Sie segmentieren nach Feldern, und unter diesem Namen können Sie ein Feld eines `Object`-Tags schreiben.
- **`Object`-Wert.** Ein Objekt pro Benutzer, zum Beispiel `"order": {"amount": 120, "status": "paid"}`.
- **`ObjectList`-Wert.** Ein Array von Objekten mit denselben Feldern, zum Beispiel `"orders": [{"amount": 120, "status": "paid"}, {"amount": 50}]`.

Objekt-Tags sind immer User-specific. Das bedeutet, dass der Wert dem Benutzer gehört, nicht einem einzelnen Gerät, und auf alle Geräte des Benutzers kopiert wird. Für reguläre Tags siehe [Tags API](/de/developer/api-reference/tags/).

## Schema-Regeln

Pushwoosh prüft diese Regeln, wenn Sie ein Objekt-Tag erstellen oder ein Feld hinzufügen:

- Objekt- und Feldnamen enthalten nur lateinische Buchstaben, Ziffern und `_`.
- Der vollständige Feldname `<object>.<field>` ist höchstens 64 Zeichen lang.
- Ein Objekt-Tag hat 1 bis 20 Felder. Bei Feldnamen wird die Groß- und Kleinschreibung nicht beachtet, daher sind `Amount` und `amount` dasselbe Feld.
- Ein Feld hat einen dieser Typen: `INTEGER`, `STRING`, `LIST`, `DATE`, `BOOLEAN`, `PRICE`, `VERSION`. Zeitzonenfelder und verschachtelte Objekte werden nicht unterstützt.
- Ein Feld kann keinen Namen erhalten, den bereits ein anderes Tag hat. Wenn ein Tag `order.note` existiert, schlägt das Hinzufügen des Feldes `note` zu `order` mit `tag order.note already exists` fehl.
- Ein Objekt-Tag kann sein letztes Feld nicht verlieren. Löschen Sie stattdessen das Objekt-Tag.
- Ein Feld oder ein Objekt-Tag, das verwendet wird, kann nicht gelöscht werden. Der Fehler listet auf, wo es verwendet wird, zum Beispiel `field is in use: segment Big buyers, in-app Spring sale`. Segmente, In-Apps, laufende Customer Journey-Kampagnen, Presets, E-Mail-Vorlagen und andere Elemente, die auf das Tag verweisen, zählen als Verwendungen.

## Schema verwalten

Erstellen und ändern Sie Objekt-Tags mit den folgenden REST-Methoden. Verwenden Sie `/json/1.3/addTag` nur für reguläre Tags, da diese Methode keine Felder definieren kann.

### Basis-URL

```
https://rpc-api.svc-nue.pushwoosh.com
```

### Authentifizierung

Jede Anfrage muss einen `Authorization`-Header mit Ihrem [Server API Token](/de/developer/api-reference/api-access-token/#server-api-token) enthalten. Ein Device API Token erhält HTTP 403 `a device API token cannot call this method, use an account API token`.

```
Authorization: Api YOUR_API_TOKEN
```

### Endpunkte

Diese Methoden verwalten das Schema von Objekt-Tags:

| Methode | Pfad | Beschreibung |
| :---- | :---- | :---- |
| `POST` | `/api/tags` | Ein Objekt-Tag mit seinen Feldern erstellen |
| `GET` | `/api/tags/{name}` | Ein Objekt-Tag mit seinen Feldern abrufen |
| `GET` | `/api/tags` | Tags auflisten. Ein Objekt-Tag wird mit seinen `fields` zurückgegeben, und die Felder werden nicht als separate Tags aufgelistet |
| `POST` | `/api/tags/{name}/fields` | Ein Feld hinzufügen |
| `DELETE` | `/api/tags/{name}/fields/{field}` | Ein Feld löschen |
| `DELETE` | `/api/tags/{name}` | Ein Objekt-Tag mit allen seinen Feldern löschen |

`POST /api/tags` und beide Feldmethoden geben das Objekt-Tag nach der Änderung zurück, eingeschlossen in `{"tag": {...}}`. `DELETE /api/tags/{name}` gibt `{}` zurück.

Wenn Objekt-Tags für Ihr Konto nicht aktiviert sind, schlagen `POST /api/tags` mit einem Objekttyp und beide Feldmethoden mit HTTP 403 `object tags are not enabled for the account` fehl. `GET /api/tags/{name}` und `DELETE /api/tags/{name}` geben HTTP 404 `tag not found` zurück, und `GET /api/tags` listet keine Objekt-Tags auf. Ohne aktivierte Objekt-Tags können Sie keines erstellen, daher gibt es nichts, wohin Werte geschrieben werden könnten.

<span id="create-an-object-tag" />

### Objekt-Tag erstellen

`POST` `/api/tags`

##### Request-Body

| Name | Typ | Beschreibung |
| :---- | :---- | :---- |
| name\* | string | Name des Objekt-Tags. |
| type\* | string | `OBJECT` für ein Objekt oder `OBJECT_LIST` für eine Liste von Objekten. |
| fields\* | array | Felder des Objekts, 1 bis 20. |
| fields[].name\* | string | Feldname. Das Feld wird zum Tag `<name>.<fields[].name>`. |
| fields[].type\* | string | Feldtyp: `INTEGER`, `STRING`, `LIST`, `DATE`, `BOOLEAN`, `PRICE` oder `VERSION`. |

```json title="Beispiel"
{
  "name": "orders",
  "type": "OBJECT_LIST",
  "fields": [
    { "name": "amount", "type": "INTEGER" },
    { "name": "status", "type": "STRING" }
  ]
}
```

```json title="Antwort"
{
  "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" }
    ]
  }
}
```

Das Tag wird unabhängig vom Wert von `user_specific` als User-specific erstellt. `GET /api/tags/{name}` gibt dasselbe Objekt ohne den `tag`-Wrapper zurück. Die Felder sind nach Namen sortiert.

### Feld hinzufügen

`POST` `/api/tags/{name}/fields`

```json title="Beispiel: POST /api/tags/orders/fields"
{
  "field": { "name": "note", "type": "STRING" }
}
```

Sie können das neue Feld sofort als Teil des gesamten Tag-Werts schreiben. Das Hinzufügen eines Feldes schlägt fehl, wenn das Objekt-Tag bereits 20 Felder hat oder wenn ein Tag mit dem vollständigen Feldnamen existiert, siehe [Fehler](#errors).

### Feld löschen

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

Zum Beispiel löscht `DELETE /api/tags/orders/fields/note` das Feld `orders.note`. Sie können weder das letzte Feld noch ein verwendetes Feld löschen, siehe [Fehler](#errors).

<span id="errors" />

### Fehler

Fehler haben das Format `{"code": <n>, "message": "...", "details": [...]}`. Beim Erstellen eines Objekt-Tags beginnen die 400-Meldungen mit `validate: `.

| HTTP-Status | Meldung | Ursache |
| :---- | :---- | :---- |
| 400 | `object tag and field names must contain only letters, digits and underscores` | Ein Name enthält ein anderes Zeichen. |
| 400 | `an object tag needs 1 to 20 fields` | Beim Erstellen keine Felder oder mehr als 20 Felder. |
| 400 | `an object tag has at most 20 fields` | Das Objekt-Tag hat bereits 20 Felder. |
| 400 | `field <name> is given twice` | Zwei Felder haben denselben Namen, ohne Beachtung der Groß- und Kleinschreibung. |
| 400 | `<object>.<field>: object and field names together cannot be longer than 64 characters` | Der vollständige Feldname ist zu lang. |
| 400 | `<object>.<field>: field type must be INTEGER, STRING, LIST, DATE, BOOLEAN, PRICE or VERSION` | Nicht unterstützter Feldtyp. |
| 400 | `an object tag needs at least one field; delete the object tag instead` | Sie haben versucht, das letzte Feld zu löschen. |
| 400 | `field is in use: ...`, `tag is in use: ...` | Das Feld oder das Objekt-Tag wird in Segmenten, In-Apps, Customer Journey-Kampagnen oder anderen Elementen verwendet. |
| 403 | `object tags are not enabled for the account` | Objekt-Tags sind für das Konto nicht aktiviert. |
| 403 | `a device API token cannot call this method, use an account API token` | Die Anfrage verwendet ein Device API Token. |
| 404 | `tag not found` | `GET` oder `DELETE /api/tags/{name}`: Es gibt kein solches Tag, der Name ist ein Feld, oder Objekt-Tags sind nicht aktiviert. |
| 404 | `object tag not found`, `field not found` | Feldmethoden: Es gibt kein solches Objekt-Tag oder Feld. |
| 409 | `tag already exists` | Ein Tag mit dem Namen des Objekt-Tags existiert. |
| 409 | `tag <object>.<field> already exists` | Ein Tag mit dem vollständigen Namen des Feldes existiert. |

## Werte schreiben

Schreiben Sie Werte von Objekt-Tags mit [`/setTags`](/de/developer/api-reference/device-api/#settags) und [`/bulkSetTags`](/de/developer/api-reference/audience-api/#bulksettags). Diese Methoden behalten ihre eigene Authentifizierung: `/setTags` erwartet ein Device API Token im Header `Authorization: Token`, und `/bulkSetTags` erwartet das API-Zugriffstoken in `auth`. Senden Sie einen `Object`-Wert als JSON-Objekt und einen `ObjectList`-Wert als Array von Objekten:

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

Wenn Sie den Wert per HWID festlegen, wird er beim Benutzer dieses Geräts gespeichert.

Jedes Feld nimmt einen Wert im Format seines Typs an:

| Feldtyp | Beispielwert |
| :---- | :---- |
| `INTEGER` | `120` |
| `STRING` | `"paid"` |
| `LIST` | `["gift", "express"]` |
| `DATE` | `"2026-10-02 22:11"` (UTC), `"2026-10-02"` oder ein Unix-Zeitstempel in Sekunden |
| `BOOLEAN` | `true` oder `false` |
| `PRICE` | `19.95` |
| `VERSION` | `"1.0.0"` |

### Schreiben ersetzt den gesamten Wert

Jeder Schreibvorgang ersetzt den gespeicherten Wert des Objekt-Tags:

- Ein Feld, das im neuen Wert fehlt, wird gelöscht. Ein als `null` gesendetes Feld wird ebenfalls gelöscht.
- `null`, `[]` oder `""` löscht den gesamten Wert.
- `{}` löscht alle Felder eines `Object`-Tags.
- Ein Schlüssel, der kein Feld des Objekts ist, wird übersprungen.
- Wenn ein Feldwert nicht zum Feldtyp passt, wird der gesamte Wert des Tags abgelehnt und der gespeicherte Wert bleibt unverändert.

`/setTags` meldet einen abgelehnten Wert nicht in seiner Antwort. Prüfen Sie das Ergebnis mit [`/getTags`](#read-values) oder verwenden Sie `/bulkSetTags`, das für jedes Tag ein Ergebnis meldet.

### Ein einzelnes Feld eines Object schreiben

Schreiben Sie ein einzelnes Feld eines `Object`-Tags über seinen vollständigen Namen. `increment` und die anderen Operationen von [`/setTags`](/de/developer/api-reference/device-api/#settags) funktionieren mit Feldern:

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

Ein Feld eines `ObjectList`-Tags kann nicht einzeln geschrieben werden, da nicht klar ist, welches Element geändert werden soll. `/setTags` ignoriert einen solchen Wert. Senden Sie stattdessen die gesamte Liste.

### Objekt-Tags werden nicht automatisch erstellt

Ein Wert mit einem Objekt oder einem Array von Objekten für ein nicht existierendes Tag wird übersprungen. Die automatische Tag-Erstellung erstellt keine Objekt-Tags, erstellen Sie daher zuerst das Schema mit [`POST /api/tags`](#create-an-object-tag).

### bulkSetTags-Ergebnisse

Mit `detailed=true` gibt [`/bulkSetTags`-Status](/de/developer/api-reference/audience-api/#bulksettags-status) für ein Objekt-Tag zusätzlich zu `ok`, `tag not found` und `wrong value. expect :<type>` eines dieser Ergebnisse zurück:

| Ergebnis | Ursache |
| :---- | :---- |
| `object tags are stored on the user only` | Das Objekt-Tag ist nicht User-specific. |
| `cannot load the fields of the object` | Pushwoosh konnte die Felder des Objekt-Tags nicht lesen. |
| `wrong value. expect an object (a map) or, for a list of objects, an array of maps` | Der Wert passt nicht zum Objekt-Tag, oder ein Feldwert passt nicht zu seinem Typ. |
| `a field of a list of objects cannot be set on its own, set the whole list` | Der Wert wird für ein Feld eines `ObjectList`-Tags festgelegt. |

<span id="read-values" />

## Werte lesen

[`/getTags`](/de/developer/api-reference/device-api/#gettags) gibt einen `Object`-Wert als JSON-Objekt und einen `ObjectList`-Wert als Array von Objekten zurück:

```json title="Antwort"
{
  "status_code": 200,
  "status_message": "OK",
  "response": {
    "result": {
      "order": { "amount": 120, "status": "paid" },
      "orders": [
        { "amount": 120, "status": "paid" },
        { "amount": 50 }
      ]
    }
  }
}
```

Feldwerte werden in `/getTags` genauso zurückgegeben wie die Werte regulärer Tags: ein Date als Unix-Zeitstempel in Sekunden, ein Price als Zeichenfolge wie `"120.00"` und ein Boolean als `1` oder `0`.

<span id="segment-by-fields" />

## Nach Feldern segmentieren

Legen Sie Segmentbedingungen für Felder fest, nicht für das Objekt-Tag selbst. In der [Segmentierungssprache](/de/developer/api-reference/segmentation-filters-api/segmentation-language/) ist ein Feld ein Tag mit einem Namen mit Punkt, und es verwendet die Operatoren seines eigenen Typs:

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

Eine Bedingung für das Objekt-Tag selbst schlägt mit `object tag has no value of its own, use one of its fields` fehl.

### Bedingungen für eine ObjectList

Eine Bedingung für ein Feld eines `ObjectList`-Tags trifft auf einen Benutzer zu, wenn mindestens ein Element der Liste die Bedingung erfüllt. Mit AND verknüpfte Bedingungen für Felder derselben Liste müssen auf dasselbe Element zutreffen:

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

Dieses Segment enthält Benutzer mit mindestens einer Bestellung, die sowohl 100 oder mehr beträgt als auch bezahlt ist. Ein Benutzer mit einer großen unbezahlten Bestellung und einer kleinen bezahlten Bestellung trifft nicht zu. Mit OR verknüpfte Bedingungen müssen nicht auf dasselbe Element zutreffen. Bedingungen für zwei verschiedene Listen werden für jede Liste separat geprüft.

Einige Operatoren funktionieren für ein Feld eines `ObjectList`-Tags anders:

- **`notset`.** Kein Element der Liste hat einen Wert in diesem Feld. Ein Benutzer ohne die Liste trifft ebenfalls zu.
- **`noteq`.** Mindestens ein Element hat einen Wert in diesem Feld, und dieser Wert unterscheidet sich vom angegebenen. Elemente ohne das Feld zählen nicht. Ein Benutzer mit Bestellungen in den Status `paid` und `new` trifft auf `noteq "paid"` zu.
- **`notin` für ein List-Feld.** Kein Element enthält einen der angegebenen Werte.
- **`notin` für ein Feld eines anderen Typs.** Mindestens ein Element hat in diesem Feld einen Wert, der nicht unter den angegebenen Werten ist.

`notset` und `notin` für ein List-Feld sind nicht an dasselbe Element gebunden wie die anderen mit AND verknüpften Bedingungen.

## Segmente mit Objekt-Tags exportieren

[`/exportSegment`](/de/developer/api-reference/segmentation-filters-api/#exportsegment) exportiert die Felder von Objekt-Tags:

- **CSV.** Jedes Feld ist eine separate Spalte mit dem Namen `<object>.<field>`, und die Objekt-Tags selbst erhalten keine Spalte. Ein Feld einer ObjectList enthält alle unterschiedlichen Werte aus allen Elementen als JSON-Array, genauso wie ein List-Tag: `["120","50"]`.
- **`json` und `json_each_line`.** Felder eines `Object`-Tags werden als separate Tags mit dem Namen `<object>.<field>` ausgegeben. Ein `ObjectList`-Tag wird als ein Eintrag in `tags` ausgegeben, mit den Elementen in `object_list.items`. Jedes Element listet seine Felder mit kurzen Namen auf, und jedes Feld trägt seinen Wert unter einem Schlüssel, der nach seinem Typ benannt ist: `integer`, `string`, `list`, `date`, `boolean`, `price` oder `version`. Integer-Werte werden als Zeichenfolgen ausgegeben:

```json
{
  "name": "orders",
  "object_list": {
    "items": [
      { "fields": [{ "name": "amount", "integer": "120" }, { "name": "status", "string": "paid" }] },
      { "fields": [{ "name": "amount", "integer": "50" }] }
    ]
  }
}
```

Wenn `tagsList` ein Objekt-Tag nennt, werden alle seine Felder exportiert.