ESP32 send data to another ESP32 without establishing a wifi connection
Finally I found a way how to do it. If you use the mac address FF:FF:FF:FF:FF:FF that works as a broadcast address. This is the working code on how to send a message from the master to another esp32 without knowing its mac address. Later the slave can reply with its real mac address:
Code for master (tx)
#include &lt;Arduino.h&gt;
#include &lt;esp_now.h&gt;
#include &quot;WiFi.h&quot;

uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? &quot;Delivery Success 1&quot; : &quot;Delivery Fail 1&quot;);
  if (status ==0){
    Serial.println(&quot;Delivery Success 2&quot;);
  }
  else{
    Serial.println(&quot;Delivery fail 2&quot;);
  }

  Serial.println();
}       

void setup()
{

  Serial.begin(115200);

  Serial.println(&quot;Starting...\n&quot;);

  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  Serial.println(WiFi.macAddress());

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println(&quot;Error initializing ESP-NOW&quot;);
    for(;;) {      delay(1);  } // do not initialize wait forever
  }

  Serial.println(&quot;initialized ESP-NOW&quot;);


  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);

   // Register peer
  esp_now_peer_info_t peerInfo;
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;

   // Add peer        
  if (esp_now_add_peer(&amp;peerInfo) != ESP_OK){
    Serial.println(&quot;Failed to add peer&quot;);
    for(;;) {      delay(1);  } // do not initialize wait forever
  }            
}

int dataToSend = 1;
void loop()
{
    dataToSend++;

    // Send message via ESP-NOW (size of an int is 4 bytes on ESP32)
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &amp;dataToSend, 4);
   
    if (result == ESP_OK) {
      Serial.println(&quot;Sent with success&quot;);
    }
    else {
      Serial.println(&quot;Error sending the data&quot;);
    }

    //Serial.println(WiFi.macAddress());    
    delay(1000);
}

Code for slave (Rx)
#include &lt;Arduino.h&gt;
#include &lt;esp_now.h&gt;
#include &quot;WiFi.h&quot;


// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) 
{
  int dataReceived;
  memcpy(&amp;dataReceived, incomingData, sizeof(dataReceived));

  Serial.print(&quot;Data Received: &quot;);
  Serial.println(dataReceived);

  Serial.println();    
}

void setup()
{

  Serial.begin(115200);
  delay(100);

  Serial.println(&quot;Starting...\n&quot;);

  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // print our mac address
  Serial.println(WiFi.macAddress());

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println(&quot;Error initializing ESP-NOW&quot;);
    for(;;) {      delay(1);  } // do not initialize wait forever
  }
  
  Serial.println(&quot;initialized ESP-NOW&quot;);



  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(OnDataRecv);

}

void loop()
{
}

You can also reply back on the receiver code if you want. It will be the same code.