Entwickler · API v1.0.0
NotiPilot Device API — Entwicklerdokumentation
API-Version: 1.0.0 · Base path: /api/v1
Mit NotiPilot registrieren Sie die Geräte Ihrer mobilen App, teilen sie in Segmente ein und senden über das NotiPilot-Dashboard Push-Benachrichtigungen an diese Geräte. Ihre mobile App kommuniziert dabei nur mit zwei Endpoints:
| Endpoint | Wann wird er aufgerufen? |
|---|---|
POST /api/v1/register-device |
Nach Erteilung der Benachrichtigungsberechtigung, bei jedem App-Start und wenn sich der Push-Token ändert |
POST /api/v1/identify-device |
Wenn sich der Nutzer anmeldet (um das Gerät mit Ihrer eigenen Nutzer-ID zu verknüpfen) |
Benachrichtigungen werden über das NotiPilot-Dashboard versendet; die mobile App muss selbst nichts senden.
Plattform-Leitfäden
| Plattform | Für wen? |
|---|---|
| Expo | Expo-Apps (Managed Workflow / Development Build) |
| React Native | Bare- / CLI-React-Native-Projekte |
| Flutter | Flutter-Apps (Android + iOS) |
| Ionic | Ionic- + Capacitor-Apps |
| Firebase | Projekte, die bereits Firebase Cloud Messaging nutzen (alle Technologien) |
| Shopify | Betreiber einer mobilen App für ihren Shopify-Shop (Kundenzuordnung, E-Commerce-Segmente) |
| Android | Native Android — Java |
| Kotlin | Native Android — Kotlin (View / Jetpack Compose) |
| iOS | Native iOS — Apple-Developer- / APNs-Einrichtung und Objective-C |
| Swift | Native iOS — Swift (UIKit / SwiftUI) |
Versionsunterstützung und Versionierungsrichtlinie
1. Wie funktioniert es?
Mobile App ──(Expo Push Token + Geräteinformationen)──▶ NotiPilot API
│
NotiPilot-Dashboard ──(Titel, Nachricht, Segment)──▶ Expo Push Service ──▶ FCM (Android) / APNs (iOS) ──▶ Gerät
NotiPilot 1.0.0 nutzt für die Zustellung den Expo Push Service. Daraus ergibt sich:
- Jedes Gerät benötigt einen Expo Push Token (
ExponentPushToken[...]). In Expo- und React-Native-Apps erhalten Sie diesen Token direkt überexpo-notifications. In nativen Android-/iOS-Apps wird der FCM-/APNs-Token des Geräts in einen Expo-Token konvertiert (die jeweiligen Leitfäden beschreiben das Schritt für Schritt). - Ihre App benötigt ein Expo-(EAS-)Projekt, in das die FCM-V1- / APNs-Zugangsdaten hochgeladen wurden (
eas credentials). - Beim Anlegen Ihrer App im NotiPilot-Dashboard geben Sie die Expo Project ID und den Expo Access Token an.
Sie können auch direkt einen FCM- oder APNs-Token an die API senden (
provider: "fcm" | "apns"). Diese Geräte werden registriert und erscheinen in Segmenten, in Version 1.0.0 werden Benachrichtigungen jedoch nur an Geräte mit Expo-Token zugestellt. Die direkte Zustellung über FCM/APNs ist auf der Roadmap.
2. Bevor Sie beginnen
- Legen Sie Ihre App im NotiPilot-Dashboard über den Bildschirm App hinzufügen an.
- Tragen Sie im Feld Expo Project ID Ihre EAS-Projekt-ID ein (UUID,
app.json→extra.eas.projectId). - Tragen Sie im Feld Expo Access Token den Token ein, den Sie unter expo.dev → Access Tokens erstellt haben. (Pflicht, wenn in Ihrem Expo-Projekt „Enhanced Security for Push Notifications“ aktiviert ist.)
- Die
app_id, die Ihre mobile App an die API sendet, muss exakt mit der im Dashboard eingetragenen Expo Project ID übereinstimmen. Wird eine nicht registrierteapp_idgesendet, antwortet die API mit404 unknown_app.
3. Allgemeine Regeln
| Thema | Wert |
|---|---|
| Base URL | https://app.notipilot.com/api/v1 |
| Protokoll | Nur HTTPS |
| Request-Body | Content-Type: application/json, UTF-8 |
| Authentifizierung | Nicht erforderlich. Da die Device API in die mobile App eingebettet ist, verwendet sie keinen geheimen Schlüssel; die app_id ist kein geheimer Wert. Die Autorisierung erfolgt dadurch, dass die app_id im Dashboard registriert ist. |
| Rate Limit | 300 Requests pro Minute und IP. Bei Überschreitung werden 429 und der Header Retry-After zurückgegeben. |
| Versions-Header | Jede Antwort enthält den Header X-NotiPilot-API-Version: 1.0.0. |
Aus Gründen der Abwärtskompatibilität funktionieren auch die (unversionierten) Adressen
/api/register-deviceund/api/identify-devicegenauso wie v1. Verwenden Sie für neue Integrationen/api/v1.
4. Endpoints
4.1 POST /api/v1/register-device
Registriert oder aktualisiert ein Gerät (Upsert). Der Zuordnungsschlüssel ist die Kombination aus app_id + device_uid; wiederholte Aufrufe für dasselbe Gerät sind unbedenklich.
Request-Felder
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
app_id |
string (≤255) | ✅ | Expo Project ID aus dem Dashboard |
device_uid |
string (≤191) | ✅ | Pro Installation dauerhafte, eindeutige Geräte-ID (siehe Geräte-ID) |
token |
string (≤512) | ✅ | Push-Token. Format für Expo-Token: ExponentPushToken[...] |
platform |
"android" | "ios" | "web" |
✅ | Plattform des Geräts |
provider |
"expo" | "fcm" | "apns" |
– | Wird automatisch aus dem Token-Format erkannt, falls nicht angegeben |
external_id |
string (≤191) | null | – | Nutzer-ID aus Ihrem eigenen System. Mit null wird die Zuordnung aufgehoben (Logout-Szenario) |
attributes |
object | – | Segmentierungsmerkmale (siehe Attributes) |
tags |
string[] | – | Freie Tags (maximal 50, jeweils ≤64 Zeichen) |
consent_marketing |
boolean | – | Einwilligung in Marketing-Benachrichtigungen. Standard: true |
Beispiel-Request
curl -X POST "https://app.notipilot.com/api/v1/register-device" \
-H "Content-Type: application/json" \
-d '{
"app_id": "1c2d3e4f-5a6b-7c8d-9e0f-112233445566",
"device_uid": "8f14e45f-ceea-467a-9575-0b3f5c6b2a11",
"token": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
"platform": "android",
"attributes": {
"locale": "tr",
"country": "TR",
"city": "Istanbul",
"app_version": "2.4.0"
},
"tags": ["beta"]
}'
Erfolgreiche Antwort — 200 OK
{
"success": true,
"message": "Device registered successfully",
"device_id": 1234,
"expo_token_id": 567,
"provider": "expo"
}
4.2 POST /api/v1/identify-device
Verknüpft das Gerät mit Ihrer eigenen Nutzer-ID (external_id) und aktualisiert optional Attributes/Tags. Rufen Sie den Endpoint auf, wenn sich der Nutzer anmeldet.
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
app_id |
string | ✅ | Expo Project ID aus dem Dashboard |
device_uid |
string | ✅ | Derselbe Wert wie bei register-device |
external_id |
string (≤191) | ✅ | Ihre Nutzer-ID |
attributes |
object | – | Wird mit den vorhandenen Attributes zusammengeführt |
tags |
string[] | – | Ersetzt die vorhandenen Tags, falls angegeben |
consent_marketing |
boolean | – | |
token, platform |
string | – | Wurde das Gerät noch nicht registriert, erfolgt mit diesen beiden Feldern eine vollständige Registrierung |
curl -X POST "https://app.notipilot.com/api/v1/identify-device" \
-H "Content-Type: application/json" \
-d '{
"app_id": "1c2d3e4f-5a6b-7c8d-9e0f-112233445566",
"device_uid": "8f14e45f-ceea-467a-9575-0b3f5c6b2a11",
"external_id": "user_98765",
"attributes": { "gender": "female" }
}'
{ "success": true, "message": "Device identified", "device_id": 1234 }
Ist das Gerät noch nicht registriert und wurde kein token gesendet, wird das Gerät ohne Token angelegt ("auto_registered": true). Dieses Gerät erhält keine Benachrichtigungen, bis über register-device ein Token gesendet wird.
4.3 GET /api/v1/version
Health-Check und Versionsinformationen.
{ "success": true, "api_version": "1.0.0", "min_supported_version": "1.0.0" }
5. Attributes und Segmente
Das NotiPilot-Dashboard erzeugt aus den attributes-Werten der Geräte automatisch Segmente (z. B. „Türkischsprachige“, „Istanbul“, „Türkei + Istanbul“). Standortbasierte Segmente entstehen nur für Geräte, die country und city senden. Senden Sie diese Felder nicht, wird das Gerät nur bei Kampagnen an „Alle Nutzer“ berücksichtigt.
Standardschlüssel (werden vom Dashboard erkannt und beschriftet):
| Schlüssel | Format | Beispiel |
|---|---|---|
locale |
ISO-639-1-Sprachcode (Kleinbuchstaben) | "tr", "en", "de" |
country |
ISO-3166-1-alpha-2-Ländercode (Großbuchstaben) | "TR", "DE", "NL" |
city |
Städtename in einheitlicher Schreibweise | "Istanbul", "Ankara" |
gender |
male | female | other |
"female" |
Sie können auch eigene Schlüssel hinzufügen (app_version, plan, favorite_team …).
Regeln
- Maximal 50 Schlüssel. Schlüssel bestehen aus den Zeichen
A-Z a-z 0-9 _ . -und sind maximal 64 Zeichen lang. - Werte können String, Zahl, Boolean oder
nullsein. String-Werte sind maximal 255 Zeichen lang. - Verwenden Sie in Werten nicht die Zeichen
,und:(sie dienen in Segmentschlüsseln als Trennzeichen). - Zusammenführen (Merge): Die gesendeten Attributes werden mit den vorhandenen Werten zusammengeführt; nicht gesendete Schlüssel bleiben erhalten. Um einen Schlüssel zu löschen, senden Sie seinen Wert als
null. - Wenn Sie das Feld
attributesgar nicht senden, bleiben die gespeicherten Attributes unverändert. - Legen Sie keine personenbezogenen Daten wie E-Mail-Adressen, Telefonnummern oder Ausweisnummern in Attributes ab. Verwenden Sie für die Nutzerzuordnung
external_id.
Woher bekomme ich Stadt und Land? Die Regionseinstellung des Geräts (locale → Land) erfordert keine Standortberechtigung und ist immer verfügbar. Für die Stadt eignen sich die im Nutzerprofil hinterlegte Stadt (die zuverlässigste Methode), Reverse Geocoding bei erteilter Standortberechtigung oder eine IP-basierte Standortermittlung in Ihrem eigenen Backend. Auch ohne Standortberechtigung sollten Sie zumindest country und locale senden.
6. Wie sollte die Geräte-ID erzeugt werden?
Für das Feld device_uid:
- Erzeugen Sie beim ersten App-Start eine UUID v4 und speichern Sie sie dauerhaft (Android:
SharedPreferences/DataStore, iOS: Keychain, Expo:expo-secure-store). - Sie darf sich bei App-Updates nicht ändern; nach Deinstallation und Neuinstallation der App ist eine Änderung normal.
- Verwenden Sie keine IMEI, MAC-Adresse oder Werbe-ID (IDFA/GAID).
7. Fehlerantworten
Alle Fehlerantworten haben dieselbe Struktur:
{
"success": false,
"error": "validation_failed",
"message": "Validation failed",
"errors": { "platform": "Must be one of: android, ios, web" }
}
| HTTP | error |
Bedeutung | Was ist zu tun? |
|---|---|---|---|
| 400 | invalid_json |
Body ist kein gültiges JSON | Request korrigieren, nicht erneut versuchen |
| 400 | validation_failed |
Ein oder mehrere Felder sind ungültig; Details in errors |
Request korrigieren, nicht erneut versuchen |
| 404 | unknown_app |
app_id ist bei NotiPilot nicht registriert |
Expo Project ID im Dashboard prüfen |
| 429 | rate_limited |
Rate Limit überschritten | Nach retry_after Sekunden erneut versuchen |
| 500 | server_error |
Serverseitiger Fehler | Mit Exponential Backoff erneut versuchen |
Empfohlenes Vorgehen auf Client-Seite: Nur bei 429 und 5xx (sowie bei Netzwerkfehlern) erneut versuchen; 4xx-Fehler protokollieren.
8. Empfohlener Ablauf
- App wird geöffnet →
device_uidwird gelesen (bzw. erzeugt, falls nicht vorhanden). - Benachrichtigungsberechtigung wird angefragt (Pflicht unter Android 13+ und iOS).
- Bei erteilter Berechtigung wird der Push-Token abgerufen →
register-devicewird aufgerufen (zusammen mit locale/country/city). - Nutzer meldet sich an →
identify-devicewird aufgerufen (mitexternal_id). - Nutzer meldet sich ab →
register-devicewird mit"external_id": nullaufgerufen. - Push-Token wird erneuert (
onNewToken/ Token-Listener) →register-devicewird erneut aufgerufen.
9. Inhalt der Benachrichtigung
Eine über das Dashboard gesendete Benachrichtigung besteht aus title, body und optional einem JSON-Feld data. Der Inhalt von data wird an Ihre App übergeben; nutzen Sie ihn für Szenarien wie Deep Links, zum Beispiel:
{ "screen": "product", "product_id": "12345" }
Unter Android werden Benachrichtigungen an den Kanal default gesendet (channelId: "default"); legen Sie in Ihrer App einen Benachrichtigungskanal mit dieser ID an.
10. Änderungsprotokoll
| Version | Datum | Änderungen |
|---|---|---|
| 1.0.0 | 2026-09 | Erste stabile Version. Base path /api/v1, Endpoint version, einheitliches Fehlerformat (error-Codes), Rate Limit, Validierung der app_id, Merge-Verhalten für Attributes. |