> ## 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.

# parsedTransactionSubscribe

> Suscríbete a transacciones decodificadas de Solana que coincidan con un filtro por programa, cuenta y nombre de instrucción. Recibe transacciones completas con argumentos y cuentas con nombre.

Inicia una suscripción. Cada transacción confirmada que coincida con tu filtro llega como `parsedTransactionNotification`, ya decodificada: cada instrucción con argumentos y cuentas con nombre, además de la comisión, la lista completa de claves de cuenta, un `summary` de nivel de transacción y las transferencias de SOL y tokens.

## Endpoints

Parsed Streams está en beta abierta y se encuentra disponible en los planes de pago. Obtén tu endpoint de conexión en el [panel de Helius](https://dashboard.helius.dev):

* `wss://<ENDPOINT>/?api-key=<API_KEY>`

## Autorizaciones

<ParamField query="api-key" type="string" required>
  Tu clave de API de Helius, enviada como parámetro de consulta `api-key` o como encabezado `x-api-key`. Si la clave falta o no es válida, la solicitud se rechaza con HTTP 401.
</ParamField>

## Cuerpo

<ParamField body="params" type="array" required>
  <Expandable title="Filter" defaultOpen>
    Se requiere al menos uno de `programs` o `accounts.include`. Los campos que configures se combinan con **AND**: una instrucción debe cumplirlos todos para coincidir.

    <ParamField body="programs" type="string[]">
      IDs de programa que deben coincidir (direcciones base58, no nombres). Una instrucción coincide si su programa está en esta lista. OR dentro de la lista.
    </ParamField>

    <ParamField body="instructionNames" type="string[]">
      Nombres de instrucciones decodificadas, como `route`. Primero se busca una coincidencia exacta y luego se usa una alternativa que no distingue entre mayúsculas y minúsculas ni separadores, por lo que `sharedAccountsRoute` también coincide con el nombre en el formato de transmisión `shared_accounts_route`. OR dentro de la lista. Solo pueden coincidir las instrucciones cuyo nombre pudo identificar el catálogo, así que obtén los nombres de [describeProgram](/docs/es/api-reference/parsed-streams/describeprogram).
    </ParamField>

    <ParamField body="accounts.include" type="string[]">
      Direcciones de cuenta. Una instrucción coincide si alguna de estas aparece en su lista de cuentas. OR dentro de la lista. Funciona con todas las instrucciones, estén decodificadas o no. El ID del programa no cuenta aquí como una cuenta.
    </ParamField>

    <ParamField body="accounts.roles" type="object">
      Un mapa del nombre del rol de la cuenta decodificada a la dirección, como `{ "user_transfer_authority": "<pubkey>" }`. Cada entrada debe cumplirse (AND entre entradas) y la instrucción debe estar decodificada para que esto se aplique. Los nombres de los roles deben coincidir **exactamente**, sin ignorar mayúsculas y minúsculas, así que cópialos de [describeProgram](/docs/es/api-reference/parsed-streams/describeprogram) en lugar de adivinarlos.
    </ParamField>

    <ParamField body="includeFailed" type="boolean" default="false">
      Incluye instrucciones de transacciones fallidas.
    </ParamField>

    <ParamField body="includeCpi" type="boolean" default="true">
      Las instrucciones internas (CPI) pueden coincidir. Establece `false` para que solo coincidan las instrucciones de nivel superior.
    </ParamField>
  </Expandable>

  <Expandable title="Options">
    El segundo parámetro es opcional.

    <ParamField body="commitment" type="string" default="confirmed">
      Solo se admite `confirmed`.
    </ParamField>

    <ParamField body="details" type="string" default="full">
      Lo que contiene cada notificación. `full`: la transacción completa, cada instrucción y `matchedIndexes`, que apunta a las coincidencias del filtro. `matched`: solo las instrucciones que coincidieron, sin lista de índices. `raw`: solo las instrucciones coincidentes, cada una reducida a su posición, `programId` y un bloque `data` en base58, sin campos decodificados ni el arreglo `accountKeys`. Usa `matched` cuando el ancho de banda importe más que el contexto (en promedio, las cargas útiles completas tienen aproximadamente tres veces el tamaño) e `raw` cuando decodifiques por tu cuenta los datos de las instrucciones y solo necesites los bytes.
    </ParamField>
  </Expandable>
</ParamField>

Los campos desconocidos en cualquier parte del filtro o de las opciones se rechazan con `-32602` en lugar de ignorarse silenciosamente. Así, los errores tipográficos generan un error explícito en vez de no producir ninguna coincidencia.

## Respuesta

<ResponseField name="result" type="integer">
  ID de la suscripción (necesario para cancelar la suscripción)
</ResponseField>

<RequestExample>
  ```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" }
    ]
  }
  ```

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

  const ws = new WebSocket("wss://<ENDPOINT>/?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://<ENDPOINT>/?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())
  ```
</RequestExample>

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

  ```json Notification 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]
        }
      }
    }
  }
  ```
</ResponseExample>

## Notificaciones

Una notificación por cada transacción coincidente y por suscripción. Dentro de `params.result.value`:

* **`transaction`** — el contexto completo: firma, slot, comisión (lamports), la lista completa de `accountKeys`, `status`/`error`, un `summary` de nivel de transacción y los elementos `nativeTransfers` e `tokenTransfers` extraídos.
* **`instructions`** — todas las instrucciones en orden de ejecución, ubicadas mediante `topIndex`, `innerIndex` e `stackHeight`. Las instrucciones decodificadas contienen `decoded.args` e `decoded.accounts` con nombre (snake\_case, con valores u64 como cadenas); las instrucciones sin decodificar contienen `rawData` e `rawAccounts` en su lugar.
* **`matchedIndexes`** — índices de `instructions` que indican cuáles coincidieron realmente con tu filtro. Con `details: "matched"`, el arreglo solo contiene las coincidencias e `matchedIndexes` no está presente; con `details: "raw"`, cada instrucción coincidente se reduce a su posición, `programId` y un bloque `data` en base58.

Para consultar cada campo de la carga útil de la notificación, revisa la [referencia del protocolo en la guía de inicio rápido](/docs/es/parsed-streams/quickstart#notificaciones).

## Administración de suscripciones

El `result` de la respuesta de suscripción es el mismo número que aparece en `params.subscription` en cada notificación de esa suscripción. Guárdalo: lo necesitas para [cancelar la suscripción](/docs/es/api-reference/parsed-streams/parsedtransactionunsubscribe).

Un proyecto puede mantener hasta **100 conexiones simultáneas**, compartidas entre todas sus claves de API, con hasta **25 suscripciones por conexión**. Consulta la [descripción general](/docs/es/api-reference/parsed-streams/overview#límites) para conocer todos los límites.
