Einheiten in Ihr System übernehmen
Übernehmen Sie die Einheiten Ihrer Organisation mit Cursor-Paginierung in ERP, MES oder Datenbank, setzen Sie nach einer Unterbrechung fort und erkennen Sie Änderungen.
listBatteries liefert die Einheiten (einzelne Batterien) Ihrer
Organisation Seite für Seite. Diese Anleitung liest alle, speichert den Cursor, damit ein unterbrochener Lauf
weitermachen kann, und zeigt, wie Sie erkennen, welche Einheiten sich seit dem letzten Lauf geändert haben. Sie
brauchen einen Schlüssel mit dem Scope read.
Um Änderungen zu bemerken, ohne jede Einheit erneut zu lesen, fragen Sie den Änderungsfeed
listChanges ab; der Ablauf
Pass-Links zurück ins ERP zeigt, wie.
Die Liste
curl -sS "$BATTERYPASS_URL/api/v1/batteries?limit=200&passport_status=published" \
-H "Authorization: Bearer $BATTERYPASS_API_KEY"{
"items": [
{
"id": "0192a3f0-5b7c-7d21-8e4f-6a2b9c1d3e5f",
"serial_number": "SV2027-000184",
"battery_model_id": "0192f0a1-6c2e-7d4b-9a10-3e5f7b2c8d41",
"model_version_id": "0192f0a2-1b3c-7e5d-8f60-7a8b9c0d1e2f",
"battery_status": "original",
"passport_status": "published",
"manufacturing_date": "2026-06-18",
"facility_id": "0192f09e-4a5b-7c6d-9e8f-0a1b2c3d4e5f",
"identifiers_locked_at": "2026-07-02T10:15:00Z",
"successor_battery_ids": [],
"row_version": 4,
"created_at": "2026-06-20T08:00:12Z",
"updated_at": "2026-07-02T10:15:00Z"
}
],
"next_cursor": "eyJTZXJpYWxOdW1iZXIiOiJTVjIwMjctMDAwMTg0IiwiSUQiOiIwMTkyYTNmMC01YjdjLTdkMjEtOGU0Zi02YTJiOWMxZDNlNWYifQ"
}Die Einheiten sind nach Seriennummer, dann ID sortiert. limit liegt zwischen 1 und 200 (Standard 50).
next_cursor ist auf der letzten Seite null. Diese Filter schränken die Liste ein und lassen sich kombinieren:
| Parameter | Nur Einheiten, |
|---|---|
battery_model_id | die zu diesem Batteriemodell gehören |
model_version_id | die zu dieser Modellversion gehören |
passport_status | deren Pass diesen Status hat: draft, qr_locked, published, update_needed, suspended, withdrawn, deleted_recycled |
serial_prefix | deren Seriennummer mit diesem Text beginnt (1 bis 50 Zeichen) |
import_id | die dieser Tabellenimport angelegt hat |
Einen Filter nach Änderungsdatum gibt es nicht. Änderungen erkennen Sie auf Ihrer Seite, wie weiter unten beschrieben.
Alle Seiten lesen
Behalten Sie in einem Lauf für jede Seite dieselben Filter bei, und speichern Sie den Cursor erst, nachdem Sie die zugehörige Seite gespeichert haben. Ist der Lauf vollständig, löschen Sie den Cursor, damit der nächste Lauf von vorn beginnt.
// sync-units.mts: npx tsx sync-units.mts
import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
const BASE = `${process.env.BATTERYPASS_URL}/api/v1`;
const headers = { Authorization: `Bearer ${process.env.BATTERYPASS_API_KEY}` };
const STATE = 'units.cursor'; // lets an interrupted pass continue where it stopped
type Unit = { id: string; serial_number: string; passport_status: string; row_version: number };
// Placeholder: insert or update the unit in your database, keyed by id.
function upsert(unit: Unit) {
console.log(unit.id, unit.serial_number, unit.passport_status, unit.row_version);
}
let cursor: string | null = existsSync(STATE) ? readFileSync(STATE, 'utf8') : null;
do {
const query = new URLSearchParams({ limit: '200' });
if (cursor) query.set('cursor', cursor);
const res = await fetch(`${BASE}/batteries?${query}`, { headers });
if (!res.ok) throw new Error(`listBatteries: ${res.status} ${(await res.json()).code}`);
const page: { items: Unit[]; next_cursor: string | null } = await res.json();
page.items.forEach(upsert);
cursor = page.next_cursor;
if (cursor) writeFileSync(STATE, cursor); // only after the page is stored
} while (cursor);
rmSync(STATE, { force: true }); // pass complete: the next one starts at the beginningWas der Cursor ist und was nicht
- Der Cursor ist undurchsichtig: Speichern Sie ihn unverändert und senden Sie ihn so zurück. Er läuft nicht ab.
- Er markiert eine Position in der Reihenfolge der Seriennummern, keinen Zeitpunkt. Eine Einheit, die während eines Laufs angelegt wird und deren Seriennummer vor dem Cursor einsortiert ist, fehlt im Rest dieses Laufs; der nächste Lauf findet sie. Fragen Sie mit einem gespeicherten Cursor also nicht „was ist seit dem letzten Mal neu“: Jeder Lauf ist ein vollständiger Durchgang, und der Cursor lässt nur einen unterbrochenen Durchgang fortsetzen.
- Lehnt BatteryPass einen gespeicherten Cursor ab (
400 validation_erroraufcursor), löschen Sie ihn und beginnen einen neuen Durchgang.
Paginierung beschreibt die Regeln für alle Listen.
Änderungen erkennen
Vergleichen Sie jede Einheit mit dem, was Sie im vorigen Lauf gespeichert haben:
| Was sich geändert hat | Woran Sie es erkennen |
|---|---|
| Eine neue Einheit | Eine id, die Sie noch nicht gespeichert haben |
Die eigenen Daten der Einheit (Seriennummer, Datumsangaben, Standort, battery_status, Modellversion, gesperrte Kennungen) | row_version ist höher und updated_at später |
Der Passstatus, z. B. published → update_needed | passport_status weicht ab; row_version ändert sich dadurch nicht |
| Eine neue Passversion | current_version.version_no von getPassport ist höher |
| Werte der Einheit | revision und recorded_at je Feld in listBatteryValues |
Über die API werden Einheiten nie gelöscht; eine Batterie am Ende ihres Lebens zeigt das in battery_status und
passport_status. Die Werte jeder Einheit zu lesen kostet eine Anfrage pro Einheit: Beschränken Sie das auf
Einheiten, deren Status oder Version sich geändert hat, oder verteilen Sie es auf mehrere Läufe. Das Rezept
Data-Warehouse-Abgleich schreibt Einheiten und Werte als JSON Lines.
Limits
Alle Schlüssel Ihrer Organisation teilen sich 600 Anfragen pro Minute. Ein vollständiger Durchgang über 10 000
Einheiten mit limit=200 braucht 50 Anfragen; die Werte jeder Einheit zu lesen kostet weitere 10 000. Auf
429 rate_limited reagieren Sie, indem Sie Retry-After abwarten (Ratenlimits,
Fehler und Wiederholungen).
Pässe exportieren
Laden Sie BatteryPass-JSON, PDF und QR-Code einer Passversion sowie die Einheiten Ihrer Organisation als Tabelle herunter.
Fehler und Wiederholungen
Entscheiden Sie, welche Antworten Sie wiederholen und welche Sie beheben, warten Sie mit Backoff und Jitter, beachten Sie Retry-After und protokollieren Sie die request_id.