> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Parsed Streams Schnellstart

> Verbinden Sie sich mit Parsed Streams, senden Sie Ihren ersten Filter und lesen Sie eine dekodierte Benachrichtigung. Plus die vollständige JSON-RPC 2.0-Protokollreferenz.

<Tip>
  Neu bei Parsed Streams? Lesen Sie zuerst [das mentale Modell](/docs/de/parsed-streams#das-mentale-modell) — es erklärt, warum Filter so aussehen, wie sie aussehen.
</Tip>

## Schnellstart

<Steps>
  <Step title="Zugang erhalten">
    Parsed Streams befindet sich in der offenen Beta und ist in kostenpflichtigen Plänen verfügbar. Holen Sie sich Ihren API-Schlüssel vom [Helius-Dashboard](https://dashboard.helius.dev) und verbinden Sie sich mit dem Beta-Endpunkt unter `wss://fs-beta.helius-rpc.com`.

    Authentifizieren Sie sich mit dem API- Schlüssel Ihres Projekts, der als `api-key`-Abfrageparameter (oder im `x-api-key`-Header) übergeben wird.
  </Step>

  <Step title="Verbinden">
    ```bash wscat theme={"system"}
    wscat -c "wss://fs-beta.helius-rpc.com/?api-key=YOUR_API_KEY"
    ```

    Ein fehlender oder ungültiger Schlüssel wird mit HTTP 401 abgelehnt. Ein Projekt mit aktiver Verbindung erhält HTTP 429.
  </Step>

  <Step title="Mit einem Filter abonnieren">
    Senden Sie `parsedTransactionSubscribe` mit einem Filter und optionalen Optionen:

    ```json theme={"system"}
    {"jsonrpc":"2.0","id":1,"method":"parsedTransactionSubscribe","params":[{"programs":["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"]}]}
    ```

    Die Antwort `result` ist eine ganze Zahl **Abonnement-ID**:

    ```json theme={"system"}
    { "jsonrpc": "2.0", "id": 1, "result": 23 }
    ```
  </Step>

  <Step title="Eine Benachrichtigung lesen">
    Jede passende Transaktion wird als ein `parsedTransactionNotification` empfangen, bereits dekodiert, wobei `matchedIndexes` auf die Anweisungen verweist, die Ihr Filter getroffen hat. Siehe [Benachrichtigungen](#benachrichtigungen) für die vollständige Form.
  </Step>

  <Step title="Abmelden">
    ```json theme={"system"}
    { "jsonrpc": "2.0", "id": 2, "method": "parsedTransactionUnsubscribe", "params": [23] }
    ```

    Oder schließen Sie einfach die Verbindung — dadurch werden alle Abonnements entfernt.
  </Step>
</Steps>

## Anleitungen

<CardGroup cols={2}>
  <Card title="Jupiter Swaps verfolgen" icon="arrow-right-arrow-left" href="/docs/de/parsed-streams/guides/track-jupiter-swaps">
    Verwenden Sie `describeProgram`, um einen vertrauenswürdigen Filter zu erstellen, bevor Sie abonnieren.
  </Card>

  <Card title="Pump.fun Mints verfolgen" icon="rocket" href="/docs/de/parsed-streams/guides/track-pumpfun-mints">
    Ein wiederverbindungs-sicherer Listener, der jede neue Pump.fun Tokenbereitstellung protokolliert.
  </Card>

  <Card title="Reconnects handhaben" icon="rotate" href="/docs/de/parsed-streams/guides/handling-reconnects">
    Überleben Sie Leerlauf-Timeouts und Deployments und füllen Sie dann genau das nach, was Sie verpasst haben.
  </Card>
</CardGroup>

## Protokollreferenz

Parsed Streams verwendet **JSON-RPC 2.0** über eine einzelne WebSocket-Verbindung. Jede Anfrage erhält eine Antwort mit demselben `id`. Ein Abonnement sendet dann `parsedTransactionNotification`-Nachrichten, bis Sie sich abmelden oder die Verbindung trennen.

| Method                         | Zweck                                                                  |
| ------------------------------ | ---------------------------------------------------------------------- |
| `parsedTransactionSubscribe`   | Ein Abonnement mit einem Filter starten                                |
| `parsedTransactionUnsubscribe` | Ein Abonnement beenden                                                 |
| `ping`                         | Liveness-Check; gibt den aktuellen Slot zurück                         |
| `describeProgram`              | Listet die Anweisungen, Ereignisse und Kontorollen eines Programms auf |

### Abonnieren

Senden Sie `parsedTransactionSubscribe` mit einem Filter und optionalen Optionen. Die Antwort `result` ist eine ganze Zahl **Abonnement-ID**.

```json Request theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "parsedTransactionSubscribe",
  "params": [
    {
      "programs": ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"],
      "instructionNames": ["route", "shared_accounts_route"],
      "accounts": {
        "include": ["So11111111111111111111111111111111111111112"],
        "roles": { "user_transfer_authority": "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin" }
      },
      "includeFailed": false,
      "includeCpi": true
    },
    { "commitment": "confirmed", "details": "full" }
  ]
}
```

```json Response theme={"system"}
{ "jsonrpc": "2.0", "id": 1, "result": 23 }
```

#### Filterfelder

Mindestens eine von `programs` oder `accounts.include` ist erforderlich. Die von Ihnen festgelegten Felder werden mit **UND** kombiniert: Eine Anweisung muss alle erfüllen, um übereinzustimmen.

<ParamField body="programs" type="string[]">
  Programm-IDs zum Abgleichen (Base58-Adressen, keine Namen). Eine Anweisung stimmt überein, wenn ihr Programm in dieser Liste enthalten ist. ODER innerhalb der Liste.
</ParamField>

<ParamField body="instructionNames" type="string[]">
  Dekodierte Anweisungsnamen, wie etwa `route`. Zuerst genau abgeglichen, dann mit einem Fall- und Trennzeichen- unsensitiven Fallback, sodass `sharedAccountsRoute` auch dem Drahtnamen `shared_accounts_route` entspricht. ODER innerhalb der Liste. Nur Anweisungen, deren Namen der Katalog identifizieren konnte, können übereinstimmen, also nehmen Sie Namen von `describeProgram`.
</ParamField>

<ParamField body="accounts.include" type="string[]">
  Konto-Adressen. Eine Anweisung stimmt überein, wenn eines dieser Konten in ihrer Kontoliste erscheint. ODER innerhalb der Liste. Funktioniert für jede Anweisung, dekodiert oder nicht. Die Programm-ID selbst zählt hier nicht als Konto.
</ParamField>

<ParamField body="accounts.roles" type="object">
  Eine Zuordnung von dekodierten Kontorollennamen zu Adressen, wie etwa `{ "user_transfer_authority": "<pubkey>" }`. Jeder Eintrag muss gelten (UND über Einträge hinweg), und die Anweisung muss dekodiert sein, damit dies gilt. Rollennamen passen **genau**, ohne Berücksichtigung des Falls, also kopieren Sie diese von `describeProgram`, anstatt zu raten.
</ParamField>

<ParamField body="includeFailed" type="boolean" default="false">
  Beinhaltet Anweisungen aus fehlgeschlagenen Transaktionen.
</ParamField>

<ParamField body="includeCpi" type="boolean" default="true">
  Innere (CPI) Anweisungen können übereinstimmen. Setzen Sie `false`, um nur Top-Level-Anweisungen zu treffen.
</ParamField>

Unbekannte Felder irgendwo im Filter oder in den Optionen werden mit `-32602` abgelehnt, anstatt stillschweigend ignoriert zu werden, sodass Tippfehler laut fehlschlagen, anstatt nichts zu treffen.

#### Optionen

Der zweite Parameter ist optional.

<ParamField body="commitment" type="string" default="confirmed">
  Nur `confirmed` wird unterstützt.
</ParamField>

<ParamField body="details" type="string" default="full">
  Was jede Benachrichtigung enthält. `full`: die gesamte Transaktion, jede Anweisung, plus `matchedIndexes`, die auf die Filtertreffer zeigt. `matched`: nur die übereinstimmenden Anweisungen, keine Indexliste. `raw`: nur übereinstimmende Anweisungen, jede reduziert auf ihre Position, `programId`, und Base58 `data` Blob, ohne dekodierte Felder und ohne `accountKeys` Array. Verwenden Sie `matched`, wenn die Bandbreite wichtiger ist als der Kontext (vollständige Nutzlasten sind im Durchschnitt etwa dreimal so groß), und `raw`, wenn Sie Anweisungsdaten selbst dekodieren und nur die Bytes benötigen.
</ParamField>

Ein Projekt kann bis zu **100 gleichzeitige Verbindungen** halten, die auf alle seine API-Schlüssel verteilt sind.

### Benachrichtigungen

Eine Benachrichtigung pro passender Transaktion pro Abonnement. Mit dem Standard `details: "full"`:

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "method": "parsedTransactionNotification",
  "params": {
    "subscription": 23,
    "result": {
      "context": { "slot": 430172053 },
      "value": {
        "transaction": {
          "signature": "3riSYL4HTRxgQjLayt6L2JPaDR3oaEQg1H4v3fnjUxNU...",
          "slot": 430172053,
          "blockTime": null,
          "feePayer": "6jduWNCTQzG91JGBchfGGxd55Vi5FxJCCJEV18RkXzJX",
          "fee": 5000,
          "accountKeys": ["6jduWNCT...", "..."],
          "status": "ok",
          "error": null,
          "summary": {
            "type": "swap",
            "description": "6jduWNCTQzG91JGBchfGGxd55Vi5FxJCCJEV18RkXzJX swapped 0.001 SOL for 0.183985 EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v via Jupiter",
            "parsedData": {
              "type": "swap",
              "protocol": "jupiter",
              "kind": "swap",
              "in_amount": "1000000",
              "actual_out_amount": "183985",
              "input_mint": "So11111111111111111111111111111111111111112",
              "output_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
            }
          },
          "nativeTransfers": [
            { "fromUserAccount": "6jduWNCT...", "toUserAccount": "DfXygSm4...", "amount": 1000000 }
          ],
          "tokenTransfers": [
            {
              "fromUserAccount": "6jduWNCT...",
              "toUserAccount": "AeUfFU6L...",
              "fromTokenAccount": "HLaEoW1s...",
              "toTokenAccount": "G13P9kSY...",
              "rawTokenAmount": 183985,
              "decimals": 6,
              "tokenStandard": "Fungible",
              "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
            }
          ]
        },
        "instructions": [
          {
            "topIndex": 4,
            "innerIndex": null,
            "stackHeight": 1,
            "programId": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
            "programName": "jupiter",
            "instructionName": "route",
            "summary": {
              "type": "swap",
              "description": "6jduWNCTQzG91JGBchfGGxd55Vi5FxJCCJEV18RkXzJX swapped 0.001 SOL for 0.183985 EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v via Jupiter",
              "parsedData": {
                "type": "swap",
                "protocol": "jupiter",
                "kind": "swap",
                "in_amount": "1000000",
                "actual_out_amount": "183985",
                "input_mint": "So11111111111111111111111111111111111111112",
                "output_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
              }
            },
            "decoded": {
              "args": { "in_amount": "1000000", "slippage_bps": 50 },
              "accounts": [
                { "name": "user_transfer_authority", "pubkey": "9xQe...", "isSigner": true, "isWritable": false }
              ]
            }
          }
        ],
        "matchedIndexes": [8, 13]
      }
    }
  }
}
```

Lesen:

* **`transaction`** ist der vollständige Kontext. `fee` ist in Lamports. `accountKeys` ist die vollständige Schlüsselliste, einschließlich der von Adresssuchtabellen geladenen Schlüssel, in der Reihenfolge, in der die Kette sie meldet. `feePayer` ist immer `accountKeys[0]`. `error` enthält den Transaktionsfehler als strukturiertes JSON, zum Beispiel `{"InstructionError": [2, {"Custom": 6001}]}`, wenn `status` `"error"` ist.
* **`summary`** hat überall die gleiche Form: ein `type` (wie `swap` oder `transfer`), ein lesbarer `description` und eine strukturierte `parsedData` Nutzlast, wenn der Parser die Aktion erkennt — für einen Swap: das Protokoll, Mengen und Mints. `transaction.summary` kennzeichnet die Hauptaktion der Transaktion; jede erkannte Anweisung enthält ihre eigene `summary` mit der gleichen Form. Um jeden Swap in einer Transaktion zu sammeln, iterieren Sie `instructions` und lesen Sie `summary.parsedData`, wo `summary.type` `"swap"` ist.
* **`nativeTransfers`** und **`tokenTransfers`** listen die SOL- und Token-Bewegungen auf, die der Parser aus der gesamten Transaktion extrahiert hat, in derselben Form, die die Parsed Events API zurückgibt, damit Stream- und API-Konsumenten denselben Verarbeitungscode teilen können. Beide sind immer vorhanden, möglicherweise leer.
* **`instructions`** ist jede Anweisung der Transaktion in Ausführungsreihenfolge: jede oberste Anweisung, gefolgt von ihren inneren Anweisungen. Jeder Eintrag enthält seine eigene Position: `topIndex` gibt an, zu welcher obersten Anweisung er gehört (beginnend bei 0), `innerIndex` ist seine Position unter den inneren Aufrufen dieser Anweisung (`null` bedeutet, dass es die oberste Anweisung selbst ist) und `stackHeight` ist die Aufruftiefe (1 für oberstes Niveau). Verwenden Sie diese, nicht die Array-Position.
* **`matchedIndexes`** sind Indizes in `instructions`, die Ihnen sagen, welche Ihre Filter tatsächlich getroffen haben. Der Rest ist für den Kontext da. Mit `details: "matched"` enthält das Array nur die Treffer und `matchedIndexes` ist abwesend.
* **`decoded` Namen sind snake\_case** (`in_amount`, `user_transfer_authority`), wie sie im IDL des Programms veröffentlicht sind. Ganzzahl-Argumente sind häufig Zeichenfolgen (`"1000000"`), da u64-Werte nicht in JavaScript-Zahlen passen.
* **`blockTime`** ist derzeit immer `null`. Nicht darauf verlassen.
* Erwarten Sie eine **Mischung aus dekodierten und undekodierten Anweisungen** innerhalb einer Transaktion: ein vollständig dekodierter Swap kann neben einem nicht erkannten Memo stehen. Verzweigen Sie nach `decoded`: Wenn es `null` ist, trägt die Anweisung `rawData` (Base58-Bytes) und `rawAccounts` (einfache Pubkey-Liste) stattdessen, so dass Sie immer etwas zum Arbeiten haben.

Mit `details: "raw"` schrumpft das `value` auf Transaktionsmeta und Blobs. `accountKeys`, `nativeTransfers`, `tokenTransfers`, `matchedIndexes` und alle dekodierten Felder sind weg (die Transaktion `summary` ist noch enthalten); jede übereinstimmende Anweisung entspricht ihrer Position, ihrem Programm und ihren `data` Bytes in Base58, genau so, wie sie auf der Kette erscheinen (auch für Anweisungen vorhanden, die der Katalog hätte dekodieren können):

```json theme={"system"}
"value": {
  "transaction": {
    "signature": "3riSYL4HTRxgQjLayt6L2JPaDR3oaEQg1H4v3fnjUxNU...",
    "slot": 430172053,
    "blockTime": null,
    "feePayer": "6jduWNCTQzG91JGBchfGGxd55Vi5FxJCCJEV18RkXzJX",
    "fee": 5000,
    "status": "ok",
    "error": null,
    "summary": {
      "type": "swap",
      "description": "6jduWNCTQzG91JGBchfGGxd55Vi5FxJCCJEV18RkXzJX swapped 0.001 SOL for 0.183985 EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v via Jupiter",
      "parsedData": {
        "type": "swap",
        "protocol": "jupiter",
        "kind": "swap",
        "in_amount": "1000000",
        "actual_out_amount": "183985",
        "input_mint": "So11111111111111111111111111111111111111112",
        "output_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
      }
    }
  },
  "instructions": [
    { "topIndex": 4, "innerIndex": null, "stackHeight": 1, "programId": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4", "data": "3Bxs4h24hBtQy9rw" }
  ]
}
```

### Abmelden

```json theme={"system"}
{ "jsonrpc": "2.0", "id": 2, "method": "parsedTransactionUnsubscribe", "params": [23] }
```

Gibt `true` zurück, wenn das Abonnement existierte und Ihnen gehörte. Benachrichtigungen stoppen sofort. Das Schließen der Verbindung entfernt alle ihre Abonnements.

### Entdeckung

Der häufigste Fehler bei dieser Art von API ist ein Filter, der gültig ist, aber nichts trifft, normalerweise ein geschätzter Anweisungs- oder Rollename. `describeProgram` verhindert dies, indem es die genauen Namen zurückgibt, mit denen der Matcher vergleicht:

```json Request theme={"system"}
{ "jsonrpc": "2.0", "id": 1, "method": "describeProgram", "params": [{ "program": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" }] }
```

```json Response theme={"system"}
{
  "jsonrpc": "2.0", "id": 1,
  "result": {
    "id": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
    "name": "jupiter",
    "instructions": ["route", "shared_accounts_route", "exact_out_route"],
    "events": ["SwapEvent"],
    "roles": ["user_transfer_authority", "destination_token_account"]
  }
}
```

Sie können eine Programmadresse oder einen Katalognamen übergeben, aber **bevorzugen Sie die Adresse**: Namen können zwischen Programmversionen mehrdeutig sein (mehr als ein Katalogeintrag trägt den Namen `jupiter`, und eine Namenssuche kann zum älteren führen). Wenn Sie nach Namen nachschlagen, überprüfen Sie, ob `result.id` das Programm ist, das Sie abonnieren möchten.

Empfohlener Ablauf: `describeProgram`, um die genauen Anweisungs- und Rollennamen zu erhalten, den Filter mit diesen Namen erstellen und dann abonnieren. Der Leitfaden [Jupiter Swaps verfolgen](/docs/de/parsed-streams/guides/track-jupiter-swaps) führt Sie von Anfang bis Ende durch diesen Prozess.

### Grenzen

| Grenze                                 | Wert                                                          |
| -------------------------------------- | ------------------------------------------------------------- |
| Gleichzeitige Verbindungen pro Projekt | 100                                                           |
| Abonnements pro Verbindung             | 25                                                            |
| Client-Nachrichten                     | 10 pro Sekunde, Stoß von 20                                   |
| Größe der Client-Nachricht             | 64 KiB                                                        |
| `programs` pro Filter                  | 10                                                            |
| `instructionNames` pro Filter          | 50, jede bis zu 64 Zeichen                                    |
| `accounts.include` pro Filter          | 100                                                           |
| `accounts.roles` pro Filter            | 20, jeder Name bis zu 64 Zeichen                              |
| Ausgangspuffer pro Verbindung          | 2048 Benachrichtigungen, dann wird die Verbindung geschlossen |

### Fehler

Fehler folgen JSON-RPC 2.0: `{ "error": { "code": <int>, "message": "<text>" }, "id": <id> }`. Nachrichten geben genau an, was falsch war und wo.

| Code     | Bedeutung                                                                                                 |
| -------- | --------------------------------------------------------------------------------------------------------- |
| `-32700` | Parserfehler (ungültiges JSON)                                                                            |
| `-32600` | Ungültige Anfrage                                                                                         |
| `-32601` | Methode nicht gefunden                                                                                    |
| `-32602` | Ungültige Parameter: ungültiger Pubkey, unbekanntes Feld, nicht unterstützter Commitment- oder Detailwert |
| `-32000` | Filterlimit überschritten                                                                                 |
| `-32001` | Server nicht bereit; mit Backoff erneut versuchen                                                         |
| `-32002` | Rate eingeschränkt (10 Nachrichten pro Sekunde)                                                           |
| `-32006` | Zu viele Abonnements (25 pro Verbindung)                                                                  |

Verbindungen können auch mit einem WebSocket-Schließcode geschlossen werden — siehe [Reconnects handhaben](/docs/de/parsed-streams/guides/handling-reconnects) für die Bedeutung jedes Codes und wie Sie sich erholen können.

## Client-Beispiele

<CodeGroup>
  ```bash wscat theme={"system"}
  wscat -c "wss://fs-beta.helius-rpc.com/?api-key=<API_KEY>"
  # then send:
  {"jsonrpc":"2.0","id":1,"method":"parsedTransactionSubscribe","params":[{"programs":["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"]}]}
  ```

  ```typescript TypeScript theme={"system"}
  import WebSocket from "ws";

  const ws = new WebSocket("wss://fs-beta.helius-rpc.com/?api-key=<API_KEY>");

  ws.on("open", () => {
    ws.send(JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "parsedTransactionSubscribe",
      params: [{ programs: ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"] }],
    }));
  });

  ws.on("message", (data) => {
    const msg = JSON.parse(data.toString());
    if (msg.method === "parsedTransactionNotification") {
      const { transaction, instructions, matchedIndexes } = msg.params.result.value;
      for (const i of matchedIndexes ?? instructions.keys()) {
        const ix = instructions[i];
        console.log(transaction.signature, ix.programName, ix.instructionName, ix.decoded?.args);
      }
    }
  });
  ```

  ```python Python theme={"system"}
  import asyncio, json, websockets

  URL = "wss://fs-beta.helius-rpc.com/?api-key=<API_KEY>"

  async def main():
      async with websockets.connect(URL) as ws:
          await ws.send(json.dumps({
              "jsonrpc": "2.0", "id": 1, "method": "parsedTransactionSubscribe",
              "params": [{"programs": ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"]}],
          }))
          async for raw in ws:
              msg = json.loads(raw)
              if msg.get("method") == "parsedTransactionNotification":
                  value = msg["params"]["result"]["value"]
                  for i in value.get("matchedIndexes") or range(len(value["instructions"])):
                      ix = value["instructions"][i]
                      print(ix.get("programName"), ix.get("instructionName"), (ix.get("decoded") or {}).get("args"))

  asyncio.run(main())
  ```
</CodeGroup>
