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

# Endpoints

> Implement the two required routes in your integration server to receive user data requests and real-time notifications from Wavy Node.

Your integration is a **single server** (one URL) that exposes **two routes**. When you configure the integration URL in the Wavy Node dashboard (e.g., `https://your-server.com`), Wavy Node appends the route paths automatically:

* `GET {integrationUrl}/users/{foreign_user_id}`
* `POST {integrationUrl}/webhook`

<Warning>
  You only need **one server** and **one integration URL**. Do not create separate servers or URLs for each route. Wavy Node sends requests to both routes on the same base URL.
</Warning>

## `GET /users/{foreign_user_id}`

Wavy Node calls this endpoint to retrieve information about a specific user. The `{foreign_user_id}` parameter is the user's ID in your system (the same ID you provided when registering the wallet address).

<Note>
  The `foreign_user_id` is the identifier you send when creating an address via `POST /projects/{projectId}/addresses`. This is how Wavy Node links wallets to users in your system.
</Note>

Your endpoint should return a JSON object with the following structure:

```json theme={null}
{
  "givenName": "Maria Guadalupe",
  "maternalSurname": "Sánchez",
  "paternalSurname": "Rodríguez",
  "birthdate": "1992-05-15",
  "nationality": "MX",
  "phoneNumber": {
    "countryCode": "+52",
    "phoneNumber": 5512345678
  },
  "email": "maria.guadalupe@example.com",
  "address": {
    "country": "MX",
    "region": "CDMX",
    "city": "Ciudad de México",
    "street": "Avenida Insurgentes Sur",
    "colonia": "Condesa",
    "exteriorNumber": "123",
    "interiorNumber": "4B",
    "postalCode": "06100"
  },
  "mexico": {
    "rfc": "ROSM920515XXX",
    "curp": "ROSM920515MDFRXXXX",
    "actividadEconomica": 612012,
    "cuentaRelacionada": "1234567890",
    "monedaCuentaRelacionada": 1,
    "documentoIdentificacion": {
      "tipoIdentificacion": 1,
      "numeroIdentificacion": "IDMEX12345678"
    }
  }
}
```

<Accordion title="Response fields">
  | Field                     | Type   | Description                                                |
  | ------------------------- | ------ | ---------------------------------------------------------- |
  | `givenName`               | string | The individual's given name(s)                             |
  | `maternalSurname`         | string | Maternal surname                                           |
  | `paternalSurname`         | string | Paternal surname                                           |
  | `birthdate`               | string | Date of birth in `YYYY-MM-DD` format (ISO 8601)            |
  | `nationality`             | string | ISO 3166-1 alpha-2 country code                            |
  | `phoneNumber.countryCode` | string | Phone country code                                         |
  | `phoneNumber.phoneNumber` | number | Phone number                                               |
  | `email`                   | string | Email address                                              |
  | `address`                 | object | Physical address                                           |
  | `mexico`                  | object | Fields required for Mexican legislation reports (optional) |
</Accordion>

<Note>
  The `mexico` object is only needed if you have Mexican compliance enabled in your dashboard.
</Note>

### Person types for Mexican reports

When Mexican legislation is active, the `mexico` data feeds the AVI report. A report supports three mutually exclusive person types, and exactly one applies per user.

<Tabs>
  <Tab title="Persona física">
    An individual account holder. At least one of `rfc`, `curp`, or `birthdate` is required.

    ```json theme={null}
    {
      "givenName": "Maria Guadalupe",
      "paternalSurname": "García",
      "maternalSurname": "López",
      "birthdate": "1990-05-15",
      "nationality": "MX",
      "mexico": {
        "rfc": "GALM900515XXX",
        "curp": "GALM900515MDFRPN09",
        "actividadEconomica": 8140001,
        "cuentaRelacionada": "012180001234567890",
        "monedaCuentaRelacionada": 1,
        "documentoIdentificacion": {
          "tipoIdentificacion": 1,
          "numeroIdentificacion": "INE123456789"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Persona moral">
    A legal entity. At least one of `rfc` or `fechaConstitucion` is required, and a legal representative (`representanteApoderado`) is mandatory.

    ```json theme={null}
    {
      "tipoPersona": "moral",
      "denominacionRazon": "Empresa Ejemplo SA de CV",
      "fechaConstitucion": "2015-03-20",
      "nationality": "MX",
      "representanteApoderado": {
        "givenName": "Juan Carlos",
        "paternalSurname": "Martínez",
        "maternalSurname": "Ruiz",
        "birthdate": "1985-08-10",
        "rfc": "MARJ850810XXX",
        "curp": "MARJ850810HDFRRL09",
        "documentoIdentificacion": {
          "tipoIdentificacion": 1,
          "numeroIdentificacion": "INE987654321"
        }
      },
      "mexico": {
        "rfc": "EEJ150320XXX",
        "giroMercantil": 5612001,
        "actividadEconomica": 5612001,
        "cuentaRelacionada": "014320001234567890",
        "monedaCuentaRelacionada": 1,
        "documentoIdentificacion": {
          "tipoIdentificacion": 4,
          "numeroIdentificacion": "ACTA-CONST-2015"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Fideicomiso">
    A trust. At least one of `rfc` or `identificadorFideicomiso` is required, and a fiduciary delegate (`delegadoFiduciario`) is mandatory.

    ```json theme={null}
    {
      "tipoPersona": "fideicomiso",
      "denominacionRazon": "Fiduciario Ejemplo SA",
      "nationality": "MX",
      "delegadoFiduciario": {
        "givenName": "Ana María",
        "paternalSurname": "Torres",
        "maternalSurname": "Vega",
        "birthdate": "1980-02-25",
        "rfc": "TOVA800225XXX",
        "curp": "TOVA800225MDFRRN09",
        "documentoIdentificacion": {
          "tipoIdentificacion": 1,
          "numeroIdentificacion": "INE555444333"
        }
      },
      "mexico": {
        "rfc": "FEJ800101XXX",
        "identificadorFideicomiso": "FID-2020-00123",
        "cuentaRelacionada": "012180009876543210",
        "monedaCuentaRelacionada": 1,
        "documentoIdentificacion": {
          "tipoIdentificacion": 4,
          "numeroIdentificacion": "CONTRATO-FID-2020"
        }
      }
    }
    ```
  </Tab>
</Tabs>

<Note>
  Codes such as `tipoIdentificacion` (1=INE, 2=Passport, 4=Incorporation deed), `actividadEconomica`, and `giroMercantil` follow the SAT catalogs, published at [sppld.sat.gob.mx](https://sppld.sat.gob.mx/pld/interiores/activos.html).
</Note>

## `POST /webhook`

Wavy Node sends real-time notifications to this endpoint. The request body contains:

| Field  | Type             | Description                               |
| ------ | ---------------- | ----------------------------------------- |
| `type` | string           | `notification` or `error`                 |
| `data` | object or string | The notification payload or error message |

### Notification payload

When `type` is `notification`, the `data` object contains transaction and compliance details:

```json theme={null}
{
    "type": "notification",
    "data": {
        "id": 1,
        "projectId": 1,
        "chainId": 42161,
        "address": {
            "id": 543,
            "userId": "user-in-your-db-123",
            "address": "0xyour-address-involved",
            "description": "Your address' description"
        },
        "txHash": "some-tx-hash",
        "timestamp": "2025-08-20T05:10:57.228Z",
        "amount": {
            "value": 1000000000000000000,
            "usd": 3000
        },
        "token": {
            "name": "Ethereum",
            "symbol": "ETH",
            "decimals": 18,
            "address": null
        },
        "inflictedLaws": [
            {
                "name": "The name of the law inflicted",
                "description": "Description of the law",
                "source": "Source of the law",
                "risk": "warn",
                "country": "mexico",
                "countryCode": "MX"
            }
        ]
    }
}
```

<Accordion title="Notification data fields">
  | Field                         | Type   | Description                                                                              |
  | ----------------------------- | ------ | ---------------------------------------------------------------------------------------- |
  | `id`                          | number | Notification ID                                                                          |
  | `projectId`                   | number | Project ID                                                                               |
  | `chainId`                     | number | Chain ID where the transaction occurred                                                  |
  | `address.id`                  | number | Address ID                                                                               |
  | `address.userId`              | string | User ID in your system (the `foreign_user_id` you provided when registering the address) |
  | `address.address`             | string | Wallet address                                                                           |
  | `address.description`         | string | Address description                                                                      |
  | `txHash`                      | string | Transaction hash                                                                         |
  | `timestamp`                   | string | Transaction timestamp (ISO 8601)                                                         |
  | `amount.value`                | number | Amount in the token's smallest unit                                                      |
  | `amount.usd`                  | number | Amount in USD                                                                            |
  | `token.name`                  | string | Token name                                                                               |
  | `token.symbol`                | string | Token symbol                                                                             |
  | `token.decimals`              | number | Token decimals                                                                           |
  | `token.address`               | string | Token contract address (`null` for native tokens)                                        |
  | `inflictedLaws`               | array  | Laws inflicted by the transaction                                                        |
  | `inflictedLaws[].name`        | string | Law name                                                                                 |
  | `inflictedLaws[].description` | string | Law description                                                                          |
  | `inflictedLaws[].source`      | string | Law source                                                                               |
  | `inflictedLaws[].risk`        | string | `warn` or `illegal`                                                                      |
  | `inflictedLaws[].country`     | string | Country name                                                                             |
  | `inflictedLaws[].countryCode` | string | ISO country code                                                                         |
</Accordion>

### Error payload

When `type` is `error`, the `data` field is a string containing the error message.
