Bugged devices after registering using the API

Hello, I’ve recently registered about 100 devices using the TTN v3 API. Everything went fine and all the requests came back with success codes, but when I open the devices in TTN Console, none of them have the App Key field or session information and when I open the device network info the dashboard crashes. This is the script that I’ve used to register the devices. Are there any mistakes?

PS: The device name is always a string consisting out of 8 alphanumeric characters, all URL safe. Also, why isn’t there just a single endpoint?

const ttnHeaders = {
  "Content-Type": "application/json",
  Accept: "application/json",
  Authorization: `Bearer ${process.env.TTN_KEY}`,
};

export async function createTTNDevice(deviceName: string) {
  const app_eui = crypto.randomBytes(8).toString("hex").toUpperCase(); // Also called join_eui
  const dev_eui = crypto.randomBytes(8).toString("hex").toUpperCase();
  const app_key = crypto.randomBytes(16).toString("hex").toUpperCase();

  const ids = {
    join_eui: app_eui,
    dev_eui: dev_eui,
    device_id: deviceName.toLowerCase(),
    application_ids: { application_id: "foo-network" },
  };

  const mainServerResponse = await fetch("https://eu1.cloud.thethings.network/api/v3/applications/foo-network/devices", {
    method: "POST",
    headers: ttnHeaders,
    body: JSON.stringify({
      end_device: {
        ids,
        name: deviceName,
        network_server_address: "eu1.cloud.thethings.network",
        application_server_address: "eu1.cloud.thethings.network",
        join_server_address: "eu1.cloud.thethings.network",
      },
    }),
  });

  const nsResponse = await fetch(
    `https://eu1.cloud.thethings.network/api/v3/ns/applications/foo-network/devices/${deviceName.toLowerCase()}`,
    {
      method: "PUT",
      headers: ttnHeaders,
      body: JSON.stringify({
        end_device: {
          frequency_plan_id: "EU_863_870",
          lorawan_version: "MAC_V1_0_3",
          lorawan_phy_version: "PHY_V1_0_3_REV_A",
          supports_join: true,
          multicast: false,
          supports_class_b: false,
          supports_class_c: false,
          mac_settings: { rx2_data_rate_index: 0, rx2_frequency: "869525000" },
          ids,
        },
      }),
    }
  );

  const asResponse = await fetch(
    `https://eu1.cloud.thethings.network/api/v3/as/applications/foo-network/devices/${deviceName.toLowerCase()}`,
    {
      method: "PUT",
      headers: ttnHeaders,
      body: JSON.stringify({
        end_device: {
          ids,
        },
      }),
    }
  );

  const jsResponse = await fetch(
    `https://eu1.cloud.thethings.network/api/v3/js/applications/foo-network/devices/${deviceName.toLowerCase()}`,
    {
      method: "PUT",
      headers: ttnHeaders,
      body: JSON.stringify({
        end_device: {
          ids,
          network_server_address: "eu1.cloud.thethings.network",
          application_server_address: "eu1.cloud.thethings.network",
          root_keys: { app_key: { key: app_key } },
        },
      }),
    }
  );

  return { app_eui, dev_eui, app_key };
}

You know you can’t just invent your own random EUIs? There are reserved ranges people paid money to obtain…

Also 100 devices sounds like commercial use. For commercial deployments please contact TTI so they get a fair share of the money generated.

Paging @rish1

1 Like

Yes, it looks like your code is registering in the wrong order as recommended in the docs.