# Remote.It Overview

Remote.It makes secure remote connections between devices without open ports or port forwarding, crossing NATs and firewalls over SSH, VNC, RDP, HTTP/S and more.

remote.it allows you to make secure remote connections between two computers. Some of the benefits include:

* Crossing multiple NATs/firewalls
* Using a single TCP port
* **portforwardless:** without requiring port forwarding in the router, significantly reducing your network's vulnerability
* Many TCP/UDP-based protocols and applications are supported
  * SSH/SCP - [network console and file transfer](https://support.remote.it/hc/en-us/sections/4412840105997-Remote-Console-and-File-Transfer)
  * VNC, RDP, Mac Screen Sharing - [remotely access the Graphical User Interface (GUI)](https://support.remote.it/hc/en-us/sections/4423781834253-Remote-desktop-control)
  * http/https (web servers and applications such as node-red)
  * SMB (Samba) file sharing
  * other protocols supported under the "custom TCP" option, e.g. MQTT

## The core remote.it components

### remoteit Service Agent

remoteit is the component that is installed on the devices which will be connected. In the case of a peer-to-peer connection, remoteit will be installed on the connection initiating device as well. You can also interact with remoteit to run network diagnostics and troubleshoot other issues with your device.

### Services

These are the specific connections and their details that tell remoteit what two endpoints to connect.

### Installation Packages

remote.it supports installation of a desktop application, CLI, or a device package on multiple platforms and architectures.

The [**Desktop**](https://link.remote.it/support/desktop-overview) application provides a UI to interact with your devices which includes configuration, connections, and event logs. This is the easiest application for technical and non-technical users.

The [**CLI**](/software/cli/overview) provides a local command line interface to the device to which it is installed. This includes configuration, connections, status, and some debugging tools. This is useful when a UI is not needed, however you may also need to use some API requests to use some of the functions such as connections.

The [**Device Package**](/software/device-package/installation) installs the Target Service Daemon component. This is useful when a UI is not needed and a small footprint on the device is needed. For example, an embedded device with limited storage.

The iOS app allows you to initiate a connect to all your devices directly from an iPhone and iPad.

{% embed url="<https://itunes.apple.com/us/app/remote-it/id1437569166>" %}

The Android app acts as an initiator or target device

{% embed url="<https://play.google.com/store/apps/details?id=com.remoteit>" %}

### APIs

APIs are the backbone of the applications and provide ways to view and manage your remote.it account as well as your devices, connections, and event logs. Further details on the APIs can be found [here](/developer-tools/api/usage#what-is-graphql).


# Get Started

Create a Remote.It account, install the Desktop app or CLI on your target device, and make your first secure connection — no port forwarding required.

## Create a Remote.It Account

Sign up here: <https://app.remote.it>

## Quick Start

Here's what is required.

1. **Download and install the** [**Desktop**](/software/desktop/overview-and-installation) **app or use** [**https://app.remote.it**](https://app.remote.it)\
   You will be using this to setup other devices and start connections
2. **Install and configure remote.it on your target device**\
   (The device you will be connecting to)
   1. **Windows or Mac**\
      Install the [Desktop](/software/desktop) or [CLI](/software/cli)
   2. **Raspberry Pi or Linux based systems, use the command provided in the Desktop to install and configure remote.it.**\
      ![The Remote.It Desktop app showing the install command to paste on a Linux target device](/files/yG9iO8EHFE0Mr94DP8cc)
3. **Connect!**

Once configured you can then share the device or individual services to others.[ Learn more](https://link.remote.it/blog/manage-access).

Check out the [Glossary](/introduction/glossary-of-terms) for more details on these terms

{% hint style="info" %}
We are in the process of adding more to our documentation. Can't find what you are looking for? [Please contact us](http://support.remot3.it).
{% endhint %}

## What is it?

remote.it is a platform that brings the world of disconnected networks to your browser, desktop and mobile devices. Securely access devices connected to any network like they were on your own local network.

remote.it lets you connect between your devices on the internet in a secure and convenient manner. In a **connection**, the device which begins the connection is called the **initiator device** and the device which responds is the **target device**.

## Why did we make it?

Our founders expertise started in TCP/IP and it grew from there. As cloud technologies advanced, it begged the question, why hasn’t networking changed? With the cloud, connecting to devices has never been easier. So, we developed [remote.it](http://remote.it) to simplify the way people and businesses connect to devices. Our goal is increase your productivity by reducing your time to device, easing access management, and giving you the peace-of-mind of making connections with no open ports.

## How does remote.it work?

When you register a device, remote.it will maintain a minimal connection while the device is online. When the devices have access to the internet **you** also have access to the device. The service agent requires **outbound** UDP traffic on ports 5959 through 5970 to communicate with remote.it.

When you register a service on a target device you're saying that you will communicate to that device on that particular service port. When ready to access we provide a local device or proxy address and port where all traffic will be routed to the target device and port.

<figure><img src="/files/2YRHQHCCGwl6fDUYVZKD" alt="Diagram of traffic routed from a local address and port through to the target device and port"><figcaption></figcaption></figure>

There are two methods we use to provide that connection access when you're ready for it. You can use either one on the same connection.

More details can be found on our connection types [here](https://link.remote.it/documentation-desktop/linux-connections)

[Proxy Connections](/features/connection-options/peer-2-peer-and-proxy)- remote.it maintains geolocated initiators that generate unique addresses. These are great if the endpoint you're trying to access is closer to us than you. This connection type is not persistent and has a defined time to live.

<figure><img src="/files/Npo0BSmJLU1rAKiHC9UN" alt="Diagram of a proxy connection routed through a geolocated Remote.It initiator"><figcaption></figcaption></figure>

[Peer-2-Peer](/features/connection-options/peer-2-peer-and-proxy)- when you request a peer-2-peer connection the remote.it service builds a tunnel from the initiating device to the target device. This connection can only be initiated on devices that have the service agent installed. This has low latency and will maintain the connection for as long as internet connection is available to both devices.

<figure><img src="/files/KXhmjTjsLV2Z9Qd769kX" alt="Diagram of a peer-to-peer tunnel built directly between the initiator and target device"><figcaption></figcaption></figure>


# Platforms & Packages

Compare the Remote.It Device Package, CLI and Desktop app across Linux, Raspberry Pi, Mac, Windows, OpenWrt, Synology, NVIDIA Jetson and more.

## Available Packages at a glance

{% tabs %}
{% tab title="Device Package" %}
[Here](https://www.remote.it/download-list?products=device-package#Download-Results) for a detailed list of supported architectures.

Installation includes the Service Agent for inbound connections only.

* Axis
* Linux
* OpenWrt
* NVIDIA Jetson
* Raspberry Pi
* Synology
* Ubiquiti
* and more!
  {% endtab %}

{% tab title="CLI" %}
[Here](https://www.remote.it/download-list?products=cli#Download-Results) for a detailed list of supported architectures

Installation includes a CLI used to setup and initiate outbound connections and Service Agent for inbound connections.

* Linux
* Raspberry Pi
* Mac
* Windows
  {% endtab %}

{% tab title="Desktop" %}
[Here](https://www.remote.it/download-list?products=desktop#Download-Results) for a detailed list of supported architectures

Installation includes a GUI to monitor, setup and initiate services, connections and users. The CLI used to setup and initiate outbound connections and Service Agent for inbound connections.

* Linux
* Raspberry Pi
* Mac
* Windows
  {% endtab %}
  {% endtabs %}

| Platform          | remoteit Device Package |  CLI  | Desktop |
| ----------------- | :---------------------: | :---: | :-----: |
| **Axis**          |          **X**          |       |         |
| **Linux**         |          **X**          | **X** |  **X**  |
| **Mac**           |                         | **X** |  **X**  |
| **NVIDIA Jetson** |          **X**          |       |         |
| **OpenWrt**       |          **X**          |       |         |
| **Raspberry Pi**  |          **X**          | **X** |  **X**  |
| **Synology**      |          **X**          |       |         |
| **Windows**       |                         | **X** |  **X**  |
| **Ubiquiti**      |          **X**          |       |         |

## Package Components

<table data-header-hidden><thead><tr><th width="200">Packages</th><th width="150" align="center">UI</th><th width="150" align="center">CLI</th><th align="center">Agent</th></tr></thead><tbody><tr><td><strong>Packages</strong></td><td align="center"><strong>UI</strong></td><td align="center"><strong>CLI</strong></td><td align="center"><strong>Agent</strong></td></tr><tr><td><strong>Desktop Application</strong></td><td align="center"><strong>X</strong></td><td align="center"><strong>X</strong></td><td align="center"><strong>X</strong></td></tr><tr><td><strong>CLI</strong></td><td align="center"></td><td align="center"><strong>X</strong></td><td align="center"><strong>X</strong></td></tr><tr><td><strong>Device Package</strong></td><td align="center"></td><td align="center"></td><td align="center"><strong>X</strong></td></tr></tbody></table>


# Remote Access Over Starlink

Reach cameras, DVRs, NAS boxes and PCs behind a Starlink connection. Starlink uses CGNAT, so port forwarding can't work — Remote.It gets you in without it.

If you have Starlink at a cabin, farm, boat, RV or job site, you have probably already discovered that you cannot get to your cameras, DVR or computers from somewhere else. Port forwarding in your router does nothing, and support articles that tell you to "open a port" don't apply.

Remote.It solves this. This guide walks through the whole setup in plain language. No networking experience needed.

## Why port forwarding doesn't work on Starlink

Starlink puts your connection behind **CGNAT** (Carrier-Grade NAT). Cellular and most other satellite providers do the same thing.

In plain terms: your Starlink router does not get its own address on the public internet. It shares one with many other customers. So there is no address anywhere in the world that points at your network, and nothing for a forwarded port to attach to.

Remote.It doesn't need one. Instead of you reaching in from outside, the Remote.It software on your network reaches **out** and stays in touch. When you want to connect, the two ends meet in the middle. Nothing on your network is exposed to the internet, and no ports are opened in your router.

## What you'll need

* **One computer that stays powered on**, on the same network as the things you want to reach. A Windows PC, Mac, Raspberry Pi or Linux machine all work. This is the only place Remote.It gets installed.
* **A free** [**Remote.It account**](https://app.remote.it).
* **The local IP address and port** of each device you want to reach — your camera, DVR/NVR, NAS, thermostat, and so on. Step 3 below shows how to find these.

{% hint style="info" %}
**The most common point of confusion: where does the software go?**

Remote.It gets installed **once**, on one always-on computer sitting on the same network as your cameras or DVR. That computer becomes your way in.

You do **not** install it on the camera or DVR itself — those devices don't accept software. And you do **not** install it on the phone, tablet or laptop you'll be using while you're away. On that end you just sign in to the Remote.It app.
{% endhint %}

## Setting it up

{% stepper %}
{% step %}

## Create your account

Sign up at [app.remote.it](https://app.remote.it). The free plan is enough for a typical home or small site.
{% endstep %}

{% step %}

## Install Remote.It on the computer that stays on

This computer has to be on the same network as your cameras or DVR — plugged into, or on Wi-Fi from, the same Starlink router.

Install the [Desktop app](/software/desktop/overview-and-installation) on it and sign in. Then click the **+** button at the top of the sidebar. On the **What do you want to connect to?** screen, look under **This System** and click your computer's name.

<figure><img src="/files/reyQlV83TsTKQNTzp17r" alt="The Remote.It Add a device screen, with the computer you are using listed under This System"><figcaption></figcaption></figure>

Give it a name you'll recognize later — `Cabin PC`, `Shop Computer`, `Barn Pi` — and click **Add Device**.

That machine now appears in your device list, reachable from any browser or phone, anywhere in the world.

{% hint style="info" %}
Using a Raspberry Pi or another Linux box as the always-on machine? Pick it from the **Add a Device** row lower down the same screen instead, and copy the one-line install command it gives you. See [Platforms & Packages](/introduction/get-started/platforms-and-packages) for the full list of supported hardware.
{% endhint %}

If all you wanted was remote access to that one computer, you're done — skip ahead to the last step. To reach your cameras or DVR, keep going.
{% endstep %}

{% step %}

## Find the address and port of the device you want to reach

Every device on your local network has a **local IP address** — four numbers separated by dots, usually starting with `192.168.` or `10.`. Your camera or DVR also listens on a **port**, which is just a number.

You can usually find both in:

* The device's own phone app or setup screen, often under Network or Status.
* Your Starlink app or router's list of connected devices.
* The manual or the sticker on the device.

Typical values:

| What you want to reach         | Common port |
| ------------------------------ | ----------- |
| Camera or DVR web page (http)  | `80`        |
| Camera or DVR web page (https) | `443`       |
| Camera or DVR phone-app port   | `8000`      |
| NAS web page (Synology, QNAP)  | `5000`      |
| Windows remote desktop         | `3389`      |

So a DVR might be `192.168.1.64` on port `80`. Write down one line like that for each device you want to reach.

{% hint style="warning" %}
Give these devices a fixed address so they don't move. Most routers call this a DHCP reservation or static lease. Otherwise the address can change after a power cut and your connection will stop working.
{% endhint %}
{% endstep %}

{% step %}

## Add a service for each device you want to reach

This is the step that answers "where do I enter my IP and ports?"

A **service** is one thing you want to reach — a camera's web page, a DVR's app port, a NAS. You add services to the computer from the previous step, and point each one at a device on the local network. Remote.It calls this a [jump service](/features/connection-options/jump-service): your always-on computer relays the connection on to the other device. You may also see it called a "jump box."

Open your always-on computer in the Remote.It app and click the **+** next to **SERVICE** to add one. You'll get the **New service** form:

<figure><img src="/files/GNo0dhbpeJLjo22MM1Sp" alt="The Remote.It New service form, showing the service type buttons and the Service URL field where the local address goes"><figcaption></figcaption></figure>

First pick the type of thing you're reaching from the row of buttons. **HTTPS**, **HTTP**, **SSH** and **RDP** are on screen; **More** opens the rest, including **TCP** and **VNC**.

**For a web page — a camera, DVR or NAS you'd normally open in a browser**

Choose **HTTPS** or **HTTP**, whichever the device uses. You get a single **Service URL** box — the address and port go in together, exactly as you'd type them at home:

* `http://192.168.1.64` — a DVR on the standard port 80
* `http://192.168.1.64:8080` — the same DVR on a custom port
* `https://192.168.1.5:5001` — a NAS admin page

Then give it a **Service Name** you'll recognize, like `Driveway Camera`, and click **Save**.

**For anything that isn't a web page**

Choose **TCP** (most DVR/NVR phone-app ports), **VNC** or **RDP** (a remote desktop screen), or **SSH**. These give you two boxes instead of one:

* **Service Host** — the local IP address you wrote down, e.g. `192.168.1.64`
* **Service Port** — the port you wrote down, e.g. `8000`

Either way, the address you type is the whole trick. Left at `127.0.0.1` or `localhost` it means "this computer." Typing another device's local IP address is what turns the service into a jump to that device.

Repeat for each camera, recorder or box you want to reach. There's no limit on how many devices one always-on computer can reach this way, and jump services show a small arrow next to them in the service list.

{% hint style="warning" %}
Jump services carry **TCP** traffic. Most camera, DVR, NAS and remote desktop connections are TCP, so this covers nearly everything. A few video streams and VPNs use UDP instead — for those, see [UDP](/features/services/udp) and [VPN](/features/services/vpn).
{% endhint %}
{% endstep %}

{% step %}

## Connect from anywhere

From your phone, laptop or a web browser at [app.remote.it](https://app.remote.it), sign in to the same account, pick your always-on computer from the device list, pick the service you want — `Driveway Camera`, `DVR App` — and click **Connect**.

Remote.It gives you a local address and port, something like `127.0.0.1:33000`. Paste that into your browser, or type it into your camera app in place of the IP address and port you'd use at home. Everything behaves as though you were standing on that network.
{% endstep %}
{% endstepper %}

## Common questions

**Do I install Remote.It on my DVR or camera?**\
No. Those devices can't run extra software. Install it on one always-on computer on the same network, then point services at the DVR or camera.

**Do I install it on the phone or laptop I'm carrying?**\
No installation needed there. Sign in to [app.remote.it](https://app.remote.it) in a browser, or use the mobile or Desktop app if you prefer.

**What's a "jumpbox"?**\
One machine on the network relaying connections to the other devices around it — exactly what you set up when you added a service with another device's address. You'll see the word in some of our older articles.

**Do I need to change anything in my Starlink router?**\
No. No port forwarding, no firewall rules, no static public IP, no Starlink bypass mode. Remote.It only needs ordinary outbound internet access.

**Can I let someone else use my connection?**\
The connection address you're given works only on your own machine. To give someone else access, share the device or specific services with them from your account — see [Device and Service Sharing](https://support.remote.it/hc/en-us/articles/360051386511-Device-and-Service-Sharing-Overview). You control which services they can reach and can revoke it at any time.

**Will this eat my Starlink data?**\
Very little when idle — a device that just sits online uses roughly 14 MB a month, plus about 7 MB per service. Video you actually watch is the real cost. See [Use Cases](/introduction/get-started/use-cases#cellular-or-starlink-devices) for exact figures.

**My connection worked and now it doesn't.**\
Check that the always-on computer is powered up and online, and that the camera or DVR still has the same local IP address. A changed address is the usual cause.

## Still stuck?

* Ask in the [Remote.It community forum](https://forum.remote.it)
* Email <support@remote.it>


# Use Cases

How Remote.It is used in industrial automation, cloud infrastructure, and cellular or Starlink deployments — including real bandwidth consumption figures.

If you have additional questions about using Remote.It in your field of expertise send us a message at <support@remote.it> and we'll schedule a call with our engineers.

## Industry

Remote.It is being leveraged in factories and heavy industry across the globe. Check out our published case studies to see how heavy industry uses Remote.It today.

{% embed url="<https://www.remote.it/blog-tag/case-study/>" %}

Most deployments into a factory require customization for installation but bundling Remote.It in your product (robots, automation control devices, etc.) allows you to add #ConnectivityAsCode at your production line. Once integrated on the customer's factory floor your engineers and service teams can gain access to perform updates or support as needed. Customer access can also be provided with device sharing.

Reducing the need to connect and reconnect to customer site VPNs or require setting up network trusts to update or service your product at a customer's location.

## Cloud

Using Remote.It also gives you the ability to configure your security group to completely block traffic from the outside, only allowing access to your instance through Remote.It. Keep in mind that Remote.It uses Zero Trust/SASE architectures, and is therefore very secure. The only way someone else would have access to your instance is if you shared it with them through Remote.It, or if they had access to your Remote.It account.

Additionally, all of your instances or resources can be found on the Remote.It Web Portal or Desktop App, meaning Remote.It can function as a hub for all of your cloud instances and connections, even if they are in different regions. This makes keeping track of all your resources very convenient and easy, as they are all in one place.

How do you access other services where Remote.It is not installed? The services you set up are not just for the local target device, you can change your endpoints to other resources in the network by updating the service host address.

That means

* OpenSearch running as a service is accessible on your desktop.
* Connections to your cache service can be made from localhost.
* Databases running at scale can safely be queried from your code editor as though it was local.
* Machine Learning in the cloud can be leveraged securely from a device in the field.
* CI/CD can be leveraged to deploy without opening additional access.

## Cellular or Starlink Devices

Accessing target devices over cellular networks using CGNAT is typically difficult, expensive or just plain impossible.

{% hint style="info" %}
Setting up a Starlink site for the first time? [Remote Access Over Starlink](/introduction/get-started/starlink) is a step-by-step guide for reaching cameras, DVRs and NAS boxes behind CGNAT.
{% endhint %}

Unlike using a broadband ISP service you not only pay for the privilege of connecting to the network but the bandwidth used. But the fact that you can connect without installing additional infrastructure with faster and faster speeds means this area will explode with growth.

On a metered connection the goal is to reach a remote device at a moment's notice while using as little bandwidth as possible.

### Reduce truck rolls

Service, upgrades and diagnostics can be performed from the office rather than out in the field.

### Reduce bandwidth

You want maximum availability when there is an issue but don't need extra connections running 24/7.

Using the Desktop app or CLI, connections are available at all times. With persistent address on-demand peer-2-peer connections, once you set it up you can go straight to your third-party app without having to call reconnect.

### Bandwidth usage

If a device is always online you will use this much data to keep it communicating with Remote.It. This is less than 1 email a month to know where a device is and its online status.

**.02 Mbyte per hr, .49 Mbyte per day, 14 Mbyte per month**

Each extra service you add to a device will consume an extra:

**.01 Mbyte per hr, .24 Mbyte per day, 7 Mbyte per month.**

An idle connected service (P2P or proxy) will use the following amount of data:

**.065 Mbyte per hr.**

This is not including the data transferred over the connection when in use.

{% hint style="info" %}
Cellular connected devices may not want to leave idle proxies or P2P connections running.
{% endhint %}


# Glossary of Terms

Definitions of core Remote.It concepts — target and initiator devices, services, the Service Agent, organizations, licensing, and connection types.

<table><thead><tr><th width="161">Term</th><th>Definition</th></tr></thead><tbody><tr><td>Application</td><td>Software or a program running on a device to which you make a connection.<br>Examples:<br>ssh<br>RealVNC Server<br>Remote Desktop Server<br>Router Admin Panel</td></tr><tr><td>Connection Settings</td><td>When making a connection from one device to another, there are configurations which set the behavior for a connection.<br>Connection Name:<br>A friendly name that you can set to distinguish a connection from another<br>Routing:<br>Peer to Peer<br>Proxy<br>Peer to peer with proxy failover<br>Local Port:<br>Assigned port once the connection is established<br>When using the remote.it desktop, CLI or mobile applications, it will reconnect automatically when the initiator device attempts to use the connection again after the idle time is exceeded.</td></tr><tr><td>Initiator Device</td><td>The local computer that has remote.it installed. Connections are outbound.<br>Examples:<br>Windows PC<br>Macbook<br>iPhone/iPad</td></tr><tr><td>License</td><td>remote.it is free for up to 5 non-commercial devices. A license and subscription authorizes the user to connect and run scripts for more than 5 devices.<br>When a user doesn't have an active professional or enterprise license, connection and scripting access is limited to the first 5 devices by create date.</td></tr><tr><td>Organization</td><td>A grouping of users who can have access to devices which belong to organization.<br>The user who creates the organization will be the owner and all of their devices will automatically transfer to the organization. The owner can add users to the organization making them members. The owner is also responsible for licensing of users in the organization<br><a href="https://link.remote.it/support/organizations">See more about Organizations and features here</a>.</td></tr><tr><td>Organization Member</td><td>Users who have been added to an organization. The owner of the organization is responsible for licensing the organization's users by purchasing seats. <a href="https://link.remote.it/support/organization-roles">See more about roles here</a><br>Licensed: The owner has assigned a seat license to the user and the user has full access to the organization's devices/services<br>Unlicensed: The owner has not assigned a seat license to the user and the user will only have access to the first 5 devices (by create date) of the organization.</td></tr><tr><td>Peer to peer connection</td><td>A remote.it connection to a target device that is initiated from your computer. <a href="https://support.remote.it/hc/en-us/articles/360044788252">Click here</a> for more on connection types</td></tr><tr><td>Peer to peer with proxy failover</td><td>A remote.it connection which attempts to use the peer to peer connection method first and if unavailable will rollover to using a proxy connection. <a href="https://support.remote.it/hc/en-us/articles/360044788252">Click here</a> for more on connection types</td></tr><tr><td>Proxy connection</td><td><a href="https://support.remote.it/hc/en-us/articles/360044788252">A remote.it connection to a target device that is initiated from our servers and remaps the port. </a><a href="https://support.remote.it/hc/en-us/articles/360044788252">Click here</a> for more on connection types</td></tr><tr><td>Registration</td><td>The process of adding a device and/or services to the remote.it system.</td></tr><tr><td>Reverse proxy connection</td><td>A type of remote.it Service, used only to connect to web servers, which does not remap the port</td></tr><tr><td>Service</td><td>A configuration registered on the target device which you will use to access remote applications. The target device can have many services. There is a bulk service created by default and does not require entry of any service attributes. The bulk service provides the basis for a target device and enables scripting functionality.<br>Attributes of a service:<br>Application Type: The application mapped to this service i.e. SSH, VNC, RDP, HTTP/S<br>Port: The port on the target device which the application is listening<br>Service host address: Local network IP address or fully qualified domain name to host this service<br><br>Enabled: Whether or not the remote.it service is available for connections. You may want to disable this and enable it only when needed if you are concerned with bandwidth like on a cellular internet connection<br>Status: This is online/offline status of the remote.it service.</td></tr><tr><td>Service Agent</td><td><a href="https://support.remote.it/hc/en-us/articles/360051286351-Glossary-of-Terms#h_01FMR1DWN4EMRHZWPCPTKXFTHV">The remote.it daemon which is associated with the </a><a href="https://support.remote.it/hc/en-us/articles/360051286351-Glossary-of-Terms#h_01FMR1DWN4EMRHZWPCPTKXFTHV">target device service</a> which enables remote.it connections.</td></tr><tr><td>Scripting</td><td>The remote.it feature which allows you to run a script on any number of target devices. This uses interpreted languages such as bash, Python, Ruby, Node, etc., assuming you have the interpreter installed on your system. This feature is only available via the remote.it portal https://app.remote.it For more on this feature, visit the scripting articles<br>Examples:<br>Fetching device information for a group of devices<br>Updating devices deployed in the field</td></tr><tr><td>Target Device</td><td>The remote computer or VM you want to connect to and/or run scripts against with remote.it installed. Connections are inbound.<br>Examples:<br>Raspberry Pi<br>AWS AMI<br>Windows Server</td></tr><tr><td>User</td><td>A person with a remote.it account. They may create devices/services and perform functions against their own devices such as connection, sharing, and script execution.</td></tr></tbody></table>


# Bluetooth Wifi Onboarding Package (r3onboard)

Configure WiFi and register headless Raspberry Pi and Debian Bookworm devices over Bluetooth LE with r3onboard — no keyboard or monitor required.

## Bluetooth WiFi Onboarding Package (r3onboard)

Bluetooth WiFi Onboarding is a solution developed by Remote.It that simplifies setting up new devices. It uses Bluetooth Low Energy (BLE) to let you configure a device's WiFi and register it with the Remote.It service — no keyboard, monitor, or pre-flashed network settings required. This makes it ideal for headless deployments and for devices that will be reconfigured after they ship.

Once a device is on the network and registered, you get secure remote access to services on it (SSH, VNC, web servers, and more) through Remote.It.

#### [r3onboard GitHub Repo](https://link.remote.it/github/ble)

#### [remote.it App for using r3onboard](https://link.remote.it/getting-started/rpi-ble-image)

#### Key Features

* **Easy WiFi configuration:** Connect over Bluetooth LE to set WiFi credentials and get your device on the network in seconds.
* **Remote access:** Register the device with the Remote.It service to reach it from anywhere.
* **Automatic WiFi scanning:** Available networks are scanned on boot so they're ready to pick from the app.
* **Compatibility:** Built for Debian Bookworm packages, with a primary focus on Raspberry Pi devices.

#### How It Works

`r3onboard` is a Python service that runs on the device and exposes a Bluetooth LE GATT server. The Remote.It app connects to that server to read WiFi status, list nearby networks, send WiFi credentials, and pass a registration code. WiFi is applied through NetworkManager, and registration hands the device off to the Remote.It service for remote access.

### Requirements

* A Raspberry Pi (primary target) or another Debian **Bookworm** device
* Bluetooth Low Energy capability (built in on modern Raspberry Pi models)
* WiFi capability for the network you want to join
* NetworkManager managing the device's networking (the default on Bookworm)

### Option 1: Use Our Prebuilt Pi Image

If you're using a Raspberry Pi, the fastest path is our prebuilt image with `r3onboard` already installed and enabled. [See details on using the prebuilt Pi image.](https://link.remote.it/getting-started/rpi-ble-image)

### Option 2: Install r3onboard Into Your Own Image

Use this path if you maintain your own Debian/Raspberry Pi OS image and want to add BLE onboarding to it.

#### Manually Installing the [r3onboard Debian Package](https://downloads.remote.it/r3onboard/latest/r3onboard_all.deb)

1. **Download the package to `/tmp`:**

   ```sh
   wget -P /tmp https://downloads.remote.it/r3onboard/latest/r3onboard_all.deb
   ```
2. **Install it with apt:**

   ```sh
   sudo apt update
   sudo apt install /tmp/r3onboard_all.deb
   ```

   Installation sets up the service and enables it to start on boot.
3. **Verify the service:**

   ```sh
   sudo systemctl status r3onboard
   ```

   You should see the service as `enabled` (starts on boot) and, after a reboot, `active (running)`. To start it now without rebooting:

   ```sh
   sudo systemctl start r3onboard
   ```
4. **Create your image:**

   Once `r3onboard` is installed, use your preferred imaging tool to capture a backup of the system. That image can then be deployed to other devices.

#### Configuration (optional)

Settings live in `/etc/r3onboard/config.ini`:

```ini
[Settings]
# How long the device advertises over Bluetooth after the service starts.
# Use s, m, or h (e.g. 30s, 10m, 1h). Set -1 to advertise indefinitely.
Duration = 10m
# Log verbosity: debug, info, warning, error, critical
LogLevel = info
```

By default the device is only discoverable over Bluetooth for **10 minutes** after the service starts. For kiosk or long-lived onboarding scenarios, set `Duration = -1`. After editing the file, restart the service:

```sh
sudo systemctl restart r3onboard
```

#### Automating the Install

You can use a tool like `systemd-nspawn` to mount and boot an existing system image on your own machine, then install the Debian package from inside that booted container. The `updateImage.sh` script in the repo is a good starting point — it's how we build the Raspberry Pi image.

### Onboarding a Device

With `r3onboard` running and the device advertising over Bluetooth:

1. Open the Remote.It app and connect to the device over Bluetooth.
2. Pick a WiFi network from the scanned list and enter the password.
3. Optionally register the device to your Remote.It account with a registration code.

The app reports WiFi and registration status back to you as each step completes.

> **Building your own BLE client?** The GATT service UUID and characteristics — WiFi status, WiFi list, registration status, and the command characteristic (`WIFI_SCAN`, `WIFI_CONNECT`, `R3_REGISTER`) — are documented in the [repo README](https://link.remote.it/github/ble).

### Viewing Logs

View recent service logs with:

```sh
journalctl -u r3onboard -n 100
```

Add `-f` to follow the logs live while you onboard a device:

```sh
journalctl -u r3onboard -f
```

For more detail, set `LogLevel = debug` in `/etc/r3onboard/config.ini` and restart the service.

### Troubleshooting

**Device doesn't appear over Bluetooth**

* By default it only advertises for 10 minutes after the service starts. Reboot, restart the service (`sudo systemctl restart r3onboard`), or set `Duration = -1` in the config.
* Confirm the service is running: `sudo systemctl status r3onboard`.

**WiFi won't connect**

* Check the logs: `journalctl -u r3onboard -n 100`.
* Double-check the SSID and password, and confirm the device's WiFi hardware supports that network's band.
* `r3onboard` applies WiFi through NetworkManager — make sure NetworkManager is installed and running.

**Registration fails**

* Confirm the registration code is valid and hasn't already been used.
* Check the logs for the specific error returned by the Remote.It service.

### Uninstalling

Remove the package (this stops and disables the service and removes its virtual environment):

```sh
sudo apt remove r3onboard
```

To also remove the configuration file at `/etc/r3onboard/config.ini`:

```sh
sudo apt purge r3onboard
```

### Resources

* [r3onboard GitHub repo](https://link.remote.it/github/ble)
* [Using the prebuilt Raspberry Pi image](https://link.remote.it/getting-started/rpi-ble-image)
* [Download the latest Debian package](https://downloads.remote.it/r3onboard/latest/r3onboard_all.deb)


# Device Package

The Device Package installs the Remote.It target agent — the smallest-footprint way to make a headless or embedded Linux device reachable for inbound connections.

## Device Package

The Device Package installs the remote.it **target agent** — the lowest-level component required for connections. It's the smallest way to make a device reachable through remote.it.

**With this package installed, other devices and users can connect&#x20;*****to*****&#x20;this device, but this device cannot initiate connections&#x20;*****to*****&#x20;others.** If this machine also needs to initiate connections, install one of these instead:

* **CLI** — if connections will be made from scripts or the command line.
* **Desktop Application** — a straightforward UI for making connections and configuring devices.

Use the Device Package when you care about disk space and process footprint — for example on headless or embedded Linux devices such as Raspberry Pi, OpenWrt routers, IoT hardware, and cloud VMs.


# Device Package Supported Platforms

Platforms and architectures supported by the Remote.It Device Package, including Linux distributions, Raspberry Pi, OpenWrt, and AWS cloud instances.

{% hint style="info" %}
AWS Cloud users, please pick the distribution package that matches your OS and architecture installed on your instance below.
{% endhint %}

### Device Package <a href="#device_package_supported_platforms" id="device_package_supported_platforms"></a>

Please see our [downloads page](https://www.remote.it/download-list?products=device-package#Download-Results) for a complete list of all of the supported platforms and architectures.


# Device Package Installation

Install and register the Remote.It Device Package on Debian, Ubuntu and Linux devices with a single terminal command, then set up your first services.

## New Installation

This guide will step you through the set up of remote.it on **Debian, Ubuntu and Linux** devices using the command line/terminal and an installation package on a device which remoteit has not been previously installed.

{% hint style="warning" %}
Prerequisites:

1. You have a remote.it account (If not, please go ahead and create an account at <https://app.remote.it>)
2. You are on <https://app.remote.it> OR have installed the remote.it Desktop application on a machine you will be using to configure and connect to your device. (This doesn't need to be on the same network as the device you are setting up) See <https://remote.it/download/> for the different options available.
3. SSH access to the device you want to install remote.it and connect to
   {% endhint %}

## Quick Install

This quick install allows you to just paste a single command into the terminal of the target device. You must have the Desktop App or access to <https://app.remote.it> installed and a remote.it account created before proceeding.

### 1. Open the remote.it Desktop App or <https://app.remote.it>

If using the desktop app, it must be version 3.5.2 or greater.

### 2. Click add device and select your system

<figure><img src="/files/2KcvqDg93pYijwfCd6Zu" alt="The Add Device screen in the Remote.It Desktop app with a system type selected"><figcaption></figcaption></figure>

### 3. Copy the registration command and paste into the terminal window of your target device

{% hint style="warning" %}
Devices are registered using the Host name of the device. You can add a variable to the command to override this before you run the command by adding the following before the the R3\_REGISTRATION\_CODE plus a space.

R3\_DEVICE\_NAME="Your device name"

Otherwise, you can rename the device after in the RemoteIt Desktop, app.remote.it or Mobile application. [See documentation on devices and Editing Device Name](https://link.remote.it/support/device-rename)
{% endhint %}

This command will automatically detect the platform and architecture of your device. It then downloads and installs the appropriate package. It will then register the device to your account.

### 4. Set up services

Your desktop app should notify you that your new device has been registered. remote.it will automatically detect and set up SSH.

If you have additional services you would like to add, follow the directions provided [here](#id-4.-set-up-services-on-your-device).<br>

## Manual Installation

We recommend using the quick install method above since it will download the package and install it automatically. You can use this method if you prefer to select the package and install it manually.

### 1. Download the package

Open a terminal window on the device where remote.it will be installed, then download the package.

Example below is for a specific pi package. Please use the appropriate package url. This will place the file in your home directory [click here ](https://www.remote.it/download-list?products=device-package#Download-Results)for specific packages and urls.

**For Debian OS distributions, if you are not sure of the architecture, you can run the following command:**

```
sudo dpkg --print-architecture
```

{% hint style="info" %}
sudo command is only required on systems where you are not logged in as root.
{% endhint %}

```
sudo wget [URL for Package 
(i.e. https://downloads.remote.it/remoteit/v4.14.1/remoteit-4.14.1.arm64.deb)]
```

### 2. Update your package manager and install

{% tabs %}
{% tab title="apt" %}
Continue in terminal on the target device

```
sudo apt update
```

Once that completes, then continue with the installation replacing the path and file name as appropriate

```
sudo apt install [file name (i.e. ./remoteit-4.14.1.armhf.rpi.deb)]
```

**When this completes you will see the claim code to use in the desktop application to complete the setup.**
{% endtab %}

{% tab title="opkg" %}
Continue in terminal on the target device

```
opkg update
```

Once that completes, then continue with the installation replacing the path and file name as appropriate

```
opkg install ./file
```

**When this completes you will see the claim code to use in the desktop application to complete the setup.**
{% endtab %}

{% tab title="yum" %}
Continue in terminal on the target device

```
sudo yum update
```

Once that completes, then continue with the installation replacing the path and file name as appropriate

```
sudo yum install ./file
```

**When this completes you will see the claim code to use in the desktop application to complete the setup.**
{% endtab %}

{% tab title="pacman" %}
Continue in terminal on the target device

```
sudo pacman -Syy
```

Once that completes, then continue with the installation replacing the path and file name as appropriate

```
sudo pacman -U ./file
```

**When this completes you will see the claim code to use in the desktop application to complete the setup.**
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
You will need this claim code to complete the setup in the next steps. Save it until you complete registering the device.

**This claim code is valid for 24 hours. If not used before then, re-run your installation command to get a new code.**
{% endhint %}

<figure><img src="/files/-Meb--NTV_eH1aKVfIH_" alt="Terminal output from the install command showing the generated registration claim code"><figcaption></figcaption></figure>

### 3. Claim and register the device

Open your remote.it desktop application and log in. Then add the device using the registration claim code by clicking the + (Device Registration) in the upper left, then enter the claim code in the provided field.

<figure><img src="/files/Qkp2fVYV8ztnxHU3eXz4" alt="The Device Registration field in the Remote.It Desktop app where the claim code is entered"><figcaption></figcaption></figure>

You have now successfully registered the device to your account and should see it in your device list. If you get a message that it was not found, this indicates that the device was already claimed.

### 4. Set up services on your device

You will now define the services/ports for connections. For example SSH, HTTP, VNC, etc.

{% hint style="info" %}
The device itself must be online to set up any services. The services you define in remote.it need to be set up and running on the device. For example if you set up VNC in remote.it, but do not have it running, it will not be reachable by remote.it
{% endhint %}

Click on the device to see its details and click the + in the Services panel to add a new service.<br>

<figure><img src="/files/HqRs956x7wLMTcbSPgA2" alt="Device details view with the Services panel and its add service button"><figcaption></figcaption></figure>

Select the appropriate service type. Then provide a name and port (Defaults are provided for most services). Only override default port if you have assigned a different port for this service on your device. Override the service host address if you are using this device as a [jump service](https://link.remote.it/support/jumpbox).

Click save. You will now see the new service.

<figure><img src="/files/TM6NRtWetJIyjYenYJsm" alt="A saved SSH service shown on the device, ready to connect"><figcaption></figcaption></figure>

Repeat this process until you have all the services you want available via remote.it. You are now ready to connect and/or share this device. Visit [connections page](https://support.remote.it/hc/en-us/articles/360048935411-Connections) or the [sharing page](https://support.remote.it/hc/en-us/articles/360053354671-Device-Service-Sharing).

## Upgrades

{% hint style="warning" %}
If you have a device with Desktop or CLI installed, upgrade those applications directly. If you have a version of remoteit which is older than 3.0, please [contact support](https://support.remote.it/hc/en-us/requests/new) so that we can assist you directly.
{% endhint %}

To upgrade a device with remoteit device package Version 3.0 and higher installed follow these instructions.

### 1. Connect to ssh service on your device

Start an ssh connection (either directly or through remoteit) OR terminal and direct access to the target device

### 2. Download the package

Create an ssh connection to the device via remote.it and open terminal. (If you do not have a remoteit ssh service defined, you can [create one](#4-set-up-services-on-your-device) or connect directly by using either the LAN or direct hardware console access)

Download the installation package to the device where remote.it will be installed. Example below is for a specific pi package. Please use the appropriate package url. This will place the file in your home directory [See above](#supported-platforms).

```
sudo wget https://downloads.remote.it/remoteit/v4.13.7/remoteit-4.13.7.armhf.rpi.deb
```

### 3. Install the new package

This will step will update the remoteit target daemon and preserve the previously defined services and configurations. age manager as appropriate. i.e. Opkg, RPM or another package manager

{% tabs %}
{% tab title="apt" %}
Continue in terminal on the target device

```
sudo apt update
```

{% hint style="warning" %}
If using remoteit to access ssh to the device, you will lose your ssh connection to the device during this step. This is normal since we are replacing the daemon and remoteit will restart the service.
{% endhint %}

During this step your desktop app will notify you that the device has gone offline. This is normal as the remoteit target service will stop during upgrade.\
Once this step completes you will again be notified that the device has come back online. If you were using the desktop for your connection, this connection will resume.

```
sudo nohup apt install ./file &
```

{% endtab %}

{% tab title="opkg" %}
Continue in terminal on the target device

```
opkg update
```

{% hint style="warning" %}
If using remoteit to access ssh to the device, you will lose your ssh connection to the device during this step. This is normal since we are replacing the daemon and remoteit will restart the service.
{% endhint %}

You may also need to install nohup which is not installed by default on most systems. This allows the installation to continue once the upgrade is in process and ssh hangs up temporarily.

```
opkg install coreutils-nohup
```

During this next step your desktop app will notify you that the device has gone offline. This is normal as the remoteit target service will stop during upgrade.\
Once this step completes you will again be notified that the device has come back online. If you were using the desktop for your connection, this connection will resume.

```
nohup opkg install ./file &
```

{% endtab %}

{% tab title="yum" %}
Continue in terminal on the target device

```
yum update
```

{% hint style="warning" %}
If using remoteit to access ssh to the device, you will lose your ssh connection to the device during this step. This is normal since we are replacing the daemon and remoteit will restart the service.
{% endhint %}

You may also need to install nohup which is not installed by default on most systems. This allows the installation to continue once the upgrade is in process and ssh hangs up temporarily.

```
yum install coreutils
```

During this next step your desktop app will notify you that the device has gone offline. This is normal as the remoteit target service will stop during upgrade.\
Once this step completes you will again be notified that the device has come back online. If you were using the desktop for your connection, this connection will resume.

```
nohup yum install ./file &
```

{% endtab %}
{% endtabs %}

## Uninstall

These instructions apply to the remoteit Device Package Version 4 and higher.

{% hint style="danger" %}
**If you remove remote.it software while using a remote.it connection you will lose access to the device through our service immediately.**
{% endhint %}

Follow this link:

<https://support.remote.it/hc/en-us/articles/360054866351-Removing-the-remoteit-package-or-Desktop-application>

At this point, you can then go to your device list (either in the Desktop Application or in the web portal at <https://app.remote.it/#devices> and delete the device to remove it from your device registry.


# Device Package Usage

Connect to the services on a device running the remote.it Device Package, and use the built-in connectd network diagnostics to verify the target device's connectivity.

### Connecting to Services

Once remote.it is installed on the target device and its services are configured, you can connect to those services from any remote.it client: the Desktop app, CLI, [Web Portal](https://app.remote.it), mobile apps, or the API.

remote.it supports two connection types — direct **peer-to-peer** and **proxy** — and not every client supports both:

| Client     | Peer-to-peer | Proxy |
| ---------- | ------------ | ----- |
| Desktop    | ✓            | ✓     |
| CLI        | ✓            | ✓     |
| Web Portal |              | ✓     |
| API        |              | ✓     |

The mobile apps can also connect to your device's services.

{% hint style="info" %}
For details on making and managing connections, see the documentation for [Desktop](https://support.remote.it/hc/en-us/articles/360048935411-Connections), the [Web Portal](https://support.remote.it/hc/en-us/articles/360048707812-The-Devices-Page), or the API.
{% endhint %}

## Checking the Target Network

The Device Package ships only the `connectd` command, and it is **not** added to the system `PATH`. Run these diagnostics on the target device itself — they confirm the device can reach remote.it's servers and any other targets on your LAN.

{% hint style="info" %}
Because `connectd` isn't on the `PATH`, call it with its full path — for example `/usr/share/remoteit/connectd -n` on Linux — or `cd` into the install directory first. The examples below use `connectd` for brevity.
{% endhint %}

{% hint style="warning" %}
If you run antivirus or endpoint protection on the device, you may need to allow `connectd` to run.
{% endhint %}

#### Network diagnostics — `connectd -n`

Run `connectd -n` to confirm the network is configured to allow a remote.it connection. It checks DNS resolution, TCP and UDP connectivity to remote.it, how your router handles NAT and ports, and runs internal cryptography self-tests.

```
connectd -n

Running Network Diagnostics
---------------------------------
Checking if DNS works ... .[OK]
Checking TCP connectivity to remote.it...<oip=10.0.0.106> [OK]
Checking UDP connectivity to remote.it...
Send to 69.64.90.20:5959 [] [mip=##.##.###.###] [oport=59450 mport=59450] [preserve port] 
Send to 69.64.90.20:5960 [] [mip=##.##.###.###] [oport=59450 mport=59450] [no remap] [preserve port] 
Send to 69.64.90.128:5961 [] [mip=##.##.###.###] [oport=59450 mport=59450] [no remap] [preserve port different IP] [OK]
Checking if NAT-PMP Router is found...[NOT FOUND]

This router preserves ports, this is optimal.
This router doesn't remap new connections to new ports.
Endian : Little
SHA1 test:
  passed.
RC4 test:
  passed
XXTEA test:
  passed.
Looks compatible.
```

{% hint style="info" %}
**What to look for:** every check should report `[OK]`, and the run should end with `Looks compatible.` A router that preserves ports and doesn't remap connections (as shown above) gives the best chance of a direct peer-to-peer connection.
{% endhint %}

#### NAT timeout check — `connectd -nat`

For extra confidence that connectivity is stable — and that the device won't report inaccurate offline events — run `connectd -nat`. It measures how long your NAT keeps a UDP mapping open. A calculated time of around 30 seconds or more is desirable.

```
connectd -nat

Running Nat UDP Reply Timeout Checker
-------------------------------------
Checking 1 seconds on port 64968 (54.245.28.114)[good reply at 1 seconds] 
Checking 2 seconds on port 62130 (54.245.28.114)[good reply at 2 seconds] 
Checking 4 seconds on port 63878 (54.245.28.114)[good reply at 4 seconds] 
Checking 8 seconds on port 59889 (54.245.28.114)[good reply at 8 seconds] 
Checking 16 seconds on port 64141 (54.245.28.114)[good reply at 16 seconds] 
Checking 32 seconds on port 64688 (54.245.28.114)[Failed at 32 seconds] 
Checking 24 seconds on port 51136 (54.245.28.114)[good reply at 24 seconds] 
Checking 28 seconds on port 50498 (54.245.28.114)[good reply at 28 seconds] 
Checking 30 seconds on port 60809 (54.245.28.114)[good reply at 30 seconds] 
Checking 31 seconds on port 52161 (54.245.28.114)[Failed at 31 seconds] 
Calculated NAT map time is 30 seconds exiting.

Running UDP Nat MAP Timeout Checker
---------------------------------
Setting up NAT mapping
[mip=##.##.###.###] [oport=55156 mport=55156] Trying for 120 seconds
testing mapping (54.245.28.114)..[mapping invalid was 55156 now 55156] [new timeout to try 60]
Trying for 60 seconds
testing mapping (54.245.28.114)..[mip=24.13.204.189] [oport=55156 mport=55156] [mapping still at 55156] [increase timeout to 90 ]
Trying for 90 seconds
testing mapping (54.245.28.114)..[mapping invalid was 55156 now 55156] [new timeout to try 75]
Trying for 75 seconds
testing mapping (54.245.28.114)..[mapping invalid was 55156 now 55156] [new timeout to try 67]
Trying for 67 seconds
testing mapping (54.245.28.114)..[mapping invalid was 55156 now 55156] [new timeout to try 63]
Trying for 63 seconds
testing mapping (54.245.28.114)..[mapping invalid was 55156 now 55156] [new timeout to try 61]
Trying for 61 seconds
testing mapping (54.245.28.114)..search completed NAT timeout calculated to ~60 seconds, exit
```

{% hint style="info" %}
**What to look for:** a calculated NAT map time of roughly 30 seconds or more. Very short mapping times can cause remote.it to see the device as intermittently offline.
{% endhint %}

#### Connectivity check — `connectd -nc <server:port>`

Use `connectd -nc <server:port>` to test whether the device can open a TCP connection to a specific address. This is useful for confirming a LAN target or jump destination is reachable before you add it as a service.

```
connectd -nc google.com:80

Connectivity Check
SUCCESS Connect to google.com:80
```

{% hint style="info" %}
`SUCCESS` confirms the device can reach that host and port. If it fails, check that the target is running and reachable from the device's network.
{% endhint %}

### Troubleshooting Connectivity

If a diagnostic check doesn't pass:

* Confirm the device has working internet access and DNS resolution.
* Make sure the device can reach remote.it's servers over the required outbound ports — no inbound port forwarding is needed. See remote.it's firewall and port requirements for the specific ports.
* Allow `connectd` through any local antivirus or endpoint protection.
* Re-run `connectd -n` after each change.

Remember that the Desktop and CLI can use faster peer-to-peer connections, while the Web Portal and API always connect through a proxy.


# NPM Package

Socket-Link 🔗 is the Remote.It NodeJS package for creating fast secure remote connections in your application or workflow.

{% hint style="info" %}
Please note this software is still in BETA. We do not recommend adding it to a production environment just yet.
{% endhint %}

## Getting Started

To create your first socket-link connection you will need NodeJS and the Service Key for the target service you want to connect to. This guide assumes you are familiar with a terminal and JavaScript.

If you already know how to use Remote.It you might just want to head to the [GitHub page of the socket-link project ](https://github.com/remoteit/socket-link.js)to get started.

### Client Sample

```typescript
import { SocketLink } from '@remote.it/socket-link'

// Create a new client
const socketLink = new SocketLink()

// Establish the connection
const proxy = await socketLink.connect('MNETSJSW')

// The address can not be used in your application
const address = proxy.address

// ... 

// Close the connection
await proxy.close()
```

Above is a simple implementation using a **Service Key** and returning an auto-assigned port.

***

## Service Authentication

In the example above the connection only needs the **Service Key** to connect. This is the simplest way to use connections, as no additional credentials are needed.

### Service Keys

Service Keys can be managed through the Remote.It application UI or the GraphQL API. You can enable / disable / delete / create unique Service Keys for quick and easy access to any service. This is the most flexible way to grant access to a service, as the key only allows access to one service and can be revoked at any time.

You can find the Service Key generation controls on the connect page of every service. All keys are eight character strings.

```
QIYOKB2H
```

You can also use GraphQL to generate a service key by running the following mutation. [Learn how to run GraphQL commands against our API.](/developer-tools/api/usage)

Generate a key:

```typescript
// Create a new client
const socketLink = new SocketLink()

// Establish the connection
const proxy = await socketLink.connect('MNETSJSW')

const mutation = `
mutation SetLink($serviceId: String!, $enabled: Boolean) {
  setConnectLink(serviceId: $serviceId, enabled: $enabled) {
    code
    enabled
    created
  }
}`

// The address can not be used in your application
const address = proxy.address


```

Remove a key:

```graphql
mutation RemoveLink($serviceId: String!) {
  removeConnectLink(serviceId: $serviceId)
}
```

## Account Authentication

Alternatively you can authenticate at the account level. Account authentication will allow connecting with a `serviceId` to any device service that the account as access to.

```typescript
// ...

// Establish the connection
const proxy = client.connect('80:00:00:00:01:0C:2B:9D', {
  credentials: 'path/to/credentials'
})

// ...
```

### User Access Key and Secret

You can generate and manage access key and secrets from the [Account > Access Keys](https://link.remote.it/credentials) section of the Remote.It apps.

To use account credentials you have three options:

1. **Credentials File** Path to the file can be added to the `credentials` configuration option or it can be placed in the default `~/.remoteit/credentials` location.
2. **Environment Variables** `R3_ACCESS_KEY_ID` and `R3_SECRET_ACCESS_KEY`
3. **Configuration Options** `keyId` and `secret`

***

## Connection Target

A Remote.It agent must be running on your target network or system. If you can not install an agent on the system hosting the service (ssh, database, api) then you can install an agent on another system on the network and *jump* to the service.

{% hint style="info" %}
NPM Package for targets is coming soon
{% endhint %}

### Device installation

To configure a target service on the device:

1. Log in to one of the **Remote.It** apps
2. Click the blue `+` button to add a new device
3. Select your device type
4. Copy the installation command
5. Run the command on your device
6. Wait a few seconds for the device to appear in the app
7. Add a service to the new device by clicking on the `+` button on the device page
8. Select a service type *(SSH, HTTPS, Postgresql, etc)* to add, or manually enter the port and host your service is running on

### Jump Installation

For a service on the same network as your device, just follow the steps above, except use the local network address and port.

You can now select a service in the app and generate a **Service Key** to connect with.

***

## CLI

The socket-link NPM package comes with a build in cli as well that can be leveraged for easy connecting and scripting as well.

Sample ssh connection:

```sh
socket-link connect TLDY6IIY -- ssh -p {port} -l root {address}
```

### Commands

#### `api`

You an use the `api` command to easily execute [GraphQL](https://api.remote.it/graphql/v1/doc) queries and mutations using your [account credentials.](#account-authentication)

Basic GraphQL query:

```sh
socket-link api "query { version }"
```

Sample query for [service key](#service-keys) from our demo device using a service `id` variable:

```sh
socket-link api -v '{"id": "80:00:00:00:01:0C:2B:9D"}' 'query ($id: [String!]!) { login { service(id: $id) { link(type: [WSS]) { code } } } }'
```

***

## API

### SocketLink Constructor

**Description**

The `SocketLink` constructor initializes a new instance of the `SocketLink` class with specified options.

**Syntax**

```typescript
constructor(options: Partial<ClientOptions> = {})
```

**Parameters**

`options`: A partial object of `ClientOptions` type, providing various configuration options for `SocketLink`. It includes:

* `router`: Hostname of the Remote.It socket-link router.
* `keyId`: Authentication key ID. Defaults to `process.env.R3_ACCESS_KEY_ID`.
* `secret`: Authentication secret. Defaults to `process.env.R3_SECRET_ACCESS_KEY`.
* `config`: Path to the Remote.It configuration files.
* `profile`: Credential profile name.
* `debug`: Boolean flag to enable debug output.

**Example Usage**

```typescript
const socketLinkOptions = {
  router: 'example.router.com',
  keyId: 'yourKeyId',
  secret: 'yourSecret',
  config: '/path/to/config',
  profile: 'default',
  debug: true
};

const socketLink = new SocketLink(socketLinkOptions);
```

***

### SocketLink Class Methods

#### `debug`

Getter method to retrieve the debug state.

* **Returns**: `boolean` - The current debug state.

#### `router`

Getter method to retrieve the router string.

* **Returns**: `string` - The current router string.

#### `resolve(name: string): string`

Resolves a path relative to the Remote.It configuration directory.

* **Parameters**: `name` - The filename or path to resolve.
* **Returns**: `string` - The resolved path.

#### `api(query: string, variables?: any): Promise<any>`

Sends a GraphQL API request.

* **Parameters**:
  * `query` - The GraphQL query string.
  * `variables` (optional) - The variables for the GraphQL query.
* **Returns**: `Promise<any>` - The data returned from the API.

#### `connect(target: string, options?: Partial<ProxyOptions>): Promise<Proxy>`

Establishes a proxy connection to a target.

* **Parameters**:
  * `target` - The target for the proxy connection.
  * `options` (optional) - Additional options for the proxy.
* **Returns**: `Promise<Proxy>` - The Proxy instance.

#### `register(options?: Partial<ServiceOptions>): Promise<Service>`

Registers a new service.

* **Parameters**:
  * `options` (optional) - Options for the service registration.
* **Returns**: `Promise<Service>` - The Service instance.

#### `getSignature(): Promise<SigningKey | undefined>`

Retrieves a signing key for API requests.

* **Returns**: `Promise<SigningKey | undefined>` - The signing key or undefined if not found or not accessible.


# CLI

The Remote.It CLI is a unified command line tool for configuring devices and initiating outbound connections without the Desktop application.

The Command Line Interface (CLI) is a unified tool that provides a consistent interface for interacting with remote.it on a given device. CLI commands are covered [here](/developer-tools/cli-usage) including descriptions, syntax, and usage examples.

{% hint style="info" %}
Only install CLI if you need to make a connection from the device to another device directly. Most of the time you need a [device package](/introduction/get-started/platforms-and-packages#device-package) or the [Desktop Application](https://remote.it/downloads). Only install the CLI if you need have the device make an initiator connections.

At this time Windows single board for IoT devices does not have a device package and you should install the CLI.
{% endhint %}

The remote.it Command Line Interface (CLI) is installed as part of the Desktop Application. This set of instructions is to install the CLI as a stand alone where the desktop application is not needed.


# CLI Supported Platforms

Platforms and architectures supported by the Remote.It CLI, including Linux, Raspberry Pi, macOS, Windows and AWS cloud instances.

{% hint style="info" %}
AWS Cloud users, please pick the distribution package that matches your OS and architecture installed on your instance.
{% endhint %}

### CLI

Please see our [downloads page](https://link.remote.it/download/cli) for a complete list of all of the supported platforms and architectures.


# CLI Installation

Install and register the Remote.It CLI on Linux, Raspberry Pi OS, macOS and Windows using the quick install command or a manual package download.

{% hint style="warning" %}
Only install CLI if you need to make a connection from the device to another device directly (Initiator connection). Most of the time you need a [device package](/introduction/get-started/platforms-and-packages#device-package) or the [Desktop Application](https://remote.it/downloads).

At this time Windows single board for IoT devices does not have a device package and you should install the CLI.
{% endhint %}

{% hint style="info" %}
The remote.it CLI has slightly different behavior if you are running as a root user versus a non-root user. In general, you will want to run as a root user, though there are a couple cases where you don't. These will be made clear.

* On Windows, you will need to open a "Command Prompt" as an Administrator and replace any example you see as `sudo remoteit` by `remoteit.exe`
* On Mac and Linux, you must run any commands related to creating/managing a Device or Services as a root user (e.g. `sudo`)
* OpenWRT is not available at this time
  {% endhint %}

## Quick Install & Registration

This quick install allows you to just paste a single command into the terminal of the target device. You must have the Desktop App or access to <https://app.remote.it> installed and a remote.it account created before proceeding.

{% hint style="warning" %}
Quick install only is available for Linux based systems such as Debian, Raspberry Pi OS, MacOS, and Linux at this time. If you have Windows, please refer to [manual installation ](#manual-installation)below.

The quick install script tries to determine the correct CLI package to download based on your system architecture. It then downloads the CLI package, installs it, and registers it to your account. You can do the same with the manual install instructions below as long as you pick the right CLI package to download and install.
{% endhint %}

### 1. Open the remote.it Desktop App or <https://app.remote.it>

If using the desktop app, it must be version 3.5.2 or greater.

### 2. Ensure that you are in the context of the account you wish to register the device. See [Organizations as Members](https://link.remote.it/support/organization-as-members)

### 3. Click add device, select your system, then copy the code.

<figure><img src="/files/FjWoU8TT92XBli3LXDeG" alt="The Add Device screen in the Remote.It Desktop app showing the registration code to copy"><figcaption></figcaption></figure>

### 4. Use the code in command to install the CLI

This command will automatically detect the platform and architecture of your device. It will install the CLI, register it to your account and set up the SSH service.

{% hint style="info" %}
Replace YOUR-REGISTRATION-CODE with the registration code you copied from the Remote.It Add Device Page.
{% endhint %}

{% code overflow="wrap" lineNumbers="true" %}

```sh
R3_REGISTRATION_CODE="YOUR-REGISTRATION-CODE" sh -c "$(curl -L https://downloads.remote.it/cli/install_cli.sh)"
```

{% endcode %}

{% hint style="warning" %}
Devices are registered using the Host name of the device. You can add a variable to the command to override this before you run the command by adding the following before the the R3\_REGISTRATION\_CODE plus a space.

R3\_DEVICE\_NAME="Your device name"

Otherwise, you can rename the device after in the RemoteIt Desktop, app.remote.it or Mobile application. [See documentation on devices and Editing Device Name](https://link.remote.it/support/device-rename)
{% endhint %}

Your new device should register to your account and it is ready for use. [See Usage.](/developer-tools/cli-usage)

If you have issues with registration, we want to hear from you. Please post on our community at [forum.remote.it](https://forum.remote.it)

## Manual Installation

We recommend using the quick install method above since it will download the package and install it automatically. You can use this method if you prefer to select the package and install it manually.

### 1. Download the Binary

Download the binary for the platform and Architecture/Distribution to the device. Find the binaries here: <https://link.remote.it/download/cli>

Please be sure to download the correct package for your device.

### 2. Run commands

{% tabs %}
{% tab title="Debian/Linux/Raspberry Pi OS" %}
Place the file in /usr/bin and rename to "remoteit"

You will need to change permissions on the file to make it executable by opening Terminal

```
sudo chmod +x /usr/bin/remoteit
```

After placing the binary and making it executable, you will need to install the agent using the following command

<pre><code><strong>sudo remoteit install
</strong></code></pre>

You can now start using CLI. See [Usage](/developer-tools/cli-usage) for **registration** and connection information
{% endtab %}

{% tab title="MacOS" %}
Place the file in /usr/local/bin and rename to "remoteit"

You will need to change permissions on the file to make it executable by opening Terminal

```
sudo chmod +x /usr/local/bin/remoteit
```

After placing the binary and making it executable, you will need to install the agent using the following command

```
sudo remoteit install
```

You can now start using CLI. See [Usage](/developer-tools/cli-usage) for registration and connection information
{% endtab %}

{% tab title="Windows" %}
Place the file in your drive which has "Program Files" typically your "C" drive and rename to "remoteit.exe"

You will need to update your PATH environmental variables to add the full path to the exe. e.g. C:\Program Files\remoteit.exe

You will need to install the agent using the following command as an Administrator in command line

```
remoteit install
```

You can now start using CLI. See [Usage](/developer-tools/cli-usage) for registration and connection information
{% endtab %}
{% endtabs %}


# Docker

Run Remote.It in Docker — the remoteit-agent image based on OpenWRT, and the Alpine-based Docker Desktop Extension that talks to the Docker daemon.

Docker is already well known for its application on desktops and servers. More and more devices are also supporting Docker in their environments. This can greatly simplify the installation and upgrade of Remote.It.

Our first implementation of Remote.It on Docker was based on the OpenWRT docker image with our Remote.It Device Package installed. This is called the "remoteit-agent".

Our second implementation was a Docker Desktop Extension. Our Remote.It Docker Extension is based on the Alpine image and not only has the Remote.It Device Package installed, but it also has a node application that communicates with the Docker Daemon.

Here is an illustration of an environment which has a Docker container with a web server, database, Redis, and Remote.It agent installed.

<figure><img src="/files/Dta7c9pTDcVmfRU9c1gq" alt="Docker environment diagram showing web server, database, Redis and Remote.It agent containers"><figcaption></figcaption></figure>


# Remote.It Agent

Run the Remote.It Device Package inside a Docker container with the remoteit-agent image, including the settings needed for a recoverable production deployment.

The [RemoteIt Agent](https://hub.docker.com/r/remoteit/remoteit-agent) docker image is the Remote.It [Device Package](/software/device-package) running inside a Docker container.

### Running the container in a development environment:

Get your registration code docker command from [app.remote.it ](https://app.remote.it)or Remote.It Desktop by clicking on the "Add Device" button in the left nav and then selecting "Docker" which is in the Add a device. Example below:

{% code overflow="wrap" lineNumbers="true" %}

```bash
docker run -d -e R3_REGISTRATION_CODE="<registration_code>" remoteit/remoteit-agent:latest
```

{% endcode %}

This will run a basic Remote.it agent and automatically register it to your Remote.it account based on the registration code.

The command is sufficient for testing but should not be used in a Production environment. There are a few other docker settings to add in order to make this container recoverable so it can be restarted without losing your configuration.

The Remote.it Agent uses a file to keep track of this device's metadata information as well as connection info. In order to maintain this configuration, there are a few more docker settings that need to be set so that when you stop and start the Remote.it Agent container, it comes back as the already registered device. We'll start off with a full production example and explain the different options in the command.

```
docker run \
  -d \
  --name myname \
  --hostname myname \
  -v $PWD/myname:/etc/remoteit \
  -e R3_REGISTRATION_CODE="<registration_code>" \
  --restart unless-stopped \
  remoteit/remoteit-agent:latest
```

This is a breakdown of the command:

* **-d** = Run this container in detached mode in the background.
* **--name myname** = This sets the container name. Otherwise a name is generated for you.
* **--hostname myname** = This sets the hostname within the container. The hostname is used by the Remote.It Agent to set the Device Name during registration.
* **-v $PWD/myname:/etc/remoteit** = The path on the Docker host that will be mapped to the /etc/remoteit folder within the container. Anything written to the /etc/remoteit folder in the container will show up on the Docker host. When you stop or kill the container, you can restart it and the Remote.it Agent will find the existing /etc/remoteit/config.json.
* **-e R3\_REGISTRATION\_CODE="\<registration\_code>"** = This is your registration\_code that you can get from the Remote.it Desktop by clicking on the + sign in the Device list and selecting "Docker" from the "Add a Device" section.
* **--restart unless-stopped** = This insures that the remoteit-agent docker container restarts after a shutdown of the docker daemon such as a power on/off or reboot of the docker host.


# Remote.it Docker Extension

Install the Remote.It Docker Extension from Docker Desktop, or run the same image as a standalone container on a server or Raspberry Pi.

The [Remote.it](https://www.remote.it) Docker Extension is a docker image.

You can install this docker image in two ways:

* Docker Extension
* Docker Container

### Docker Extension

1. Open your Docker Dashboard from your Docker Desktop app
2. Go to the Extensions menu item on the left side
3. Click on the "Add Extensions" menu item
4. In "Browse" search bar enter "Remote.It"
5. Select the "Remote.It" extension
6. Click on "Install" and then "Open" after the Remote.It Docker Extension is installed
7. Click on "Get Registration Code" and log into your RemoteIt account that you want to register this device with
8. Once you have logged in you will see it generate a registration code and ask you to open Docker Desktop
9. Once you get back to Docker Desktop the new registration code should be automatically populated for you
10. Just click the "Register" button

### Docker Container

You can run this same image on server-based docker hosts that do not have the Docker Desktop installed. For example, you could install this on a Raspberry Pi running just the Docker daemon. In order to do that you can run the following command:

```
docker run \
  -d \
  --name myname \
  --hostname myname \
  -e R3_REGISTRATION_CODE="<registration_code>" \
  -v $PWD/myname:/etc/remoteit \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --restart unless-stopped \
  remoteit/docker-extension
```

This is a breakdown of the command:

* **-d** = run this container in detached mode in the background.
* **--name myname** = This sets the container name. Otherwise a name is generated for you.
* **--hostname myname** = This sets the hostname within the container. The hostname is used by Remote.it to set the Device Name during registration.
* **-e R3\_REGISTRATION\_CODE="\<registration\_code>"** = This is your registration\_code that you get from the Remote.it Desktop by clicking on the + sign in the Device list and selecting "Docker" from the "Add a Device" section.
* **-v $PWD/myname:/etc/remoteit** = The path on the Docker host that will be mapped to the /etc/remoteit folder within the container. Anything which is written to the /etc/remoteit folder in the container will show up on the Docker host. When you stop or kill the container, you can restart it and the Remote.it Agent will find the existing /etc/remoteit/config.json.
* ***-v /var/run/docker.sock:/var/run/docker.sock*** = Mount the docker socket inside the container.
* **--restart unless-stopped** = Insures that the remoteit-agent docker container restarts after a shutdown of the docker daemon such as a power on/off or reboot of the docker host.


# Desktop

The Remote.It Desktop application installs the full ecosystem and provides a UI to configure devices, manage services and make connections.

The Desktop Application installs all of the components of the remoteit ecosystem and provides a UI to configure and connect to devices to which you have access.


# Desktop Installation

Download and install the Remote.It Desktop application for Windows, macOS and Linux to manage devices, services and connections from a single UI.

Please see our [downloads page](https://link.remote.it/download/desktop) for a complete list of all of the supported platforms and architectures

## Usage

For more on the Desktop application please visit the [User Documentation](https://support.remote.it/hc/en-us/sections/360010275391-remote-it-Desktop-for-Windows-macOS-and-Linux) website.


# Web Portal & Mobile

Manage devices, view logs and run bulk scripts from the Remote.It web portal, or connect to SSH, RDP and web services from the iOS and Android apps.

### Web Portal

Access your device list, logs, define products for OEM registration and execute bulk scripting from our web app at <https://app.remote.it>

### Mobile Apps

Access SSH, RDP, web services and more on the go from your mobile devices. Remote.it offers iOS and Android apps.

{% embed url="<https://itunes.apple.com/us/app/remote-it/id1437569166>" %}

{% embed url="<https://play.google.com/store/apps/details?id=com.remoteit>" %}


# Custom Solutions

Remote.It supports platforms beyond the standard packages — Ansible automation, side-loaded Android, Dragino LoRaWAN routers and custom builds.

## Not finding your platform?

We promote the most common requested **installation packages** but that doesn't mean we don't support what you already have. If you're looking for more \*nix based packages or custom networking solutions to include in your product please contact us at <support@remote.it> and we'll schedule a chat with our engineers.

Not just operating systems and architectures -

We have built support for Ansible automation, side loading android devices, dragino LORAWAN routers and more!


# Services

A Remote.It service maps an application, port and host address on a target device so you can reach it remotely. Learn the attributes of a service.

A configuration registered on the [target device](https://support.remote.it/hc/en-us/articles/360051286351-Glossary-of-Terms#h_01FMR1CAQ6AGF2077RXY49FTSX) which you will use to access remote [applications](https://support.remote.it/hc/en-us/articles/360051286351-Glossary-of-Terms#h_01FMR1FGMKVJ6ZB9X3DQ8RJ133). The target device can have many services. There is a bulk service created by default and does not require entry of any service attributes. The bulk service provides the basis for a target device and enables scripting functionality.*Attributes of a service:*

* Application Type: The application mapped to this service i.e. SSH, VNC, RDP, HTTP/S
* Port: The port on the target device which the application is listening
* Service host address: Local network IP address or fully qualified domain name to host this service
* Enabled: Whether or not the remote.it service is available for connections. You may want to disable this and enable it only when needed if you are concerned with bandwidth like on a cellular internet connection
* Status: This is online/offline status of the remote.it service.


# SSH

Connect over SSH to devices behind NAT, CGNAT or a firewall with no port forwarding — auto-launching Terminal, PuTTY or Termius from Remote.It.

Remote.it has a pre-built service to connect to SSH on devices behind NAT to perform any function on the terminal.

Create and enable your service then use your favorite app to connect. SSH will auto-launch to the terminal (Linux/MacOS), putty (windows), terminus (mobile) if installed.

<figure><img src="/files/HsP5ycC9mArOEz5WXJfg" alt="Creating an SSH service in the Remote.It Desktop application"><figcaption></figcaption></figure>


# RDP and VNC

Set up Remote.It RDP and VNC services to reach a remote desktop across NAT using the remote desktop clients you already use.

Remote.it has pre-built service types for RDP and VNC to connect over NAT. Confirm RDP and VNC servers are running on the remote device [first](https://support.remote.it/hc/en-us/articles/360044517231-Control-your-Windows-Device-Remotely-Windows-to-Windows-), add your service with the configurations below and you'll be able to connect with the applications you already use.

## RDP

<figure><img src="/files/SVL1VHtGr8lBSK5gHTX5" alt="Remote.It RDP service configuration showing the default port 3389"><figcaption></figcaption></figure>

## VNC

<figure><img src="/files/Q6eRLFmx8E6P8iEOrrng" alt="Remote.It VNC service configuration showing the default port 5900"><figcaption></figcaption></figure>


# SMB and CIFS

Reach SMB and CIFS network file shares remotely as if you were on the same LAN, by adding a Remote.It service to the device hosting the shared folders.

Local network file shares can be done privately and consistently. Add the service to the device hosting the shared drives or folders and connect as if it was on the same LAN.

<figure><img src="/files/jHBgppS6YDtYd2pZYF5K" alt="Remote.It SMB service configuration showing the default port 445"><figcaption></figcaption></figure>


# HTTP/S

Host a private website or API behind NAT and reach it through a Remote.It HTTP/S service pointed at the port your web server is listening on.

Host a private website or api behind NAT and build your HTTP/S service as below given the remote port the server is listening on.

<figure><img src="/files/WVxQMIsiwens6ezLyFSE" alt="Remote.It HTTP/S service configuration showing the web server port"><figcaption></figcaption></figure>


# Database

Query remote databases securely over Remote.It — Microsoft SQL on port 1433 by default, or any database reachable on a TCP port via the service host address.

If you install Remote.it directly onto the server hosting your database the below is the needed setup on port 1433 as the default port for Microsoft SQL. This connection type will support any database given the correct port.

If running a database on another device or as a service you change the Service Host Address with the fully qualified domain name.

<figure><img src="/files/27aXUhPJdovYVfGke1jk" alt="Remote.It database service configuration showing port 1433 for Microsoft SQL"><figcaption></figcaption></figure>


# Redis

Connect to a remote Redis instance on port 6379 through Remote.It, or any other cache service listening on a TCP port.

If you install Remote.it directly onto the server hosting redis the below is the needed setup on port 6379. This works for other cache services so long as they listen on a particular TCP port.

If running redis on another device or as a service you change the Service Host Address with that fully qualified domain name.

<figure><img src="/files/gdkQE03eUx3RSQjWymx1" alt="Remote.It Redis service configuration showing the default port 6379"><figcaption></figcaption></figure>


# UDP

Create a Remote.It UDP service on any port you need. There is no default service port for UDP — you specify the one your application listens on.

You can create a UDP service to any port where needed. Remote.it does not provide a default service port.

<figure><img src="/files/LCTju0WawwkixXuzZnRf" alt="Remote.It UDP service configuration with a user-specified port"><figcaption></figcaption></figure>


# VPN

Register one or more VPN services on a device to reach multiple VPNs through Remote.It without constantly reconnecting and disconnecting.

remote.it has default service configurations for some of the most popular VPN solutions. Registering 1 or more VPN services on a device allows you to access multiple VPNs without constantly reconnecting and disconnecting.

<figure><img src="/files/oJ2Deglb0MlZGL2Urcxg" alt="Remote.It VPN service configuration with presets for popular VPN solutions"><figcaption></figcaption></figure>


# Connection Options

Ways to route a Remote.It connection — peer-to-peer, proxy, LAN sharing, and jump services that reach devices where Remote.It isn't installed.

Remote.It offers several ways to reach a target service, depending on where the device sits and who needs access.

* [**LAN Sharing**](/features/connection-options/lan-sharing) — share a peer-to-peer connection with others on your local network, scoped to a single IP or a range.
* [**Jump Service**](/features/connection-options/jump-service) — reach TCP services on other devices on the same LAN without installing Remote.It on each one.
* [**Peer-2-Peer & Proxy**](/features/connection-options/peer-2-peer-and-proxy) — the two underlying routing methods, and when each applies.


# LAN Sharing

Share a Remote.It peer-to-peer connection with others on your local network, scoped to a single LAN address or a range of IPs.

{% hint style="info" %}
**Detailed use guide on LAN Sharing:**

<https://link.remote.it/support/lan-sharing>
{% endhint %}

LAN (Local Area Network) sharing allows you to share a Remote.It peer to peer connection to a remote service with someone else on the same LAN where you are currently located.

Sharing a service across your local network is a great easy way to reduce time spent setting up additional machines and users with their own accounts. The share is done on a specific service and you can control who can access it. Either specifically to a single LAN address or to a range of IPs.

Secure it for your private network and hide from your guest network.

<figure><img src="https://support.remote.it/hc/article_attachments/360060235011/lan_sharing_1.png" alt="Diagram of a Remote.It LAN share reaching multiple devices on a local network"><figcaption></figcaption></figure>

With remote.it installed anywhere on the network you have the control to share it with specific IP, a range of IPs, or everyone on the LAN.


# Jump Service

Use one device as a jump box to reach TCP services on other devices on the same LAN — printers, appliances or an AWS VPC — without installing Remote.It on each.

You can use the Remote.It application running on one device to access TCP services on other devices on the same LAN, without needing to install remoteit on those other devices. This is sometimes referred to as a **jump service/box.**

Best practice is to install remoteit on a device that will be available at all times. This is ideal in an AWS environment to have a since EC2 instance act as the gateway into the VPC.

This is typically done when the targeted resource is not compatible with Remote.It and it cannot be installed (e.g. a printer, hosted resources). [Learn more about jump services here.](https://link.remote.it/support/jumpbox)

For a step-by-step walkthrough aimed at non-technical users, see [Remote Access Over Starlink](/introduction/get-started/starlink) — it sets up a jump service to reach cameras and DVRs behind CGNAT.


# Peer-2-Peer & Proxy

How Remote.It peer-to-peer and proxy connections differ, and when each routing method is used.

{% hint style="info" %}
Check back soon, documentation for this is still being generated

See our [support guides](https://support.remote.it/hc/en-us/articles/360044788252-Peer-to-Peer-vs-Proxy-Connections) for an overview on this topic
{% endhint %}


# Logging

Event logging in Remote.It — audit device, service and connection activity across your account.

{% hint style="info" %}
Check back soon, documentation for this is still being generated
{% endhint %}


# Organizations

Create a Remote.It organization to share devices with your team, manage seat licenses and member roles, and integrate SAML single sign-on.

For all levels of plans you can now create your own Organization and invite members to immediately collaborate and share all your devices. An Organization owner can purchase additional seats and assign them to members. This allows members to get access to all devices owned by the Organization. [Learn more about Organizations here.](https://link.remote.it/support/organizations)

## SAML Integration

Remote.It can manage user logins for your users using a SAML integration. [Learn more about it here.](https://link.remote.it/support/organizations-saml)

## Manage Access

You can change the number of user licenses at any time to scale your team.

Invite Licensed members to have access to the complete device list.

Invite Unlicensed members to have access to the first 5 devices in the account.

[Learn more about member roles and custom roles here.](https://link.remote.it/support/organization-custom-roles)

<figure><img src="/files/xKP1KQKuMNYPw0VNINF6" alt="Organization members list showing licensed and unlicensed member roles"><figcaption></figcaption></figure>

## Access

Quickly switch between your personal device list and organizations without logging out so all connections stay online.

<figure><img src="/files/ER8wSXFtPYpu2Y64mbNT" alt="Switching between a personal device list and an organization without logging out"><figcaption></figcaption></figure>


# Authentication

Authenticate to the Remote.It GraphQL API using HTTP Request Signature with non-expiring access keys you can revoke at any time.

The GraphQL API requires authentication for requests. Remote.It authentication uses HTTP Request Signature. The advantages of this method are:

* Keys do not expire
* Keys can be disabled and revoked (deleted) by the user at any time
* Keys are not dependent on password
* Keys are more secure (the secret is never transmitted because the request is signed)

{% hint style="danger" %}
**With 2FA enabled,** you'll need to provide an authentication code when accessing Remote.It through your browser, desktop and mobile apps. If you access Remote.It using other methods, such as the the CLI, you'll need to sign in with credentials using and access key and secret.
{% endhint %}

## Key Management

You can generate, enable, disable and delete keys in the Account section of the web portal here <https://app.remote.it/#/account/accessKey>.

{% hint style="warning" %}
***Please note: Generation of keys is crypto-random and the secret is only available immediately after creation by clicking the “Show secret access key” link or downloading the key as a CSV file (containing the Access Key ID and Secret Access Key)***
{% endhint %}

You are limited to 2 active access keys. The account page will also show when the key was created and last used for authentication. If you suspect your key has been compromised, generate a new one, replace it in your code and disable it. If desired you can delete the compromised key after disabling it.

In addition, if you will be using the REST-API you will also need to retrieve your Developer API Key. This can also be found in the Account section of the web portal.

### Create a remote.it Credentials File

You will need to follow the steps above with Key Management to generate your access key and secret before proceeding. Then, create a file to save your Remote.It credentials. The file name should be **credentials** with no extension. The folder depends on your operating system.

<table><thead><tr><th width="193.02230015369736">Operating System</th><th>Folder</th></tr></thead><tbody><tr><td>Linux/macOS</td><td>~/.remoteit (in your home directory)</td></tr><tr><td>Windows</td><td>C:\Users\[your Windows user name]\.remoteit</td></tr></tbody></table>

The file is in the standard ini file format:

```
[DEFAULT]
R3_ACCESS_KEY_ID=Z5QCS6ZO7PXXXMVDNXXX
R3_SECRET_ACCESS_KEY=XXXWC14Qsktnq/nbF+iXxXq2yc4sVPkQn3J0m5i
R3_DEVELOPER_API_KEY=XXXXXXX
```

You can save more than one key pair under different profiles (sections) in the Remote.It credentials file. DEFAULT is the default profile name. Profiles name is case sensitive and should not have a "." in the name.

## API Request Signing

{% hint style="danger" %}
**Timezones**

Request signing is done for each request independently and is sensitive to clock drift based on the system time of the machine making the API call.

Best practice is to use **UTC or GMT** when using the signature methods to avoid ambiguous time zones when dates are generated by your code.
{% endhint %}

To authenticate an API request, the client must generate a signature using the previously created key and secret. The REST-API example you will also need your Developer API Key which you can get from your account page <https://app.remote.it/#account>

### Examples

{% hint style="warning" %}
These are examples of query requests only for the purposes of how to do the request signing. Please refer to the schema and usage documentation for requests which are supported.
{% endhint %}

{% tabs %}
{% tab title="bash/cURL" %}
The examples reads the \~/.remoteit/credentials file for the variables of your access key, secret, and developer key.

```bash
#!/bin/bash
source ~/.remoteit/credentials

SECRET=`echo ${R3_SECRET_ACCESS_KEY} | base64 --decode`

HOST="api.remote.it"
URL_PATH="graphql/v1"
URL="https://${HOST}/${URL_PATH}"

VERB="POST"

CONTENT_TYPE="application/json"

LC_VERB=`echo "${VERB}" | tr '[:upper:]' '[:lower:]'`

DATE=$(LANG=en_US date -u "+%a, %d %b %Y %H:%M:%S %Z")

DATA='{ "query": "{ login { email  devices (size: 1000, from: 0) { items { id name services { id name} } } } }" }'

SIGNING_STRING="(request-target): ${LC_VERB} /${URL_PATH}
host: ${HOST}
date: ${DATE}
content-type: ${CONTENT_TYPE}"

echo ${SIGNING_STRING}

SIGNATURE=`echo -n "${SIGNING_STRING}" | openssl dgst -binary -sha256 -hmac "${SECRET}" | base64`

SIGNATURE_HEADER="Signature keyId=\"${R3_ACCESS_KEY_ID}\",algorithm=\"hmac-sha256\",headers=\"(request-target) host date content-type\",signature=\"${SIGNATURE}\""

curl --write-out -v -X ${VERB} -H "Authorization:${SIGNATURE_HEADER}" -H "Date:${DATE}" -H "Content-Type:${CONTENT_TYPE}" ${URL} -d "${DATA}" --insecure
```

{% endtab %}

{% tab title="Node" %}
**GraphQL**

This typescript example shows

1. How to retrieve credentials from the remote.it credentials file using a `default` profile
2. Use `http-signature` client library to Authenticate each request
3. How to query GraphQL using variables and the `https` library

```javascript
import fs from 'fs'
import https from 'https'
import os from 'os'
import path from 'path'
​
import httpSignature from 'http-signature'  // npm install http-signature
import ini from 'ini'                       // npm install ini
​
const R3_ACCESS_KEY_ID = 'R3_ACCESS_KEY_ID'
const R3_SECRET_ACCESS_KEY = 'R3_SECRET_ACCESS_KEY'
​
const CREDENTIALS_FILE = '.remoteit/credentials'
const DEFAULT_PROFILE = 'default'
​
const SIGNATURE_ALGORITHM = 'hmac-sha256'
const SIGNED_HEADERS = '(request-target) host date content-type'
​
const APPLICATION_JSON = 'application/json'
​
const GRAPHQL_HOST = 'api.remote.it'
const GRAPHQL_URL = '/graphql/v1'
​
function getCredentials(profileName = DEFAULT_PROFILE) {
  const file = path.resolve(os.homedir(), CREDENTIALS_FILE)
​
  if (!fs.existsSync(file)) throw new Error(`remote.it credentials file not found: ${file}`)
​
  const credentials = ini.parse(fs.readFileSync(file, 'utf-8'))
​
  const profile = Object.entries(credentials).find(([name]) => name.toUpperCase() === profileName.toUpperCase())
​
  if (!profile) throw new Error(`remote.it profile not found: ${profileName}`)
​
  const [_, section] = profile
​
  const keyId = section[R3_ACCESS_KEY_ID]
​
  if (!keyId) throw new Error(`remote.it credentials missing: ${R3_ACCESS_KEY_ID}`)
​
  const secret = section[R3_SECRET_ACCESS_KEY]
​
  if (!secret) throw new Error(`remote.it credentials missing: ${R3_SECRET_ACCESS_KEY}`)
​
  return {keyId, secret}
}
​
async function graphql(keyId, secret, query, variables) {
  const body = JSON.stringify({query, variables})
​
  const options = {
    host: GRAPHQL_HOST,
    port: 443,
    path: GRAPHQL_URL,
    method: 'POST',
    headers: {
      'Content-Type': APPLICATION_JSON
    },
    body
  }
​
  return new Promise((resolve, reject) => {
    const request = https.request(options, response => {
      response.on('data', json => resolve(JSON.parse(json)))
    })
​
    httpSignature.sign(request, {
      keyId,
      key: Buffer.from(secret, 'base64'),
      algorithm: SIGNATURE_ALGORITHM,
      headers: SIGNED_HEADERS.split(/\s+/)
    })
​
    request.on('error', error => reject(error))
​
    request.write(body)
    request.end()
  })
}
​
(async () => {
  try {
    const query = 'query TestQuery($id: String!) {' +
      '  login {' +
      '    device(id: [$id]) {' +
      '      name' +
      '      endpoint {' +
      '        timestamp' +
      '        state' +
      '        externalAddress' +
      '      }' +
      '    }' +
      '  }' +
      '}'
​
    const variables = {
      id: '80:00:00:00:01:02:03:04'
    }
​
    const {keyId, secret} = getCredentials()
​
    const result = await graphql(keyId, secret, query, variables)
​
    console.log(JSON.stringify(result, null, 2))
  } catch (error) {
    console.error(error)
  }
})()
```

{% endtab %}

{% tab title="Python 3" %}
This example is using a helper library `requests_http_signature==v0.7.1` for Python 3 which will sign the request before submitting it to the server. This demonstrates how to safely reference the key and secret from the \~/.remoteit/credentials file.

Reference functions create a connection and have a disconnect.

```
import configparser
import json
import os.path
from base64 import b64decode

import requests
from requests_http_signature import HTTPSignatureAuth, algorithms

# File and URL Constants
CREDENTIALS_FILE = "~/.remoteit/credentials"
REMOTEIT_URL = 'https://api.remote.it/graphql/v1'


def remoteit_authorizer(profile="DEFAULT"):
    """Authorize remote.it API access using credentials from a file.

    Args:
        profile (str, optional): Profile name in credentials file. Defaults to "DEFAULT".

    Returns:
        HTTPSignatureAuth: Auth object to be used in requests.
    """
    # Resolve the full path for the credentials file
    file = os.path.expanduser(CREDENTIALS_FILE)

    # Check if the file exists
    if not os.path.exists(file):
        raise FileNotFoundError(f"remote.it credentials file not found: {file}")

    # Parse the credentials file
    config = configparser.ConfigParser()
    try:
        config.read(file)
    except Exception as e:
        raise Exception(f"remote.it credentials file error: {e}")

    # Fetch credentials for the selected profile
    credentials = config[profile]

    # Validate existence of required keys
    key_id = credentials.get('R3_ACCESS_KEY_ID')
    key = credentials.get('R3_SECRET_ACCESS_KEY')
    if not key_id or not key:
        raise Exception("Missing required credentials")

    # Create and return auth object
    return HTTPSignatureAuth(key_id=key_id, key=b64decode(key), signature_algorithm=algorithms.HMAC_SHA256)


def remoteit_api(auth, query, variables=None):
    """Send a GraphQL query to remote.it API.

    Args:
        auth (HTTPSignatureAuth): Auth object.
        query (str): GraphQL query string.
        variables (dict, optional): Variables for the GraphQL query. Defaults to None.

    Returns:
        dict: Parsed JSON response from the API.
    """
    response = requests.post(REMOTEIT_URL, json={"query": query, "variables": variables}, auth=auth)
    if response.status_code != 200:
        raise Exception(f"remote.it API error: {response.status_code}")
    return json.loads(response.text)


def connect(auth, service_id):
    """Connect to a remote.it service and return session details.

    Args:
        auth (HTTPSignatureAuth): Auth object.
        service_id (str): The service ID.

    Returns:
        tuple: Session ID, host, and port.
    """
    query = "mutation connect($id: String!) {connect(serviceId: $id) {id host port}}"
    response = remoteit_api(auth, query, variables={"id": service_id})
    connection = response["data"]["connect"]
    return connection["id"], connection["host"], connection["port"]


def disconnect(auth, session_id):
    """Disconnect a remote.it session.

    Args:
        auth (HTTPSignatureAuth): Auth object.
        session_id (str): The session ID to disconnect.

    Returns:
        bool: True if successful, False otherwise.
    """
    query = "mutation disconnect($id: String!) {disconnect(connectionId: $id)}"
    response = remoteit_api(auth, query, variables={"id": session_id})
    return response["data"]["disconnect"]


# Example usage
if __name__ == "__main__":
    # Initialize authorizer
    authorizer = remoteit_authorizer()

    # Connect to a service
    service_id = "80:XX:XX:XX:XX:XX:XX:XX"
    session_id, host, port = connect(authorizer, service_id)
    print(f"Connected: session_id={session_id}, host={host}, port={port}")

    # Disconnect from the service
    status = disconnect(authorizer, session_id)
    print(f"Disconnected: {status}")
```

{% endtab %}

{% tab title="C#" %}
This example is a port of the bash/cURL example assuming a C# program and that you have stored your credentials in a file as indicated from the credential file generation and only ONE profile. If there is more than one, it will use the first. You could change this to load them from an environment variable instead.

```csharp
using System.Security.Cryptography;
using System.Text;

class Program
{
	const string credsFile = ".remoteit/credentials";
	class KeyAndSecret
	{
		public bool HasError;
		public string Error;
		public string Key;
		public string Secret;
	}

	private static async Task Main()
	{
		KeyAndSecret keyAndSecret = readKeyAndSecret();
		if (keyAndSecret.HasError)
		{
			Console.WriteLine(keyAndSecret.Error);
			return;
		}

		string host = "api.remote.it";
		string urlPath = "/graphql/v1";  // Ensure proper formatting with a trailing slash
		string url = $"https://{host}{urlPath}";
		string verb = "POST";
		string contentType = "application/json";
		string date = DateTime.UtcNow.ToString("r"); // RFC 1123 format

		string data = "{ \"query\": \"{ login { email  devices (size: 1000, from: 0) { items { id name services { id name} } } } }\" }";
		// string data = "{\"query\":\"{ applicationTypes { id name description port proxy protocol } }\"}";

		// line to sign
		string lineToSign = $"(request-target): {verb.ToLower()} {urlPath}\n"
			+ $"host: {host}\n"
			+ $"date: {date}\n"
			+ $"content-type: {contentType}\n"
			+ $"content-length: {data.Length}";

		byte[] signedLine = generateSignature(lineToSign, keyAndSecret.Secret);
		string signedLineAsBase64 = Convert.ToBase64String(signedLine);

		// signature line
		string signatureLine = $"keyId=\"{keyAndSecret.Key}\""
			+ $",algorithm=\"hmac-sha256\""
			+ $",headers=\"(request-target) host date content-type content-length\""
			+ $",signature=\"{signedLineAsBase64}\"";

		// create HTTP request
		var content = new StringContent(data, Encoding.UTF8, contentType);
		content.Headers.Remove("Content-Type");
		content.Headers.Remove("Content-Length");
		content.Headers.Add("Content-Type", contentType);
		content.Headers.Add("Content-Length", data.Length.ToString());

		HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
		request.Headers.Add("User-Agent", "sample-sdk-c#");

		request.Headers.Add("Date", date);
		request.Headers.Add("Authorization", "Signature " + signatureLine);
		request.Content = content;

		// execute + read response
		var client = new HttpClient();
		HttpResponseMessage response = await client.SendAsync(request);
		string responseBody = await response.Content.ReadAsStringAsync();

		Console.WriteLine("\nResponse: {0}", response.ToString());
		Console.WriteLine("\nResponse Body: {0}", responseBody);
	}

	private static byte[] generateSignature(string lineToSign, string secret)
	{
		byte[] secretAsBytes = Convert.FromBase64String(secret);
		using (var hmac = new HMACSHA256(secretAsBytes))
		{
			byte[] lineToSignAsBytes = Encoding.UTF8.GetBytes(lineToSign);
			return hmac.ComputeHash(lineToSignAsBytes);
		}
	}

	private static KeyAndSecret readKeyAndSecret()
	{
		//Reads the credentials from the credentials file. If there is more than one, it will take the last; or you can read from environment variables instead.
		string homeFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
		string credentialsPath = Path.Combine(homeFolder, credsFile);
		if (!File.Exists(credentialsPath))
		{
			return new KeyAndSecret { HasError = true, Error = "err: credentials file not found" };
		}

		var credentials = File.ReadAllLines(credentialsPath);
		string accessKeyId = "";
		string secretAccessKey = "";
		//assumes that there is one profile. If you have more than one, adapt this part as needed. 	
		bool accessKeyFound = false;
		bool secretKeyFound = false;	

		foreach (var line in credentials)
		{
			if (line.StartsWith("R3_ACCESS_KEY_ID="))
			{
				accessKeyId = line.Split(new char[] { '=' }, 2)[1];
				accessKeyFound = true;
			}
			else if (line.StartsWith("R3_SECRET_ACCESS_KEY="))
			{
				secretAccessKey = line.Split(new char[] { '=' }, 2)[1];
				secretKeyFound = true;
			}
	
			if (accessKeyFound && secretKeyFound)
				break;
		}

		if (string.IsNullOrEmpty(accessKeyId) || string.IsNullOrEmpty(secretAccessKey))
		{
			return new KeyAndSecret { HasError = true, Error = "err: missing API credentials in the credentials file" };
		}

		return new KeyAndSecret { Key = accessKeyId, Secret = secretAccessKey };
	}
}
```

{% endtab %}

{% tab title="Other Languages" %}
You can reference different standard implementations of the signature in different languages from w3c-ccg <https://github.com/w3c-ccg/http-signatures/issues/1>
{% endtab %}
{% endtabs %}


# API

Use Remote.It APIs to manage devices, services, connections and event logs in code, with GraphQL coverage supplemented by the legacy REST API.

remote.it is powered by a robust set of APIs that allow you to do anything via an API that you can do with our [web portal](https://app.remote.it), desktop or mobile applications.

Below are pages documenting our graphQL API. It is best to start with the authentication docs since the API requires you to authenticate. GraphQL is a data query language for API's, developed by Facebook in 2012 before being publicly released in 2015. GraphQL provides an alternative to the REST API.

For more information on GraphQL, learn on the official GraphQL website [**here.**](https://graphql.org/)


# Using Developer Tools

There are multiple developer tool IDEs such as Insomnia, Postman, and Altair. Here are examples using Insomnia and Postman.

Insomnia and Postman are API request IDEs and a sample collection is provided for both tools to get you started. Insomnia also has a remote.it plugin available to assist with authentication to allow you to experiment before you develop code.

\
For graphQL, you can explore the schema, generate queries and mutations.\
For the REST-API, you can create http requests.

## Insomnia Set Up

### Download and Install Insomnia

{% embed url="<https://insomnia.rest/>" %}

It is recommended that you install Insomnia Core rather than Insomnia Designer, but the plugin should work for both versions.

### Add the Plugin to Insomnia

We will be using a remote.it provided plugin to create queries which will automatically sign the requests.

Go to preferences:

<figure><img src="/files/-M_vMHwNHA2JpjNFBznA" alt="The Insomnia preferences menu where the Remote.It authentication plugin is installed"><figcaption></figcaption></figure>

Enter insomnia-plugin-remoteit and click *Install Plugin*

### Remote.it Insomnia Collection

We have developed an example set of GraphQL queries and mutations in a collection that you can import directly into insomnia to get started. You will still need to install the authentication plug-in [here](#add-the-plugin-to-insomnia) and [create your access keys](/developer-tools/api/usage/access-keys) in your account before getting started.

{% embed url="<https://raw.githubusercontent.com/remoteit/code_samples/refs/heads/main/api_tools/Remoteit_Prod_Insomnia.json>" %}
Remote.It Insomnia Collection
{% endembed %}

You can download all our examples here:

```
$ git clone https://github.com/remoteit/code_samples.git
```

The collection is found in the api\_tools folder.

Here is a quick overview of the UI once you have imported the collection

<figure><img src="/files/xl38waV8HsA6F6NhXpip" alt="The Insomnia interface after importing the Remote.It GraphQL collection"><figcaption></figcaption></figure>

{% hint style="warning" %}
If you want to start using the API requests in your code, you cannot use the generated code out of Insomnia as the generated signature is only good for that specific request. You will need to use the http request signing methodology. Some examples can be found on the [authentication page](/developer-tools/authentication#examples).
{% endhint %}

### Building a graphQL request on your own

Make sure to create a ***POST*** request and select ***GraphQL Query*** as Body type. NOTE: All graphQL queries and mutations are made with **POST**

You can type a sample GraphQL query to <https://api.remote.it/graphql/v1> like:

```
{
  login {
    email
  }
}
```

If you haven't already set up your machine with the credentials file, see [here](/developer-tools/authentication) and do so now.

Select the ***Auth*** tab of the query and select ***Bearer Token*** authentication.

<figure><img src="/files/SPwKhPTYAhCjPSJcTnmI" alt="The Insomnia Auth tab with Bearer Token authentication selected"><figcaption></figcaption></figure>

Click on th&#x65;***Token*** field and `CTRL+Space`to select the ***remote.it API authentication*** tag, and select a specific profile otherwise the default profile will be used.

<figure><img src="/files/oc8MafjYGD9ybBkJGUkp" alt="Selecting the Remote.It API authentication tag in the Insomnia Token field"><figcaption></figcaption></figure>

You now can send the request and execute the query using the credentials stored earlier.

### Using graphQL in your application

Once you have your query or your mutation working as you expect, then you can work to integrate it into your application. Examples of request signing can be found [here](/developer-tools/authentication#api-request-signing).

## Postman Set Up

### Download and Install Postman

{% embed url="<https://www.postman.com>" %}
These instructions have been written using Version 11.2.1
{% endembed %}

### Remote.it Postman Collection

We have developed an example set of GraphQL queries and mutations in a collection that you can import directly into Postman to get started. Be sure to set up your environment variables before using these.

```
$ git clone https://github.com/remoteit/code_samples.git
```

The collection is found in the api\_tools folder

#### Import the environment and collection

You will need to import both the environment file and the collection file.

Update the environment variable values (R3\_ACCESS\_KEY\_ID, R3\_DEVELOPER\_API\_KEY, and R3\_SECRET\_ACCESS\_KEY) retrieved from your [credentials file](https://docs.remote.it/developer-tools/api/pages/-M_b0yOVV0jMMRYgCl2N#create-a-remote.it-credentials-file) into the Current value field and then **"Save"** at the top of the variables list.

<figure><img src="/files/8lb86trqOnxAPDkH2GAQ" alt="Postman environment variables for the Remote.It access key, developer API key and secret"><figcaption></figcaption></figure>

This is a quick overview of the UI. Please refer to the Postman documentation if yours doesn't look the same as versions may change.

<figure><img src="/files/owrLCGJnAMRxYIbOkKbg" alt="The Postman interface running a Remote.It GraphQL query from the imported collection"><figcaption></figcaption></figure>

{% hint style="warning" %}
If you want to start using the API requests in your code, you cannot use the generated code out of Insomnia as the generated signature is only good for that specific request. You will need to use the http request signing methodology. Some examples can be found on the [authentication page](/developer-tools/authentication#examples).
{% endhint %}

### Building a graphQL request on your own

A Pre-request Script is required which handles the request signing. The script can be found in the Collection, under the main folder. Any new requests that you create under this collection should inherit this script.

<figure><img src="/files/0PXZNfezco4ZARxcBGGs" alt="The Postman Pre-request Script that signs Remote.It GraphQL requests"><figcaption></figcaption></figure>

Make sure to create any new request as a ***POST*** request and select ***GraphQL Query*** as Body type. and use your variable for the url. NOTE: All graphQL queries and mutations are made with **POST**

You can type a sample GraphQL query to <https://api.remote.it/graphql/v1> like:

```
{
  login {
    email
  }
}
```

If you haven't already set up your machine with the credentials file, see [here](/developer-tools/authentication) and do so now.

### Using graphQL in your application

Once you have your query or your mutation working as you expect, then you can work to integrate it into your application. Examples of request signing can be found [here](/developer-tools/authentication#api-request-signing).


# API Usage

Get started with the Remote.It GraphQL API — endpoint, authentication, the Insomnia sample collection, and how GraphQL replaces the legacy REST API.

remote.it is in the process of making available all functions in graphQL and will be eventually deprecate the REST-API. This documentation provides the REST-API where the function is not available via graphQL.

## Remote.it Insomnia Collection

We have developed an example set of GraphQL queries and mutations in a collection that you can import directly into insomnia to get started. You will still need to install the authentication plug-in [here](/developer-tools/api/using-developer-tools#add-the-plugin-to-insomnia) and create your access keys in your account before getting started.

```
$ git clone https://github.com/remoteit/code_samples.git
```

## What is GraphQL?

GraphQL is a data query language for API's, developed by Facebook in 2012 before being publicly released in 2015. GraphQL provides an alternative to the REST API.

For more information on GraphQL, learn on the official GraphQL website [**here.**](https://graphql.org/)

## How to Access GraphQL

`https://api.remote.it/graphql/v1` Continue through this documentation to learn about our schema and some useful examples.

remote.it authentication uses HTTP Request Signature; more on Authentication can be found [here](/developer-tools/authentication).

### GraphQL Clients (Developer Tools)

These are some of the most popular developer tools used with GraphQL API's which you can use to explore the schema.

* [**Insomnia**](https://insomnia.rest/graphql/)
* [**Postman**](https://www.getpostman.com/)
* [**GraphiQL**](https://www.electronjs.org/apps/graphiql)
* [**Altair**](https://altair.sirmuel.design/)

We provide some basic setup and usage for the Insomnia client [here](/developer-tools/api/using-developer-tools).

You can view our visual schema reference [**here.**](https://api.remote.it/graphql/v1/doc)

### **Schema Definitions**

GraphQL endpoint supports introspection queries via the \_\_schema quer&#x79;**.** There is also a visual version of the schema available at <https://api.remote.it/v1/graphql/doc>

{% hint style="info" %}

#### We recommend using a GraphQL client (Developer Tools) to introspect and explore the schema.

Configure your GraphQL client to use the API endpoint:

`https://api.remote.it/graphql/v1`
{% endhint %}

Schema convention is to use upper camel case for object types and lower camel case for property names.

Note that these objects and parameters are continually enhanced. Please use your IDE for the most up to date schema. The changes are designed to be non-breaking by adding rather than deleting or changing existing definitions.

Basic types are:

* ID (similar to the string type but used for object IDs)
* String
* Int
* Float
* Boolean
* DateTime (ISO 8601 format Date String)

## Queries

Queries are requests which read the data and will not change the data. All queries will be in context of the user associated with the access key and secret. The usage examples include a variable section which will need to accompany the query or alternatively, you can put the values inline.

### Fetching updates

If you're working on building an application which display data and you want the status information to update (near) realtime, use the [webhook](/developer-tools/webhooks). To prevent excessive usage of our API, we recommend that you be mindful about your implementation.

**Do's:**

* Register a programmatic [webhook](/developer-tools/webhooks) and get updates for status changes on your devices. When you detect changes, update the device information

**Dont's:**

* Poll updates for each device. There should never be a reason to do this, unless in small cases and your application might get rate limited. See above tactics to implement this better.

## Mutations

Mutations are requests which update data. All mutations are in context of the user associated with the access key and secret.

In the case where we do not have the functionality supported, the REST-API examples are provided. These will be updated from time to time as remote.it migrates to support graphQL only.

## Pagination

The list responses from the devices and event log queries return paginated results. We implement a pagination model with `from`/`after` and `size` pagination arguments. Responses can return `hasMore`, `last` and `total` . If the `hasMore` response returns true, this indicates do another fetch. In this case, the `from` will increment to 1001 to fetch the next set. You could also determine this by iteration until you get to the `total`. Size is limited to 1000 max in each return.

**Filter**

| Attribute                                       | Data Type | Description                                                                                                                                                                |
| ----------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| size                                            | Int       | Number of records to return in result of items (Max value is 1000)                                                                                                         |
| from                                            | Int       | Where to start return of list if there are more records than the size                                                                                                      |
| last                                            | String    | Primary ID of the item returned to start in the return (If this is passed, from is ignored, however it may not return if the rest of the filters to not include this item) |
| sort                                            | String    | attribute to sort the item list return and append a space + asc or desc for ascending and descending                                                                       |
| additional filters are available per collection |           | See documentation in Schema for complete list as this is updated.                                                                                                          |

```javascript
#Query

query getDevices($size: Int, $from: Int, $sort: String) {
  login {
    devices(size: $size, from: $from, sort: $sort) {
      total
      hasMore
      last
      items {
        id
        name
        hardwareId
        created
        services {
          id
          name
        }
      }
    }
  }
}

#Variables
{
  "size": 1000,
  "from": 0,
  "sort": 'name',
}
```

Result Response

```bash
{
  "data": {
    "login": {
      "devices": {
        "total": 1200,
        "hasMore": true,
        "items": [
          {
            "id": "8X:XX:XX:00:29:01:8e:ed",
            "name": "bento",
            "hardwareId": "dc:a6:32:19:8b:a3-xWoYf46uJ6QdtPXTloLb",
            "created": "2019-12-20T22:13:46.000Z",
            "services": [
              {
                "id": "8X:XX:XX:00:29:01:8e:ed",
                "name": "ssh service"
              }
            ]
          },
        ...
        ]
      }
    }
  }
}    

```

**Response List Attribute**

| Attribute | Data Type | Description                                                                                        |
| --------- | --------- | -------------------------------------------------------------------------------------------------- |
| total     | Int       | Number of records that exist based on the filter criteria of query                                 |
| hasMore   | Boolean   | Indicates if you should make an additional request to fetch more records if you want the full list |
| last      | String    | ID of the last item in the returned list.                                                          |
|           |           |                                                                                                    |


# Devices and Services

GraphQL queries and mutations for listing, creating and updating Remote.It devices and services, plus the supported application types.

## Remote.it Insomnia Collection

We have developed an example set of GraphQL queries and mutations in a collection that you can import directly into insomnia to get started. You will still need to install the authentication plug-in [here](/developer-tools/api/using-developer-tools#add-the-plugin-to-insomnia) and create your access keys in your account before getting started.

```
$ git clone https://github.com/remoteit/code_samples.git
```

## Application Types

Application types are service type definitions which are used as parameters for Get Devices By An Attribute and in services. In the case of services only the ID is returned so you will reference this response.

```graphql
query {
  applicationTypes {
   id
   name
   description
   port
   protocol
   proxy
  }
}
```

Response Example

```bash
{
  "data": {
    "applicationTypes": [
      {
        "id": 1,
        "name": "TCP",
        "description": "Generic TCP",
        "port": null,
        "protocol": "TCP",
        "proxy": false
      },
      {
        "id": 4,
        "name": "VNC",
        "description": "VNC remote desktop",
        "port": 5900,
        "protocol": "TCP",
        "proxy": false
      },
      ...
    ]
  }
}      
```

| Attributes  | Data Type | Description                                                                                                                 |
| ----------- | --------- | --------------------------------------------------------------------------------------------------------------------------- |
| id          | Int       | The primary key of the application type used in queries such as [Get Devices By An Attribute](#get-devices-by-an-attribute) |
| name        | String    | The given short name for an application type. This is unique                                                                |
| description | String    | Further explanation of the application type                                                                                 |
| port        | Int       | The default port for the application type. This can be overridden on a service by service basis                             |
| protocol    | String    | The protocol used when creating a connection to this application type                                                       |
| proxy       | Boolean   | Whether the application type will use a reverse proxy when creating a proxy connection.                                     |

## Get Your Devices

In this example we will be fetching your devices using graphQL. If you wish to get devices which meet a certain criteria like inactive devices, use the [Attribute Query](#get-devices-by-an-attribute). Devices uses [pagination](/developer-tools/api/usage#pagination) for the result set. Please refer to the [pagination explanation](/developer-tools/api/usage#pagination) for more on working with these results.

{% hint style="info" %}
This example only shows some of the variables and available attributes for the device and service collections.
{% endhint %}

```graphql
#Query
query getDevices($size: Int, $from: Int, $sort: String) {
  login {
  # account(id:"######") {
  # use account when organization results are needed and the user credentials are not the org owner
  # org user results are based on permissions
    devices(size: $size, from: $from, sort: $sort) {
      total
      hasMore
      items {
        id
        name
        hardwareId
        created
        services {
          id
          name
        }
      }
    }
  }
  #} if org used
}
#Variables
{
  "size": 1000,
  "from": 0,
  "sort": "name",
}
```

Response Example

```bash
{
  "data": {
    "login": {
      "devices": {
        "total": 1200,
        "hasMore": true,
        "items": [
          {
            "id": "8X:XX:XX:00:29:01:8e:ed",
            "name": "bento",
            "hardwareId": "dc:a6:32:19:8b:a3-xWoYf46uJ6QdtPXTloLb",
            "created": "2019-12-20T22:13:46.000Z",
            "services": [
              {
                "id": "8X:XX:XX:00:29:01:8e:ed",
                "name": "ssh service"
              }
            ]
          },
        ...
        ]
      }
    }
  }
}    
```

#### Parameters

| Parameter   | Data Type        | Description                                                                                                                                                                                                               |
| ----------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| size        | Int              | max is 1000                                                                                                                                                                                                               |
| from        | Int              | Index of result set to start return. 0 based.                                                                                                                                                                             |
| after       | String           | Device ID to use to start the return list after (used in pagination)                                                                                                                                                      |
| name        | String           | Filters the devices based on the string passed in (not case sensitive) Can be partial string.                                                                                                                             |
| application | Array of Int     | Array of Application IDs. Will return only devices that have matching [application type ](#application-types)in its list of of services                                                                                   |
| hardwareId  | String           | Filter to return devices which have matching hardware ID. Can be a partial string                                                                                                                                         |
| id          | String           | Device ID filter                                                                                                                                                                                                          |
| platform    | Array of Int     | Array of Platform Type IDs. (See graphQL examples for query for Platform Types                                                                                                                                            |
| state       | String           | Default is both active and inactive. Values can be "active" or "inactive"                                                                                                                                                 |
| tag         | Array of Strings | Array of tag names used on devices.                                                                                                                                                                                       |
| owner       | Boolean          | true to return only owned devices. false to return only devices shared to this account (not organization devices). Default is to return both.                                                                             |
| sort        | String           | <p>attributes: name, created, id, lastReported, owner, platform, state.</p><p>For ascending, use only the attribute name. For descending order, prepend the attribute name with "-".</p><p>For example: sort: "-name"</p> |

## Get Devices By An Attribute

In this example we will be fetching all devices with "tim" in the name using graphQL. This will return all devices with "tim" in the name and is not case sensitive. You can use any number of combinations of available attributes to narrow your result set further.

Other available parameters available:

| Parameter   | Data Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ----------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| application | Int       | <p>ID of the application type (service type). Using this parameter will return devices which have services of a given type and if the services are returned in the query will only include the services of this type. For example, if you request an application type id which is mapped to SSH and include the services, only services of type of SSH will be returned in the services array even when there are other services defined on the device.</p><p>To get available service types, please see <a href="#application-types">Application Types</a></p> |
| hardwareid  | String    | The hardware ID associated with the device.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| name        | String    | String which is present in the name of the device and is not case sensitive.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| platform    | \[Int]    | Array of platform IDs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| state       | String    | accepted values "active" and "inactive"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

**Additional attributes will become available over time**. Please refer to the schema documentation for the extensive list.

{% hint style="info" %}
This example only shows some of the variables and available attributes for the device and service collections.
{% endhint %}

```graphql
#Query
query getDevices($size: Int, $from: Int, $sort: String, $state: String, $name: String) {
  login {
    devices(size: $size, from: $from, sort: $sort, state: $state, name: $name) {
      total
      hasMore
      items {
        id
        name
        hardwareId
        created
        services {
          id
          name
        }
      }
    }
  }
}
#Variables
{
  "size": 1000,
  "from": 0,
  "sort": "name",
  "state": "inactive",
  "name": "tim"
}
```

Once you get the results, if the hasMore response returns true you know to do another fetch and in this case the from will increment to 1001 to fetch the next set, you could also determine this by iteration until you get to the total. Size is limited to 1000 max in each return.

Response Example

```bash
{
  "data": {
    "login": {
      "devices": {
        "total": 1200,
        "hasMore": true,
        "items": [
          {
            "id": "8X:XX:XX:00:29:01:8e:ed",
            "name": "Bento Time Machine",
            "hardwareId": "dc:a6:32:19:8b:a3-xWoYf46uJ6QdtPXTloLb",
            "created": "2019-12-20T22:13:46.000Z",
            "services": [
              {
                "id": "8X:XX:XX:00:29:01:8e:ed",
                "name": "ssh service"
              }
            ]
          },
        ...
        ]
      }
    }
  }
}    
```

## Update a Device/Service Name

Only the owner of the device **or an admin on the organization owning the device** can update the name of the device or service.

| Parameters | Data Type | Description                                              |
| ---------- | --------- | -------------------------------------------------------- |
| serviceId  | String    | This is the device Id or service Id that will be updated |
| name       | String    | The new name of the device or service                    |

```graphql
mutation {
  renameService(
    serviceId: "80:00:00:01:23:45:67:89",
    name: "New Name"
  )
}
```

Query Response

```graphql
{
  "data": {
    "renameService": true
  }
}
```

## Update a Device or Service

Only the owner of the device **or an admin on the organization owning the device** can update a device.

| Parameter   | Data Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ----------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| serviceId   | String!   | Required - The device Id or service Id that will be updated                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| refresh     | Boolean!  | Boolean to send the updates to the device. This should be true to push the updated configuration to the device.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| enabled     | Boolean   | Configuration for the remoteit daemon on a service. It must be true to enable connections and online/offline state. Can be set to false if you would like to disable the service to reduce network ping traffic.                                                                                                                                                                                                                                                                                                                                                |
| application | Int       | <p>ID of the application type (service type). Using this parameter will return devices which have services of a given type and if the services are returned in the query will only include the services of this type. For example, if you request an application type id which is mapped to SSH and include the services, only services of type of SSH will be returned in the services array even when there are other services defined on the device.</p><p>To get available service types, please see <a href="#application-types">Application Types</a></p> |
| name        | String    | The name of the device or service                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| host        | String    | <p>Default is 127.0.0.1 (localhost) if the service runs locally on the device, if null it is treated like localhost.</p><p>OR</p><p>The local network IP address or fully qualified domain name to configure this as a jump service to a system on your local network.</p>                                                                                                                                                                                                                                                                                      |
| port        | String    | The port for this service on the device. (Leave null for the Device) For example, SSH is 22 unless configured differently on your device                                                                                                                                                                                                                                                                                                                                                                                                                        |

```graphql
mutation {
    updateDevice(
     deviceId: "80:00:00:98:01:23:45:67",
     refresh: true,
     name: "New Name",
     port: 22
    )
}
```

Query Response

```graphql
{
  "data": {
    "updateDevice": true
  }
}
```

## Delete Device

Only the owner of the device **or an admin on the organization owning the device** can delete a device. Devices can only be deleted when the state is `inactive`.

```graphql
mutation {
  deleteDevice(
    deviceId: "80:00:00:98:01:23:45:67"
  )
}
```

Query Response

```graphql
{
  "data": {
    "deleteDevice": true
  }
}
```

## Remove a Service

Only the owner of the device **or an admin on the organization owning the device** can remove a service from a device.

{% hint style="danger" %}
Services will be removed even if active and in use
{% endhint %}

```graphql
mutation {
  removeService(
    id:"80:00:00:98:01:23:45:67"
    )
}
```

Query Response

```graphql
{
  "data": {
    "removeService": true
  }
}
```


# Event Logs

Query Remote.It event logs through the GraphQL API — event types, attributes, and the users and devices each event affects.

## Event Log Attributes

| Attribute | Description                                                                                                                                                                                                           |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id        | Event ID                                                                                                                                                                                                              |
| timestamp | DateTime of the Event in ISO 8601 format Date String                                                                                                                                                                  |
| type      | Event Type                                                                                                                                                                                                            |
| actor     | User who initiated the event. This is currently only applicable for DEVICE\_SHARE and DEVICE\_CONNECT. You can get user ID and email                                                                                  |
| owner     | User who owns the device when the event affects a device/service. You can get user ID and email                                                                                                                       |
| users     | An array of users affected by the event. For example on a DEVICE\_SHARE it is the users whose access to a device/service was added or removed. On a DEVICESTATE event it is the users who were notified of the event. |
| state     | The service state (online or offline)                                                                                                                                                                                 |
| target    | The services affected by the event. For example the services that changed state, the services that where share access was changed, or the services connected                                                          |

### Additional Attributes by Type

For each event type extends the general EventType. Please refer to the schema documentation for the available attributes.

## Event Log Parameters

Event Logs support pagination which is described [here](/developer-tools/api/usage#pagination). Event response are sorted chronologically descending.

Additional parameters

| Parameter | Type                | Description                                                                                                                                       | Default                                         |
| --------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| types     | Array of EventTypes | <p>"DEVICE\_STATE", "DEVICE\_CONNECT", "DEVICE\_SHARE"</p><p>More types will be become available. Please refer to the schema for current list</p> | All                                             |
| maxDate   | DateTime            | The last date you wish to be included in the result set. Accepts ISO 8601 format Date String with or without the timestamp                        | Today with 1000 events being the max size       |
| minDate   | DateTime            | The first date you wish to be included in the result set. Accepts ISO 8601 format Date String with or without the timestamp                       | 1 month ago with 1000 events being the max size |

## Get All Event Logs

These examples will fetch 1000 connection logs for all of your devices in the last month. See above for other event types. Min and max dates should not exceed 1 month.

### JSON

```javascript
query getEvents($size: Int, $from: Int, $minDate: DateTime, $maxDate: DateTime, $types: [EventType!]){
  login {
    events(size: $size, from: $from, minDate: $minDate, maxDate: $maxDate, types: $types) {
      hasMore
      total
      items {
        type
        owner {
          email
        }
        actor {
          email
        }
        target {
          created
          id
          name
        }
        users {
          email
        }
        timestamp
      }    
    }
  }
}

#Variables
{
  "size": 1000,
  "from": 0,
  "minDate": "2021-06-01",
  "maxDate": "2021-07-01"
  "types": ["DEVICE_CONNECT"]
}
```

Response Example

```bash
{
  "data": {
    "login": {
      "events": {
        "hasMore": false,
        "total": 4,
        "items": [
          {
            "type": "DEVICE_CONNECT",
            "owner": {
              "email": "XXX@gmail.com"
            },
            "actor": {
              "email": "actor@remote.it"
            },
            "target": [
              {
                "created": "2021-03-24T09:56:16.873Z",
                "id": "80:XX:00:00:01:0A:FF:00",
                "name": "ssh"
              }
            ],
            "users": [],
            "timestamp": "2021-07-16T20:53:59.644Z"
          },
          {
            "type": "DEVICE_CONNECT",
            "owner": {
              "email": "owner@remote.it"
            },
            "actor": {
              "email": "actor@remote.it"
            },
            "target": [
              {
                "created": "2021-03-24T09:56:16.873Z",
                "id": "80:XX:00:00:01:0A:FF:00",
                "name": "ssh"
              }
            ],
            "users": [],
            "timestamp": "2021-07-16T20:35:06.215Z"
          },
          {
            "type": "DEVICE_CONNECT",
            "owner": {
              "email": "owner@remote.it"
            },
            "actor": {
              "email": "actor@remote.it"
            },
            "target": [
              {
                "created": "2021-03-24T09:56:16.873Z",
                "id": "80:XX:00:00:01:0A:FF:00",
                "name": "ssh"
              }
            ],
            "users": [],
            "timestamp": "2021-07-16T20:20:41.601Z"
          },
          {
            "type": "DEVICE_CONNECT",
            "owner": {
              "email": "owner@remote.it"
            },
            "actor": {
              "email": "actor@remote.it"
            },
            "target": [
              {
                "created": "2021-03-24T09:56:16.873Z",
                "id": "80:XX:00:00:01:0A:FF:00",
                "name": "ssh"
              }
            ],
            "users": [],
            "timestamp": "2021-07-16T18:56:31.453Z"
          }
        ]
      }
    }
  }
}
```

### CSV

This returns a url which you can use to download the results in a csv format. The url will expire in 1 hour. Max 10000 lines or 28 seconds of execution.

```bash
{
  login {
    eventsUrl(minDate: "2021-06-01", maxDate: "2021-07-01", types: ["DEVICE_CONNECT"])
  }
}
```

Response example

```bash
{
  "data": {
    "login": {
      "eventsUrl": "https://api.remote.it/graphql/v1/files/e60xxxx-8a71-4870-bxxf-xxxdd2021f7.csv"
    }
  }
}
```

## Get Event Logs for Specific Devices

This request will fetch state logs for a specified device in a csv format using graphQL. In these examples we want to get the external IP address each time it comes online to track the device location.

### JSON Result

```javascript
#query
query getEvents($deviceID: [String!]!, $minDate: DateTime, $maxDate: DateTime, $types: [EventType!]) {
  login {
    device(id: $deviceID) {
      events(minDate: $minDate, maxDate: $maxDate, types: $types) {
        hasMore
        total
        items {
          state
          timestamp
          target {
            name
            id
          }
          ... on DeviceStateEvent {
          externalAddress
          geo {
            connectionType
            isp
          }
          } 
        }
      }
    }
  }
}

#variables
{
  "deviceID": ["80:XX:00:00:01:05:82:22"],
  "minDate": "2021-06-01",
  "maxDate": "2021-07-01",
  "types": ["DEVICE_STATE"]
}
```

Response Example

```javascript
{
  "data": {
    "login": {
      "device": [
        {
          "events": {
            "hasMore": false,
            "total": 76,
            "items": [
              {
                "state": "inactive",
                "timestamp": "2021-07-17T22:16:11.921Z",
                "target": [
                  {
                    "name": "MacBook-Pro-15 - vnc",
                    "id": "80:XX:00:00:01:05:82:23"
                  }
                ],
                "externalAddress": "73.189.XX.XXX:53190",
                "geo": {
                  "connectionType": "Cable/DSL",
                  "isp": "Comcast Cable"
                }
              },
              {
                "state": "inactive",
                "timestamp": "2021-07-17T22:16:07.479Z",
                "target": [
                  {
                    "name": "New ssh",
                    "id": "80:XX:00:00:01:1A:4A:AB"
                  }
                ],
                "externalAddress": "73.189.XX.XXX:56236",
                "geo": {
                  "connectionType": "Cable/DSL",
                  "isp": "Comcast Cable"
                }
              },
              ...
            ]
          }
        }
      ]
    }
  }
}
```

### CSV Result

This request will return a url for a CSV download. The url will expire in 1 hour. Max 10000 lines or 28 seconds of execution. Min and max dates should not exceed 1 month.

```javascript
query getEventsUrl($deviceID: [String!]!, $minDate: DateTime, $maxDate: DateTime, $types: [EventType!]) {
  login {
    device(id: $deviceID) {
      eventsUrl(minDate: $minDate, maxDate: $maxDate, types: $types)
    }
  }
}
```

Response Example

```bash
{
  "data": {
    "login": {
      "device": [
        {
          "eventsUrl": "https://api.remote.it/graphql/v1/files/af7xxx-82x7-464c-xxxc-132xxxx.csv"
        }
      ]
    }
  }
}
```

##


# Connections

Create on-demand, proxy and reverse proxy connections through the Remote.It GraphQL API, including peer-to-peer with proxy failover.

## On Demand Connections

To create a connection from one device to another which will reconnect on demand, you can use the Desktop Application or the CLI tool. This type of connection is Peer to Peer by default with a Proxy Failover.

## Create a Proxy Connection

{% hint style="info" %}
For http and https remote.it Services, the returned value for "proxy" will be a single string similar to the following. It does not need an explicit port value to be used. These are "reverse proxies". Reverse proxies are always public, which is why the randomized URL is generated at the time of creating the connection.

```
"proxy": "https://xprbjalo.p18.rt3.io"
```

For all other types of remote.it Services, the returned value for "proxy" will include a hostname and a port value separated by a colon, as shown below. These are "port proxies".

```
"proxy": "http:\/\/proxy18.rt3.io:38575"
```

{% endhint %}

### Proxy Connection Modes

The following options apply only to "port proxies", namely all Service types except the **http** and **https** Service types, which use "reverse proxies". Reverse proxies are always public which is why the randomized URL is created.

#### hostIP Options

| Mode          | Value          | Description                                                                                                                                                                                                   |
| ------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Public        | 0.0.0.0        | Anyone who has the connection URL and port can connect to it until the connection expires or is closed. If you use the Public connection mode, make sure that your resources are properly password protected. |
| IP Restricted | Unique IP      | Only connections coming from that public IP address will be allowed. Any other incoming connection will be blocked.                                                                                           |
| IP Latching   | 255.255.255.25 | Whoever uses the connection URL and port first will "latch" the connection, blocking all other connection attempts regardless of where they originated.                                                       |

### Connect

<table><thead><tr><th>Parameter</th><th width="171.33333333333331">Data Type</th><th>Description</th></tr></thead><tbody><tr><td>serviceId</td><td>String</td><td>The id of the service you will make a connection to</td></tr><tr><td>hostIP</td><td>String</td><td>Used to restrict the range of IP addresses who can connect to the proxy.</td></tr></tbody></table>

```graphql
#Query
mutation query($serviceId: String!, $hostIP: String!) {
  connect(serviceId: $serviceId, hostIP: $hostIP) {
	id
	created
	host
	port
	reverseProxy
	timeout
	}
}
#Variables
{
	"serviceId": "80:00:00:12:34:56:78:90",
	"hostIP": "255.255.255.255"
}
```

Query response for reverse proxy connections (http/s services)

```graphql
{
  "data": {
    "connect": {
      "id": "123ddfff-6432-49d0-6432-205d49d08454",
      "created": "2020-01-01T01:09:00.000Z",
      "host": "a4csg2w9f8wipk.p16.rt3.io",
      "port": null,
      "reverseProxy": true,
      "timeout": 28800
    }
  }
}
```

{% hint style="info" %}
The value returned for "id" can be used with the [Disconnect](#disconnect) API endpoint to terminate the proxy connection to your target when you are done using it.
{% endhint %}

Query response for all other proxy requests where host + port is required to connect

```graphql
{
  "data": {
    "connect": {
      "id": "123ddfff-6432-49d0-6432-205d49d08454",
      "created": "2020-01-01T01:20:00.000Z",
      "host": "proxy18.rt3.io",
      "port": 37488,
      "reverseProxy": false,
      "timeout": 28800
    }
  }
}
```

### Disconnect

| Parameter    | Data Type | Description                                                              |
| ------------ | --------- | ------------------------------------------------------------------------ |
| serviceId    | String    | The id of the service you want to terminate the connection for           |
| connectionId | String    | This is the connect id in the query response from the connect call above |

```graphql
#Query
mutation query($serviceId: String!, $connectionId: String!){
  disconnect(serviceId: $serviceId, connectionId: $connectionId)
}
#Variables
{
	"serviceId": "80:00:00:12:34:56:78:90",
	"connectionId": "123ddfff-6432-49d0-6432-205d49d08454"
}
```

Query Response

```graphql
{
  "data": {
    "disconnect": true
  }
}
```


# Access Keys

Create, disable and delete the access keys that authenticate you to the Remote.It API. Secret keys cannot be retrieved once lost.

Access keys are used to authenticate you with our API. You can create a new key or delete an existing key at any time. You can also temporarily disable a key.

## Creating an Access Key

{% hint style="warning" %}
**If you lose or forget your secret key, you cannot retrieve it.** You can create a new access key and disable/delete the other. There is a limit of 2 access keys.
{% endhint %}

```
mutation {
  createAccessKey {
    key
    secret
  }
}
```

Response Example

```
{
  "data": {
    "createAccessKey": {
      "key": "YX62XXXXXXXXXX6YB",
      "secret": "XXXXXXXXXXXXXX"
    }
  }
}
```

## Disable/Enable an Access Key

This request will disable/enable an existing access key. Arguments must pass the access key id (not the secret) and enabled as a boolean

```
mutation {
    updateAccessKey(key:"YX62XXXXXXXXXX6YB", enabled: false) {
        key
        enabled
    }
}
```

Response Example

```
{
  "data": {
    "updateAccessKey": {
      "key": "YX62XXXXXXXXXX6YB",
      "enabled": false
    }
  }
}
```

## Delete an Access Key

This mutation will delete the access key permanently.

{% hint style="danger" %}
Any API or CLI requests using this access key will start failing authentication when this is completed.
{% endhint %}

```
mutation {
  deleteAccessKey (key: "YXXXXXXXXXXXX6YB") 
}
```

Response Example

```
{
  "data": {
    "deleteAccessKey": true
  }
}
```


# Device Sharing

Share and unshare Remote.It devices and individual services with other users through the GraphQL API, with optional scripting permission.

This mutation allows you to add or remove device and service sharing from your account to other users. DeviceId and ServiceId can be retrieved [here](/developer-tools/api/usage/devices-and-services#get-your-devices).

| Parameters | Data Type                | Description                                                                                                                               |
| ---------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| deviceId   | String                   | <p><strong>required</strong></p><p>The ID of the device to share</p>                                                                      |
| email      | \[String]                | <p><strong>required</strong></p><p>The email(s) of the user you want to share the device with, or you can specify an array of emails.</p> |
| scripting  | Boolean                  | Grants bulk scripting permission to the user (**default**: false)                                                                         |
| notify     | Boolean                  | The user will be notified (**default**: true)                                                                                             |
| action     | String                   | ADD, REMOVE, LEAVE (**default**: ADD)                                                                                                     |
| services   | \[ServiceSharingOptions] | For sharing only a subset of services. This field and below is not required if sharing all services of a device                           |
| serviceId  | String                   | The ID of the specific service associated with the deviceID                                                                               |

### Add or Remove

This example shares and notifies `email@example.com` that deviceId `80:00:00:00:12:34:56:78` has been shared and all services associated with it but does not grant bulk scripting permissions.

```graphql
mutation {
  share(deviceId: "80:00:00:00:12:34:56:78", 
        email: "email@example.com", 
        scripting: false,
        notify: true,
        action: ADD)
}
```

This example shares a service and removes a share of another service on the same device to multiple users.

```graphql
mutation {
  share(deviceId: "80:00:00:00:12:34:56:78",
        email: [
          "email1@example.com",
          "email2@example.com"
        ],
        notify: true,
        services: [
          {serviceId: "80:00:00:00:12:34:56:79", action: ADD},
          {serviceId: "80:00:00:00:12:34:56:79", action: REMOVE}
        ]
```

### Leave

If you want to leave a shared device that another user has shared with you previously

```graphql
mutation {
  share(
    deviceId: "80:00:00:00:12:34:56:78"
    email: "YourEmail@example.com"
    action: LEAVE
  )
}
```

Response Example

```graphql
{
  "data": {
    "share": true
  }
}
```


# Custom Attributes

Attach your own metadata to Remote.It users, devices and services with custom attributes, including per-context value overrides.

Attributes can be added to Users, Devices and Services. Attributes can have overrides defined by context. This is used for your own custom metadata.

### Add/Update Attribute

| Parameter | Data Type | Description                                                                                           |
| --------- | --------- | ----------------------------------------------------------------------------------------------------- |
| name      | String    | <p><strong>required</strong></p><p>Name of attribute</p>                                              |
| value     | String    | <p><strong>required</strong></p><p>Value of attribute<br><code>null</code> to remove</p>              |
| serviceId | String    | <p><strong>required</strong></p><p>The userId, deviceId or serviceId the attribute is assigned to</p> |
| context   | String    | defined context of the attribute. Allows for override of attribute value for the same name            |

```graphql
mutation {
  setAttribute(
    name: "CustomAttribute",
    value: "ValueOfAttribute",
    serviceId: "80:00:00:00:12:34:56:78",
    context: "CustomContext"
  )
}
```

Query Response

```graphql
{
  "data": {
    "setAttribute": "ValueOfAttribute"
  }
}
```

### Category and Status Fields

We have reserved names of remote.it Device attributes which will be displayed on the Web Portal and Desktop UIs. These attributes are for Category and Status fields. The UI currently can display Category A-E and Status A-E. These must be set against the Device ID (also known as the Bulk Service's "Service ID" of the remote.it Device). The convention for the name is $remoteit.categoryA for category attributes and $remoteit.statusA for status attributes. The convention is the same for removing and retrieving these attributes.

**Example Category Mutation**

```graphql
mutation {
  setAttribute(
    name: "$remoteit.categoryA",
    value: "my category A value",
    serviceId: "80:00:00:00:12:34:56:78",
  )
}
```

### Remove Attribute

```graphql
mutation {
  setAttribute(
    name: "CustomAttribute",
    value: null,
    serviceId: "80:00:00:00:12:34:56:78",
  )
}
```

### Set Multiple Attributes

This method shows how to update multiple attributes on a single device by passing in a JSON formatted variables.

```graphql
#Query
mutation UpdateMultipleAttributes($attributes: Object!, $serviceId: String!) {
	setAttributes(attributes: $attributes, serviceId: $serviceId)
}

#Variables
{
  "attributes": {
    "$remoteit": {
      "categoryA": "Uptime: 1h, 06m",
      "categoryB": "Version: 1.0",
      "categoryC": "Serial Number: x292jsu2",
      "categoryD": "MAC: AUWS83729A"
    },
    "MoreJsonAttributes": {
      "version": "1.0"
    },
    "StringAttribute": "newvalue"
  },
  "serviceId": "80:00:00:00:01:12:12:12"
}
```

### Retrieve Attributes

```graphql
{
  login {
    attributes #User Attributes
    devices{
      items{
        attributes #Device Attributes
        services{ 
          attributes(context: "customContext") #Service Attributes
        }
      }			
    }
  }
}
```

Query Response

```graphql
{
  "data": {
    "login": {
      "attributes": { #User Attributes
	"newAttribute": "CustomAttributeValue",
	},
     "devices": {
	"items": [
	{
	"attributes": { #Device Attributes
	  "newAttribute": "CustomAttributeValue"
	},
	"services": [
	{
	  "attributes": { #Service Attributes
	     "newAttribute": "ContextAttributeValue"
	   }
	},...]						
	}
	]
      }
    }
  }
}
```


# Scripting

Upload script files and execute them against your Remote.It devices through the GraphQL API, including passing arguments and checking job status.

For more about script files themselves see [Device Scripting](/developer-tools/device-scripting)

## Upload File

You can upload files to be run as script against your devices. Scripts can have arguments which you can pass.

**You must be the account owner or if you belong to an organization have administrator priviledges on the account to upload a file.**

{% hint style="warning" %}
Files must be able to be uploaded in 30 seconds. If you need to have larger files, consider hosting at another location such as S3 and having your script fetch them.
{% endhint %}

**Details**

**Example of File Upload is part of the** [**Insomnia Collection**](https://docs.remote.it/developer-tools/api/usage/pages/-Ma4sJZMT46Sv_Kt2vva#remote.it-insomnia-collection) **and** [**Postman Collection** ](/developer-tools/api/using-developer-tools#postman-set-up)**under Scripting**

* **Endpoint:** `/file/upload`
* **Method:** `POST`
* **This is not a graphQL mutation. It is REST**
* **Form Parameters:**
  * `file`: The file or script name to be uploaded, designated with its file path.
  * `shortDesc` - Short description for the Script File (optional)
  * `longDesc` - Long description for Script File (optional)
  * `selections`: A JSON array which defines selection criteria and options.

{% hint style="info" %}
Uploading a file of the same name as an existing file will create a new version of the file.
{% endhint %}

**Arguments**

Arguments can be of three types:

* `FileSelect`: A previously uploaded file
* `StringSelect`: A preset collection of strings
* `StringEntry`: User entered string

Arguments are passed as a list to the form entry called 'arguments'. Each list item contains the following:

* name - a reference for this argument
* type - (FileSelect, StringSelect or StringEntry)
* options -
  * For FileSelect this will limit the files shown by the strings given
  * For StringSelect this will be the list of strings that can be chosen
  * For StringEntry no options are required

## Get List of Script Files

Return a list of scripts that have been uploaded to your account. Additionally, if you add the context of an account (organization) where you have manage with scripting capabilities or admin role.

**Query**

{% code lineNumbers="true" %}

```graphql
query GetFiles {
login {
# Add the following line if you need to do this in Org context.
# The ID is the Org ID
  #account(id:"XXXXXX-XXXX-XXXXXX-XXXXX") {
  files {
    owner {
      email
      id
    }
    id
    name 
    shortDesc
    longDesc
    created
    updated
    versions {
      total
      hasMore
      items{
      id
      created
      version
      arguments {
        name
        order
        options
        argumentType
      }
      }
    }
  }
  #} end of org context
}
}
```

{% endcode %}

**Response**

{% code lineNumbers="true" %}

```json
{
"data": {
  "login": {
      "files": [
        {
          "owner": {
            "email": "support@remote.it",
            "id": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXX"
          },
          "id": "881189d3-59b8-48d7-84fe-3199bdfbc40a",
          "name": "new_script_example.sh",
          "created": "2024-01-11T00:11:50.388Z",
          "updated": "2024-01-11T06:03:26.000Z",
          "versions": {
            "total": 7,
            "hasMore": false,
            "items": [
            {
              "id": "bf0273c8-9077-408e-9560-975a504a47b2",
              "created": "2024-01-11T00:11:50.639Z",
              "version": 1
            },
            {
              "id": "50e0c466-8312-455e-9ebd-1f5afd7aa733",
              "created": "2024-01-11T05:40:06.679Z",
              "version": 2
            },
            {
              "id": "16dbff8b-596d-4785-9908-659bb10e7987",
              "created": "2024-01-11T05:44:28.539Z",
              "version": 3
            },
            {
              "id": "28e8647a-a2c7-4bd9-8f8a-130db01fa7e4",
              "created": "2024-01-11T05:49:09.608Z",
              "version": 4
            },
            {
              "id": "d3449672-74e6-4745-8c25-2ffd79e6be36",
              "created": "2024-01-11T05:57:45.977Z",
              "version": 5
            },
            {
              "id": "3d94ad75-35a0-4af8-b0fa-5cbdfbfaaa77",
              "created": "2024-01-11T05:58:08.464Z",
              "version": 6
            },
            {
              "id": "50046b34-186c-47ee-a171-968f43ef2d96",
              "created": "2024-01-11T06:03:25.730Z",
              "version": 7
            }
          ]
          }
        },
        {
          "owner": {
            "email": "support@remote.it",
            "id": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXX"
          },
          "id": "f12d6bf2-0f6d-4bf6-95be-cd045b2471c2",
          "name": "test_upload.txt",
          "created": "2024-01-11T00:06:25.781Z",
          "updated": "2024-01-11T00:06:26.000Z",
          "versions": {
            "total": 1,
            "hasMore": false,
            "items": [
            {
              "id": "3f5f04d4-23f4-4cd8-a9ba-70814952dff7",
              "created": "2024-01-11T00:06:26.074Z",
              "version": 1
            }
            ]
          }
        }
      ]
    }
  }
}
```

{% endcode %}

**File Attributes**

| Attributes | Data Type              | Description                                                                                      |
| ---------- | ---------------------- | ------------------------------------------------------------------------------------------------ |
| id         | Int                    | The primary key of the file                                                                      |
| name       | String                 | The given short name for a file                                                                  |
| shortDesc  | String                 | Optional short description for the file                                                          |
| longDesc   | String                 | Optional long description for the file. Can be used to provide further information to your team. |
| owner      | User                   | User who owns the file. id and email are available as attributes of a User.                      |
| created    | Date                   | DateTime of the File creation in ISO 8601 format Date String                                     |
| updated    | Date                   | DateTime of the File last updated in ISO 8601 format Date String                                 |
| versions   | Paginated FileVersions | See [Pagination](#pagination)                                                                    |

**File Version Attributes**

Files of the same name create versions.

| Attributes | Data Type       | Description                                                     |
| ---------- | --------------- | --------------------------------------------------------------- |
| id         | Int             | The primary key of the file version.                            |
| version    | int             | The Version number                                              |
| created    | Date            | DateTime of the Version creation in ISO 8601 format Date String |
| arguments  | \[FileArgument] | The list of arguments that are required to run the script.      |

**Version Filtering Arguments**

| Filter Attribute | Data Type | Description                                                                         |
| ---------------- | --------- | ----------------------------------------------------------------------------------- |
| sort             | String    | sortable attributes - ids, created. prepend attribute with - for sorting descending |
| from             | Int       | Index of results to start from given the applied filters                            |
| after            | String    | Version ID for to return results from.                                              |
| size             | Int       | Size of the results to return. Max of 100                                           |
| id               | String    | Filter on the given version ID                                                      |
| ids              | Strings   | Filter to return the given versions                                                 |
| latest           | Boolean   | return the latest version                                                           |
| maxDate          | DateTime  | ISO 8601 format date string - Return versions created before the given DateTime     |
| minDate          | DateTime  | ISO 8601 format date string - Return versions created after the given DateTime      |

**File Argument Attributes**

| Attributes   | Data Type        | Description                                                    |
| ------------ | ---------------- | -------------------------------------------------------------- |
| name         | string           | Named used to reference the argument                           |
| desc         | string           | The string used when selecting a value for the argument.       |
| order        | int              | The order the options will be placed                           |
| options      | \[string]        | The list of options given to the user to choose                |
| argumentType | FileArgumentType | The type of argument (FileSelect, StringSelect or StringEntry) |

## Download File

You must be the account owner or if you belong to an organization, the owner, an admin or a user with Manage role with scripting permission.

Use the base graphQL url + /file/download/{fileVersionId}

## Delete File

You must be the account owner or if you belong to an organization, an admin on the account to delete a file.

**Mutation**

{% code lineNumbers="true" %}

```graphql
mutation deleteFile {
  deleteFile(fileId: "881189d3-59b8-48d7-84fe-3199bdfbc40a")
}

```

{% endcode %}

**Response**

{% code lineNumbers="true" %}

```json
{
  "data": {
     "deleteFile": true
  }
}
```

{% endcode %}

## Delete File Version

You must be the account owner or if you belong to an organization, an admin on the organization to delete a file version.

**Mutation**

{% code lineNumbers="true" %}

```graphql
mutation deleteFileVersion {
  deleteFileVersion(fileVersionId: "d3449672-74e6-4745-8c25-2ffd79e6be36")
}
```

{% endcode %}

**Response**

{% code lineNumbers="true" %}

```json
{
  "data": {
    "deleteFileVersion": true
  }
}
```

{% endcode %}

## Create a Job (Run a Script)

**Owners of the devices or managers or admins which have access to the selected devices can run a script**. For example, if a user has a role which only allows them manage capabilities on devices tagged with "support". If there are any devices which are not valid for the user, then the entire job is rejected.

{% hint style="warning" %}
Script jobs should not be sent to more than 50 devices at a time. Job execution is sent to all devices by separate processes at nearly the same time. The Remote.It server wil attempt to send a job to a given device 26 times with an exponential backoff that will end after 1.5 days. This will allow for a device that might be offline temporarily to still receive a script job.
{% endhint %}

**Mutation**

When you have file versions, you can pass the file version ID in the "fileId" field to specify the version. See [Creating Scripts](#creating-scripts) section for more on authoring the scripts themselves.

<pre class="language-graphql" data-line-numbers><code class="lang-graphql"><strong>mutation execute {
</strong>  startJob(
    #fileId or fileVersionId are required. If both are passed, the fileVersionId is used.
    fileId: "881189d3-59b8-48d7-84fe-3199bdfbc40a",
    #fileVersionId: "3f5f04d4-23f4-4cd8-a9ba-70814952dff7",
    #Device IDs OR Tags are used to identify the devices for the job. If both device IDs and tags are passed, device Ids will be used.
    deviceIds: ["80:00:00:00:01:22:37:AE"],
    #optional device tags (can be used to run a group of scripts against a set of devices with these tags at time of execution)
    #ANY/ALL (i.e. or/and), when tags are used, operator should accompany
    tagFilter: {operator: ANY, values:["reboot"]},
    arguments: [
      {
        name: "url"
        value: "https://remote.it"
      },
      {
        name: "imageFile"
        value: "3f5f04d4-23f4-4cd8-a9ba-70814952dff7"
      },
      {
        name: "bookmarkName"
        value: "RemoteIt"
      },
      {
        name: "action"
        value: "Add"
      }
    ]
  )
}
</code></pre>

**Response**

Success will result in a job ID. If there are any devices which are not valid for the user, then the entire job is rejected. A job will also be rejected if a script is not valid for the account.

{% code lineNumbers="true" %}

```json
{
  "data": {
    "startJob": "57592ee3-ed89-4265-89af-337c8fb8d36d"
  }
}
```

{% endcode %}

**Job Parameters**

| Parameter     | Data Type            | Description                                                                                                                                                 |
| ------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| fileId        | String               | Primary key of Script file to be executed (either fileID or fileVersionID are required, if both are present, then fileVersionId is used)                    |
| fileVersionId | String               | Primary of version ID of the file to be executed. (either fileID or fileVersionID are required, if both are present, then fileVersionId is used)            |
| deviceIds     | Array of Device IDs  | Device Ids for job to execute script against. If both tags and deviceIds are given in mutation, deviceIds will be used. (required if not using fileTags)    |
| tagFilter     | Tag Filter Arguments | Tags and operator for job execution parameters. If both tags and deviceIds are given in mutation, deviceIds will be used. (required if not using deviceIds) |
| arguments     | Array of argument    | ArgumentType (Optional) - Only supported in the API and not in app.remote.it or the Desktop application.                                                    |

**TagFilter**

| Attribute | Data Type                    | Description                                                                  |
| --------- | ---------------------------- | ---------------------------------------------------------------------------- |
| operator  | TagOperatorEnum              | ANY,ALL (or/and) (optional, if not using fileTags)                           |
| values    | Array of tag names (Strings) | Devices with tags at time of job creation will be selected for job execution |

**Job Arguments (only in API)**

| Attribute | Data Type | Description                                                                                                  |
| --------- | --------- | ------------------------------------------------------------------------------------------------------------ |
| name      | String    | Name of argument used in script                                                                              |
| value     | String    | User selected argument value, could be arbitrary string or file id depending or argument type used in script |

## Cancel Job (Run)

**Owners of the devices or managers or admins which have access to the selected devices can run a script**. Cancel Job requires the job ID and will cancel the job that is in progress but cannot revert any scripts that have already executed. Any currently executing script will no longer update the Remote.It backend for updating attributes or legacy task notifier, but the script will finish running. Any scripts not yet received by devices will be cancelled.

**Mutation**

{% code lineNumbers="true" %}

```graphql
mutation cancelJob {
  cancelJob(jobId: "41fc0cec-4efd-40ef-8e48-1aa109019f1c")
}
```

{% endcode %}

**Response**

{% code lineNumbers="true" %}

```json
{
  "data": {
     "cancelJob": true
   }
}
```

{% endcode %}

## View Jobs (Runs) and Device Status

Get a list of Jobs and their devices' status. Optionally you can filter by passing an array of jobIDs, array of statuses. [Examples of Pagination.](#pagination)

**Query**

<pre class="language-graphql"><code class="lang-graphql">query GetJobs {
   login {
     # Add the following line if you need to do this in Org context.
     # The ID is the Org ID
     #account(id:"XXXXXX-XXXX-XXXXXX-XXXXX") {
     #see documentation on paginated responses for iteration
     #examples of filtering below
      jobs(ids: ["41fc0cec-4efd-40ef-8e48-1aa109019f1c","41fc0cec-4efd-40ef-8e48-xxxxx"], statuses:[FAILED,WAITING,RUNNING,SUCCESS,CANCELLED],size: 1000)
      {
	  hasMore
          total
          last
          items {
	     id
             owner {
          	email
             }
	     user {
	   	email
	     }
	     created
	     updated
             # One of the following FAILED,WAITING,RUNNING,SUCCESS,CANCELLED
             status
             #tags associated with job
             tags {
	       name
             }
             #ANY/ALL (i.e. or/and)
             tagOperator,
             fileVersion {
   		id
                file {
<strong>                   name
</strong> 	        }
             }
             jobDevices {
    		id
    		device {
                   id
    		}
		#attributes associated with the job.
		attributes {
			 created
			 id
			 key
			 value
		}
	   	#one of the following: FAILED,WAITING,RUNNING,SUCCESS,CANCELLED
	   	status
	      }
	      arguments {
		  id
		  fileArgument {
		   id
		   name
		   desc
		   order
		   options
		   argumentType
		   created
		  }
		  name
		  desc
		  order
	          argumentType
	          value		
              }
          }
       }
    }
}
</code></pre>

**Response:**

{% code lineNumbers="true" %}

```json
{
  "data": {
    "login": {
      "account": {
        "jobs": 
           {
	     "hasMore": false,
	     "total": 1,
	     "last": "57592ee3-ed89-4265-89af-337c8fb8d36d",
	"items": [
          {
            "id": "57592ee3-ed89-4265-89af-337c8fb8d36d",
            "owner": {
              "email": "support@remote.it"
            },
            "user": {
              "email": "support@remote.it"
            },
            "created": "2024-01-13T01:34:38.358Z",
            "updated": "2024-01-13T01:34:57.000Z",
            "status": "SUCCESS",
            "tags": [{"name":"reboot"}],
            "tagOperator":"ANY",
            "fileVersion": {
              "id": "50046b34-186c-47ee-a171-968f43ef2d96",
              "file": {
                "name": "new_script_example.sh"
              }
            },
            "jobDevices": [
              {
                "id": "e88583b3-dac4-44f3-8c17-43f4fd22174f",
                "device": {
                  "id": "80:00:00:00:01:22:37:AE"
                },
                "status": "SUCCESS"
                "attributes": [
                {
                  "created": "2024-01-13T01:34:38.358Z"
                  "id": "XXXX-XXX-XXX-XXX",
                  "name": "category1",
                  "value": "pi reboot"
                }
                ]
              }
            ],
            "arguments": [
              {
                "id": "25e905cf-e649-42f2-92d8-2df637893b15",
                "fileArgument": {
                  "id": "2c1ff728-a6fb-4d8d-9c44-3e952b40f4fb",
                  "name": "action",
                  "desc": "Choose Action",
                  "order": 4,
                  "options": [
                    "Add",
                    "Remove"
                  ],
                  "type": "StringSelect",
                  "created": "2024-01-11T06:03:26.264Z"
                },
                "name": "action",
                "desc": "Choose Action",
                "order": 4,
                "argumentType": "String",
                "value": "Add"
              },
              {
                "id": "42e83021-a5f2-4770-ae31-0c7a981a71cc",
                "fileArgument": {
                  "id": "55968a9c-edc6-4fb4-a233-431bdeeb07e9",
                  "name": "fileName",
                  "desc": "Select File",
                  "order": 1,
                  "options": [
                    ".png"
                  ],
                  "argumentType": "FileSelect",
                  "created": "2024-01-11T06:03:25.803Z"
                },
                "name": "fileName",
                "desc": "Select File",
                "order": 1,
                "argumentType": "File",
                "value": "3f5f04d4-23f4-4cd8-a9ba-70814952dff7"
              },
              {
                "id": "5a42272b-6402-457b-9350-4d9a8d8ac9dc",
                "fileArgument": {
                  "id": "3ae9b823-0c60-4f2c-a8d6-84ae287cb3d9",
                  "name": "bookmarkName",
                  "desc": "Enter Name For Bookmark",
                  "order": 3,
                  "options": [],
                  "argumentType": "StringEntry",
                  "created": "2024-01-11T06:03:26.055Z"
                },
                "name": "bookmarkName",
                "desc": "Enter Name For Bookmark",
                "order": 3,
                "argumentType": "String",
                "value": "RemoteIt"
              },
              {
                "id": "d6fdfd65-3083-4546-a30b-f7416e729a2c",
                "fileArgument": {
                  "id": "96bde6a5-f252-4b17-9d41-1ac0c044e895",
                  "name": "url",
                  "desc": "Enter Fully-Qualified URL",
                  "order": 2,
                  "options": [],
                  "argumentType": "StringEntry",
                  "created": "2024-01-11T06:03:25.898Z"
                },
                "name": "url",
                "desc": "Enter Fully-Qualified URL",
                "order": 2,
                "argumentType": "String",
                "value": "https://remote.it"
              }
            ]
          }
        ]
      }
    }
  }
}
```

{% endcode %}

**Job Attributes**

| Attributes  | Data Type           | Description                                                                                     |
| ----------- | ------------------- | ----------------------------------------------------------------------------------------------- |
| id          | String              | Id of the job                                                                                   |
| owner       | User                | User who owns the job/devices                                                                   |
| user        | User                | User who ran the job                                                                            |
| created     | Date                | DateTime created in ISO 8601 format Date String                                                 |
| updated     | Date                | DateTime updated in ISO 8601 format Date String                                                 |
| status      | JobStatusEnum       | FAILED,WAITING,RUNNING,SUCCESS,CANCELLED                                                        |
| tags        | Array of TagObjects | tags being used for identification of devices. If any. name is the only attribute at this time. |
| tagOperator | TagOperatorEnum     | ANY,ALL (Or/And)                                                                                |
| fileVersion | FileVersion         | the file version that was used to run the script                                                |
| jobDevices  | \[JobDevice]        | A list of job devices with status                                                               |
| arguments   | \[JobArgument]      | List of job Arguments                                                                           |

**Job Device Attributes**

| Attributes | Data Type                                    | Description                                                            |
| ---------- | -------------------------------------------- | ---------------------------------------------------------------------- |
| id         | String                                       | The primary key of the Job Device.                                     |
| device     | Device                                       | Remote.it Device                                                       |
| status     | JobStatusEnum                                | WAITING, RUNNING, FAILED, SUCCESS, CANCELLED                           |
| created    | Date                                         | DateTime of the Device was created in ISO 8601 format Date String      |
| updated    | Date                                         | DateTime of the Device was last updated in ISO 8601 format Date String |
| attributes | Array of Device Attributes applied to device | Device Attributes                                                      |

**Job Argument Attributes**

| Attributes   | Data Type       | Description                                                 |
| ------------ | --------------- | ----------------------------------------------------------- |
| name         | string          | Named used to reference the argument                        |
| desc         | string          | The string used when selecting a value for the argument.    |
| order        | int             | The order the options will be placed                        |
| argumentType | JobArgumentType | The type of argument (File or String)                       |
| value        | string          | Value selected for this job                                 |
| fileArgument | FileArgument    | <p>The FileArgument this J</p><p>obArgument is based on</p> |

**Device Attributes**

| Attribute | Data Type | Description                                                        |
| --------- | --------- | ------------------------------------------------------------------ |
| created   | Date      | DateTime of the Attributes creation in ISO 8601 format Date String |
| id        | String    | The primary key of the Job Device.                                 |
| name      | String    | Name of the attribute                                              |
| value     | String    | Value of the attribute                                             |

## Pagination

The list responses from the versions and jobs queries return paginated results. We implement a pagination model with `from`/`after` and `size` pagination arguments. Responses can return `hasMore`, `last` and `total` . If the `hasMore` response returns true, this indicates do another fetch. For example if your size is 100 and hasMore returns true, the `from` will increment to 101 to fetch the next set. You could also determine this by iteration until you get to the `total`. Size is limited to 1000 max in each return.


# CLI Usage

Remote.It CLI command reference — register devices, add and manage services, start connections and check status from the command line.

{% hint style="info" %}
The remote.it CLI has slightly different behavior if you are running as a root user versus a non-root user. In general, you will want to run as a root user, though there are a couple cases where you don't. These will be made clear.

* **On Windows**, you will need to open a "Command Prompt" as an Administrator
* **On Mac and Linux**, you must run any commands related to creating/managing a Device or Services as a root user (e.g.`sudo`)
  {% endhint %}

## Help

List the available commands.

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit help
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit help
```

{% endtab %}
{% endtabs %}

## Version

Get the version of CLI installed

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit version
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit version
```

{% endtab %}
{% endtabs %}

**Example output**

```
4.1.0
```

## Account

{% hint style="danger" %}
**With 2FA enabled,** you'll need to provide an authentication code when accessing remote.it through your browser, desktop and mobile apps. If you access remote.it using other methods, such as the API or the CLI, you'll need to sign in with credentials using an access key and secret.
{% endhint %}

### Sign In

Without the user and pass options it will prompt for the username and password.

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit account signin --user <remote.it username> --pass <password>
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit account signin --user <remote.it username> --pass <password>
```

{% endtab %}
{% endtabs %}

### Sign in with Credentials

**For accounts that have 2FA enabled OR do not have a username and password (i.e. Google sign in), you can still use the CLI**. In this situation, the CLI will use a credentials file which contains an access key and access key secret to execute all CLI commands.

Instructions for creating an access key and secret can be found [here](/developer-tools/authentication#key-management).

{% tabs %}
{% tab title="Linux/Mac" %}
{% hint style="warning" %}
If you switch to using credentials with the CLI `sudo` privileges are no longer required when running many of these commands on the device. All subsequent calls will need to be made by the same user.
{% endhint %}

Create a credentials file in the .remoteit directory of the user home directory, if it doesn't already exist.

```
remoteit account credentials add
```

You will be prompted to enter your key, secret and user defined profile name

```
key    : R3_ACCESS_KEY_ID
secret : R3_SECRET_ACCESS_KEY
profile: default
```

**Example output**

```
Active:  @ /home/user/.remoteit/credentials
 profile   | key                | value
------------------------------------------------------------
 default   | R3_ACCESS_KEY_ID   | ***************EMKU4
```

Finally, activate and enable the credentials file with the following command.

```
remoteit account credentials set --file ~/.remoteit/credentials --profile default
```

You have successfully signed in with credentials over username and password
{% endtab %}

{% tab title="Windows" %}
{% hint style="warning" %}
If you switch to using credentials with the CLI all commands can be run from a **non-adminstrative** command prompt. All subsequent calls will need to be made by the same user.
{% endhint %}

Create a credentials file in the .remoteit directory of the user account which will be using the CLI, if it doesn't already exist.

```
remoteit account credentials add
```

You will be prompted to enter your key, secret and user defined profile name

```
key    : R3_ACCESS_KEY_ID
secret : R3_SECRET_ACCESS_KEY
profile: default
```

**Example output**

```
Active:  @ /home/user/.remoteit/credentials
 profile   | key                | value
------------------------------------------------------------
 default   | R3_ACCESS_KEY_ID   | ***************EMKU4
```

You have successfully signed in with credentials over username and password
{% endtab %}
{% endtabs %}

### Sign Out

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit signout
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit signout
```

{% endtab %}
{% endtabs %}

## Device and Service

### Register

Registers this device to your account to allow access. This is not needed if you only need to initate a connection to another device. Once registered you can no longer register this device.

If you need to re-register, unregister first, then register. If you just need to move the device to another account, use transfer.

After registration, you can then add services to this device to allow other devices to connect to this device.

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit device register --name <name of your device>
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit device register --name <name of your device>
```

{% endtab %}
{% endtabs %}

### List supported application types

This is referenced in adding a new service or modifying a service

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit supportedApplications
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit supportedApplications
```

{% endtab %}
{% endtabs %}

New application types are added all of the time, but common ones are listed below.<br>

```
 ID      | Name                | Default Port   | Protocol   | Description               
-------------------------------------------------------------------------------------------
 42      | Admin Panel         | 29999          | TCP        | remote.it admin panel     
 8       | HTTPS               | 443            | TCP        | Secure web protocol       
 8       | HTTPS               | 443            | TCP        | Secure web protocol       
 8       | HTTPS               | 443            | TCP        | Secure web protocol       
 28      | SSH                 | 22             | TCP        | Secure shell terminal     
 4       | VNC                 | 5900           | TCP        | VNC remote desktop        
 34      | SMB/CIFS            | 445            | TCP        | Internet file sharing     
 32770   | WireGuard           | 51820          | UDP        | WireGuard VPN server      
 1       | TCP                 | 0              | TCP        | Generic TCP               
 7       | HTTP                | 80             | TCP        | Web protocol              
 5       | RDP                 | 3389           | TCP        | Microsoft remote desktop  
 39      | OpenVPN             | 1194           | TCP        | OpenVPN server            
 7       | HTTP                | 80             | TCP        | Web protocol              
 32769   | UDP                 | 0              | UDP        | Generic UDP               
 37      | NxWitness           | 7001           | TCP        | Nx Witness VMS            
 38      | Nextcloud           | 443            | TCP        | Nextcloud hub  
```

### List services and status on this device <a href="#cli_status" id="cli_status"></a>

You can add an option of --j or --json to output the results in JSON

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit status
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit status
```

{% endtab %}
{% endtabs %}

**Example output**

Device and services are this device information. Connections are connections from this device to other services.

```
Device:
 UID                        | Name                             | Type              | Status       | Address                 
------------------------------------------------------------------------------------------------------------------------------
 80:00:XX:XX:XX:XX:XX:C6    | My-MBP-15                        | device            | connected    | 127.0.0.1:65535         


Services:
 UID                        | Name                             | Type              | Status       | Address                  | Enabled  
-----------------------------------------------------------------------------------------------------------------------------------------
 80:00:XX:XX:XX:XX:XX:C6    | vnc                              | VNC (4)           | connected    | 127.0.0.1:5900           | true     
 80:00:XX:XX:XX:XX:XX:C6    | remoteit admin                   | Admin Panel (42)  | connected    | 127.0.0.1:29999          | true     
 80:00:XX:XX:XX:XX:XX:C6    | ssh                              | SSH (28)          | connected    | 192.168.1.60:3389        | true     


Connections:
 UID                        | Name                             | Type              | Status       | Address                                                    | Enabled   | P2P   | Failover  
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 80:55:XX:XX:XX:XX:XX:C6    | rds-mssql-replica                | TCP (1)           | ready        | someservice.at.remote.it:33002   | true      | false | false     
 80:00:XX:XX:XX:XX:XX:C6    | My SSH                           | SSH (28)          | ready        | my-ssh.at.remote.it:33003        | true      | false | false     

```

### Add a new service on this device

Adds a new service to this device. This will define a remote.it Service which is running on this machine. NOTE: This does not detect if the actual service is running on this machine. The type option will accept either the ID or Name of an application type and is not case sensitive. Available service types can be found [here](/developer-tools/cli-usage).

{% tabs %}
{% tab title="Linux/Mac" %}

```shell
sudo remoteit service add --name <service name> --port <service port> --type <application type> 
```

Example adding an SSH service

```bash
sudo remoteit service add --name "my ssh service" --port 22 --type 28
```

{% endtab %}

{% tab title="Windows" %}

```bash
remoteit service add --name <service name> --port <service port> --type <application type>
```

Example adding an SSH service

```bash
remoteit service add --name "my ssh service" --port 22 --type 28
```

{% endtab %}
{% endtabs %}

You can also add a service which connects to an application on another device on the same LAN. This is also referred to as a [jumpbox](/features/connection-options/jump-service). The host name can be either an IPv4 IP address or mDNS address (i.e. raspberrypi.local) of the device which is running the application.

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit service add --name <service name> --port <service port> --type <application type> --hostname <hostname>
```

Example of adding service to "jump" to RDP on a windows desktop on the LAN

```bash
sudo remoteit service add --name "my windows RDP" --port 3389 --type 28 --hostname "192.168.1.60"
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit service add --name <service name> --port <service port> --type <application type> --hostname <hostname>
```

Example of adding service to "jump" to RDP on windows desktop on the LAN

```bash
remoteit service add --name "my windows RDP" --port 3389 --type 28 --hostname "192.168.1.60"
```

{% endtab %}
{% endtabs %}

### Remove a service from this device

Removes a service from this device. This will cause a disconnect for all other users who had an active connection to this service. If you are concerned about the disconnect, you can use the graphQL API to fetch active connection to this service and then notify users accordingly. Use the [status command](#list-services-on-this-device) to get the service ID.

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit service remove --id <service id>
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit service remove --id <service id>
```

{% endtab %}
{% endtabs %}

### Modify a service on this device

Modifies a service on this device. This will cause a disconnect for all other users who had an active connection to this service. If you are concerned about the disconnect, you can use the graphQL API to fetch active connection to this service and then notify users accordingly.

The enabled option disables the service without deleting it. The hostname option will modify a service which connects to an application on another device on the same LAN. The host name can be either an IPv4 IP address or mDNS address (i.e. raspberrypi.local) of the device which is running the application. The type option will accept either the ID or Name of an application type and is not case sensitive. Available service types can be found [here](/developer-tools/cli-usage).

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit service modify --id <service id> --enable <boolean> --port <port> --hostname <hostname> --type <application type> 
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit service modify --id <service id> --enable <boolean> --port <port> --hostname <hostname> --type <application type> 
```

{% endtab %}
{% endtabs %}

## Creating Connections

Once you have created a service on a **target device** you can generate a a persistent address on demand connection from the CLI on your **initiator** device. This requires the service id and **local port**. Verify there are not other connections on the local port before generating. Learn more about [peer to peer vs proxy](/features/connection-options/peer-2-peer-and-proxy). The connection will be attempted as peer to peer (p2p) first with a proxy failover if allowed. In some cases such as https and http it will be a reverse proxy connection.

Below is a general connection add command for a peer to peer connection.

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit connection add --id <service id> --port <port> --p2p true
```

The connection will be generated in the background. Run the [status command](#list-services-on-this-device) to retrieve the generated url in the Address column

```
sudo remoteit status
 ✓ Fetching status

Connections:
 UID                     | Name         | Type    | Status | Address                                                | Enabled | P2P  | Failover  
----------------------------------------------------------------------------------------------------------------------------------------------
 80:07:06:01:20:30:40:50 | service name | SSH (28)| online | <device_name>-<service_name>.at.remote.it:<local_port> | true    | true | false 
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit connection add --id <service id> --port <port> --p2p true
```

The connection will be generated in the background. Run the [status command](#list-services-on-this-device) to retrieve the generated url in the Address column.

```
remoteit status
 ✓ Fetching status

Connections:
 UID                     | Name         | Type    | Status | Address                                                | Enabled | P2P  | Failover  
----------------------------------------------------------------------------------------------------------------------------------------------
 80:07:06:01:20:30:40:50 | service name | SSH (28)| online | <device_name>-<service_name>.at.remote.it:<local_port> | true    | true | false 
```

{% endtab %}
{% endtabs %}

## Unregister This Device

Unregister this device from your account and removes the services. This will also remove access to this device for any users to which you have shared this device. This will cause a disconnect for all other users who had an active connection to this service as well. If you are concerned about the disconnect, you can use the graphQL API to fetch active connection to this service and then notify users accordingly. Once unregistered, this device can be registered again.

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit unregister --yes
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit unregister --yes
```

{% endtab %}
{% endtabs %}

## Transfer

Transfer this device and defined services to another account. This will remove your access to this device along with any users to which you had previously shared this device. This will cause a disconnect for all other users who had an active connection to this service. If you are concerned about the disconnect, you can use the graphQL API to fetch active connection to this service and then notify users accordingly. **If the account doesn't exist, the transfer will fail.** If this is the case, you can sign-in to the [web portal](https://link.remote.it/portal/contacts) and create the contact and then transfer the device from the devices list.

{% hint style="warning" %}
Verify the email address used for the transfer is correct. This device will transfer to the email address provided and cannot be undone. The new owner would need to transfer the device back to you.
{% endhint %}

{% tabs %}
{% tab title="Linux/Mac" %}

```bash
sudo remoteit transfer --to <email address>
```

{% endtab %}

{% tab title="Windows" %}

```
remoteit transfer --to <email address>
```

{% endtab %}
{% endtabs %}

## More

CLI has many more functions, examples provided here are the most common. You can use [help](#help) to explore other functions supported by your version such as graphQL query helper, upgrades, and more.


# Webhooks

Receive HTTP push notifications when your devices go online or offline, and build integrations on top of Remote.It webhooks.

remote.it supports **webhooks** which allow you to receive HTTP push notifications for device online/offline notifications. This allows you to build integrations on top of remote.it. Some examples are to perform debug operations on devices which go offline, send messages, or check for the device IP change when it comes online.

Your webhook consumer is a simple HTTP endpoint. It is not an email address or a general website url. It must satisfy the following conditions:

* It's available in a publicly accessible HTTPS, non-localhost URL
* It will respond to the remote.it Webhook push (HTTP POST request) with a `HTTP 200` ("OK") response within 5 seconds

If a delivery fails (i.e. server unavailable or responded with a non-200 HTTP status code), the push might subsequently be retried a couple of times. If the webhook URL continues to be unresponsive the webhook might be disabled by remote.it, and must be re-enabled again manually.

For additional information on Webhooks, you can use any of these resources:

* [RequestBin: Webhooks – The Definitive Guide](https://requestbin.com/blog/working-with-webhooks/)
* [requestbin.com](https://requestbin.com/) is a great tool for testing webhooks
* [GitHub Developer Guide: Webhooks](https://developer.github.com/webhooks/)

## Enabling a Webhook

You can add a webhook endpoint to your account, by signing in to your account and navigating to the account page. Select the types of notifications you to which you wish to subscribe and enter the webhook url.

{% hint style="info" %}
A webhook url is not a email address or a general website url. If you wish to receive email notifications select the email checkbox. It is also a VARCHAR 255 field.
{% endhint %}

<figure><img src="/files/4YTmKEMt9rTP95N9Er7y" alt="Account notification settings with webhook URL field and subscription checkboxes"><figcaption></figcaption></figure>

## Whats in the Webhook?

The body of a webhook call contains the latest state information of the device or service. This can be recorded in a database to review later. You will receive unique webhook notifications for the device and each service registered to that device when their state changes.

| Value   | Description                                               |
| ------- | --------------------------------------------------------- |
| Address | Public IP Address of the device/service                   |
| Device  | Unique ID of the device or service                        |
| Email   | Email address of the owner of the device                  |
| Name    | Name of the device or service                             |
| State   | {online/offline} state being recorded                     |
| Time    | When the state change happened in UTC time string format. |
| Type    | Type of state change that happened                        |

## Notification Latency

* Online notifications will be sent almost immediately.
* Offline notifications will be sent almost immediately, if the system was shutdown or rebooted using specific "shutdown" or "reboot" commands. Using command line options to stop and start the connectd daemons directly will also send notifications immediately.
* If the reason for your device going offline is an unexpected interruption of power or internet connection, it may take up to 15 minutes to receive the offline notification.


# Slack Integration

Send Remote.It device online and offline notifications to a Slack channel by creating a Slack app with an incoming webhook.

The following is how to set up Slack to receive online/offline notifications for your devices using a webhook. We will be creating an app in Slack and configuring it to as a webhook, then use the webhook url generated by Slack in remote.it

This example assumes you already have the Slack app set up and Slack workspace (account) and a channel where these messages will be sent.

{% hint style="info" %}
It is recommended that you have a dedicated channel to receive these messages so that you can control the message notifications.
{% endhint %}

## Create the Slack App

Please note that Slack may update their UI. If so, please refer to their documentation on how to create a new App with a webhook.

1. In a browser, go to <https://api.slack.com/apps?new_app=1>
2. Select "From Scratch"
3. Name your App and select the Slack workspace where want to send messages. Then click on "Create App"
4. Next, under "Settings" in the left nav, click on "Incoming Webhooks"
5. Activate Incoming Webhooks by switching it to "On"
6. Scroll down and click "Add a New Webhook to Workspace"
7. Select the channel you would like to receive the messages and finish.
8. Copy the webhook url. You will use this when you configure your webhook in remote.it

## Configure the webhook in remote.it

1. Open the Settings link and then Notifications tab <https://app.remote.it/#/settings/notifications>
2. Make sure the checkbox for webhook is selected, paste in the webhook url and save.

<figure><img src="/files/5HZ8pL6EowZIrygA5Or6" alt="Remote.It notification settings with the Slack webhook URL pasted into the webhook field"><figcaption></figcaption></figure>

Congratulations! You now will be receiving notifications on your device status changes.


# Docker Video Walkthroughs

Video walkthroughs of the Remote.It Docker Desktop Extension, including running it as a standalone container on an ECS cluster.

Here is a video on the Docker Desktop Extension.

{% embed url="<https://youtu.be/P020hGVcCOE>" %}

Here is the Docker Extension running as a separate container on an ECS cluster.

{% embed url="<https://youtu.be/ZXOPhBRrb58>" %}


# Device Scripting

Run unattended scripts across any number of Linux or Windows devices with the Remote.It GraphQL API — in bash, Python, Ruby, Node or any installed language.

## Overview

Scripting is a feature that allows you to run a script unattended (written in any interpreted language you have installed on your Operating System) on any number of devices with a Linux or Windows based operating system.

This is useful when you have a repetitive action that you would like to perform on one or more devices.

{% hint style="warning" %}
These examples are for graphQL API scripting and do not apply to legacy.app.remote.it UI scripting. **legacy.app.remote.it is deprecated and you should use this method.**
{% endhint %}

## Creating Scripts

Remote.It allows you to write scripts in any language your host operating system supports because the script is run just like any other executable script on your machine. This means you can write in bash, Python, Ruby, Node, etc., assuming you have the interpreter installed on your system. Scripts are executed as root.

#### Hello world script returning a value to Remote.It:

```bash
#!/bin/bash

Attribute() {
    ATTRIBUTE_NAME="$1"
    ATTRIBUTE_VALUE="$2"

    # Send the data to the API, including jobDeviceId and attributeName in the URL
    curl -X POST "https://${GRAPHQL_API_PATH}/job/attribute/$JOB_DEVICE_ID/$ATTRIBUTE_NAME" \
         -H "Content-Type: text/plain" \
         --data "$ATTRIBUTE_VALUE"
}

Attribute hello "world"
Attribute hostname "$(hostname)"
```

#### More example shell scripts can be found at our github repository:

<https://link.remote.it/github/scripts>

{% hint style="warning" %}
Files must be able to be uploaded in 30 seconds. If you need to have larger files, consider hosting at another location such as S3 and having your script fetch them.
{% endhint %}

Scripts can also have arguments which you can pass. Arguments can be created by placing commented lines like this in your code:

<pre><code># The following defines arguments for selecting a file, entering a string or selecting from a list of strings:
<strong># These arguments are optional and can be removed if not needed.
</strong># Once defined their values can be accessed  via their name in the script (e.g., $textFile, $url, $name, $action)
# &#x3C;arguments>, &#x3C;type>, &#x3C;name>, &#x3C;prompt>, &#x3C;option1>, &#x3C;option2>, ... 
# r3_argument, FileSelect, textFile, Select File, .txt
# r3_argument, StringEntry, url, Enter Fully-Qualified URL
# r3_argument, StringEntry, name, Enter a Name
# r3_argument, StringSelect, action, Choose Action, ADD, REMOVE
</code></pre>

These arguments can then be used as environment variables in you code. See script examples for usage.

## API

**Below is a quick reference and not all functions are listed here. For full documentation, including working with scripting in an organization, please see** [**Scripting API**](/developer-tools/api/usage/scripting)**. You can also download and use our examples for** [**Insomnia**](/developer-tools/api/using-developer-tools#insomnia-set-up) **and** [**Postman**](/developer-tools/api/using-developer-tools#postman-set-up)**.**

## Uploading a Script

You can upload files using a multi form post to be run as a script or a file to be used by your scripts. Setting the executable flag will determine if the file can be run as a script ([see scripting API docs](/developer-tools/api/usage/scripting)).

```
curl --request POST \
  --url https://api.remote.it/graphql/v1/file/upload \
  --header 'Authorization: ' \
  --header 'Content-Type: multipart/form-data' \
  --header 'Date: Thu, 23 May 2024 00:32:27 GMT' \
  --header 'Host: api.remote.it' \
  --header 'User-Agent: insomnia/8.5.1' \
  --form file=@/Users/ebowers/Documents/remoteit/scripting/final/script_example_no_args.sh \
  --form executable=true \
  --form 'shortDesc=New Script Example No Args' \
  --form 'longDesc=This is a new script that has no args as an example'
```

**You must be the account owner or if you belong to an organization, an admin on the account to upload a file. For full documentation, please see** [**Scripting API**](/developer-tools/api/usage/scripting)**.**

Files must be able to be uploaded in 30 seconds. If you need to have larger files, consider hosting at another location such as S3 and having your script fetch them.

## Running a Script

You can run your recent uploaded script with a graphQL mutation. **This is a quick reference. For full documentation, please see** [**Scripting API**](/developer-tools/api/usage/scripting)**.**

### View files

```graphql
query GetFiles {
  login {
    account {
      id
      files {
        id
        name
        shortDesc
        longDesc
        lastVersion {
          id
          version
        }
        executable
      }
    }
  }
}
```

### Run Script without arguments

```graphql
mutation execute {
  startJob(
    deviceIds: ["80:00:00:00:01:22:37:AE"]
    fileId: "b0fd8a0f-2850-4be3-88cd-b554551e4dd4"
  )
}
```

### Run Script with arguments

**This is a quick reference. For full documentation, please see** [**Scripting API**](/developer-tools/api/usage/scripting)**.**

```graphql
mutation execute {
  startJob(
    deviceIds: ["80:00:00:00:XX:XX:XX:XX"]
    fileId: "5539cee9-3bea-4c04-add6-bd7c2aff12df"
    arguments: [
      { name: "url", value: "https://remote.it" }
      { name: "textFile", value: "6b69b085-5507-468f-93c2-d64cdd40eb8e" }
      { name: "name", value: "RemoteIt" }
      { name: "action", value: "Add" }
    ]
  )
}
```

## Get Script/Job Status

You can query for scripts status using the API. Attributes and Status set during the script will appear in the attribute list for the job. Filtering and sorting is available. **This is a quick reference. For full documentation, please see** [**Scripting API**](/developer-tools/api/usage/scripting)**.**

```graphql
query GetJobs {
  login {
    jobs {
      hasMore
      total
      items {
        id
        created
        status
        fileVersion {
          id
          file {
            id
            name
          }
        }
        jobDevices {
          id
          device {
            id
            name
          }
          attributes {
            key
            value
          }
          status
        }
      }
    }
  }
}
```


# Zero-Trust AWS Access

Use an EC2 instance as a jump server to reach databases, Kubernetes and other VPC services with zero inbound security group rules and no open ports.

You can use an EC2 instance as a Jump server to other services running in the same VPC, such as a database or Kubernetes cluster. You can also add remote.it access to any services which are running on an existing EC2 instance. Setup only takes a couple of minutes. You can do all of this without any inbound rules in the AWS security groups, thereby blocking all ingress traffic and eliminating open ports to the internet.

With the target services setup such as databases, storage and web applications, you can simply add authorized users via email address in the Remote.It application. This works well with your remote workers and contractors by eliminating the need for IP allow lists to be maintained. It also works on CGNAT connections where your team may be connected via a cellular or satellite carrier where IP addresses are not known or are transient. For more information on Organizations, [click here](https://link.remote.it/support/organizations).

{% embed url="<https://youtu.be/6kv_EYkfiyY>" %}

## Creating a EC2 instance with Remote.It

You will need:

* A Remote.It account
* Remote.It Desktop Application (version 3.5.2 or greater)
* AWS console access to the account where you will setup the instance

### 1. Retrieve your Remote.It one line setup code

Log into the Remote.It Desktop App with the account which will act as owner of the instance

Click + (add device) and select "Linux & Raspberry Pi"<br>

<figure><img src="/files/JhIWbnMGHLk5TLmuTHpV" alt="Selecting Linux &#x26; Raspberry Pi from the Add Device menu in the Remote.It Desktop app"><figcaption></figcaption></figure>

Copy the generated command (You will be using this in your EC2 setup)<br>

<figure><img src="/files/oJKoOwxpl5rdjQhyEQ64" alt="The generated one-line Remote.It setup command ready to copy"><figcaption></figcaption></figure>

### 2. Launch your EC2 instance

Log into AWS console account

Select the region and go the the EC2 dashboard

Select "Launch Instance"

Enter name for the instance and leave the defaults for the Application and OS images (Amazon Linux 2)

The instance type can be left at t2.micro (if this instance is being used as a bastion host)

Select a key pair that you already have setup or create a new key pair

Deselect the checkbox for "Allow SSH traffic from" (you do not need public access with Remote.It)

Open "Advanced details"

In the "User data", field enter `#!/bin/sh` + return and your previously copied command from Remote.it<br>

<figure><img src="/files/y0mo3k5FPSQR6zLJm52L" alt="The EC2 Advanced details User data field containing the Remote.It install command"><figcaption></figcaption></figure>

Click "Launch Instance"

Once the EC2 instance initializes and is running it should automatically appear in your Remote.It device list with an SSH service.

**Congratulations, you are now ready to connect via SSH or continue on to** [**add other services**](#3.-add-other-services-optional-1) **or** [**share**](#4.-share-with-colleagues-optional-1)

## Install remote.it on an existing EC2 instance

You will need:

* A Remote.It account
* Remote.It Desktop Application (version 3.5.2 or greater)
* SSH access to the EC2 instance

### 1. Retrieve your Remote.It one line setup command

Log into the Remote.It Desktop App with the account which will act as owner of the instance

Click + (add device) and select "Linux & Raspberry Pi"<br>

<figure><img src="/files/JhIWbnMGHLk5TLmuTHpV" alt="Selecting Linux &#x26; Raspberry Pi from the Add Device menu in the Remote.It Desktop app"><figcaption></figcaption></figure>

Copy the generated command (You will be using this in your EC2 setup)<br>

<figure><img src="/files/oJKoOwxpl5rdjQhyEQ64" alt="The generated one-line Remote.It setup command ready to copy"><figcaption></figcaption></figure>

### 2. Install remote.it

SSH into your EC2 instance

Paste the generated command into your terminal and enter

This will automatically install Remote.It, register the EC2 instance to your account, and setup the SSH service in Remote.It

Once the installation is complete, it will automatically appear in your Remote.It device list with an SSH service.

**Congratulations!** You are now ready to connect via SSH or continue on to [add other services](#3.-add-other-services-optional-1) or [share](#4.-share-with-colleagues-optional-1). You can also close any external inbound security groups which have IP allow lists once you share to anyone who needs access.

## Add other services (optional)

You can add additional services that are either on the instance (i.e. web server) or a jump target to a service in the VPC such as a database which will allow you to connect directly as localhost.

### Add a jump service

Examples are not limited to the ones provided. As long as you have an internal route from the EC2 instance to the target, you can add anything. You can look at any of the examples for a general guide. If you need further assistance, contact <support@remote.it>

* [RDS](/developer-tools/zero-trust-aws-access/aws-rds-postgres-and-mysql) (Postgres and MySQL)
* More examples coming soon!

### Add a service which is running on the EC2 instance

Use this option when you want to add access to a service(port) which is on the instance itself such as a web server.

Select the instance from the device list

Click + (Add Service)

<figure><img src="/files/W3KiXECPzdPZwMaO1PAG" alt="The Add Service button on the selected EC2 instance in the Remote.It device list"><figcaption></figcaption></figure>

Select the service type from the list and name the service

Verify the port (will default to the standard port for that type)

Click "Save"

The service will be available in a few moments.

#### You are ready to connect!

## Share with colleagues (optional)

You can also share access to this instance and even only to specific services.

[Learn more about organizations](https://link.remote.it/support/organizations)

[Learn more about sharing](https://link.remote.it/docs/sharing)


# AWS RDS (Postgres and MySQL)

Reach an AWS RDS Postgres or MySQL instance through an EC2 bastion host with Remote.It — no public accessibility required.

Building off the setup of an EC2 instance, you can use it as a bastion host to "jump" to other services in the VPC. One of these types of services can be an RDS (managed relational database). The advantage is that you do not have to make it publicly accessible and still have access yourself.<br>

This allows the developers to work with the database with their tools and in their local development environments as if the database were running locally even when the database has multiple availability zones.

{% hint style="info" %}
The RDS instance must have a VPC security group assigned which allows the EC2 instance a path to the RDS instance.
{% endhint %}

To get started you will need:

* A Remote.It account which owns the EC2 device or management rights to the device
* Remote.It Desktop Application (version 3.5.2 or greater)
* AWS console access to the RDS instance

1. Open your AWS Console to the database instance page.
2. Copy the Endpoint address (internal DNS name) and note the port. See image below

<figure><img src="/files/4EH30RnMFxWDr3F6cH52" alt="The AWS RDS console showing the database instance endpoint address and port"><figcaption></figcaption></figure>

3\. In the Remote.It Desktop App, select the instance from the device list

4\. Click + (Add Service)

<figure><img src="/files/W3KiXECPzdPZwMaO1PAG" alt="The Add Service button on the selected EC2 instance in the Remote.It device list"><figcaption></figcaption></figure>

5\. Select the service type from the list and name the service (Many options are available, if you do not see the type you need, you can select TCP), name your service so you can identify it in the future from the list.

6\. Verify the port which will default to the standard port for the service type. If you have changed it, update it to match what is shown in your AWS Console.

7\. In the Service Host Address field, which is pre-populated with "127.0.0.1", paste the address you copied from the AWS console.

<figure><img src="/files/BKww8vl9qSauRbf8mUId" alt="Service configuration with the RDS endpoint pasted into the Service Host Address field"><figcaption></figcaption></figure>

8\. Click "Save". In a few moments the service will become available and is ready to connect.


# Zero Trust Azure Cloud Access

Use an Azure Virtual Machine as a jump server to reach databases, Kubernetes and other VNet services with no inbound rules and no open ports.

You can use a Virtual Machine as a Jump server to other services running in the same VNet, such as a database or Kubernetes cluster. You can also add Remote.It access to any services which are running on an existing Virtual Machine instance. Setup only takes a couple of minutes. You can do all of this without any inbound rules in the security groups, thereby blocking all ingress traffic and eliminating open ports to the internet.

With the target services setup such as databases, storage and web applications, you can simply add authorized users via email address in the Remote.It application. This works well with your remote workers and contractors by eliminating the need to maintain IP allow lists. It also works on CGNAT connections where your team may be connected via a cellular or satellite carrier where IP addresses are not known or are transient. For more information on Organizations, [click here](https://link.remote.it/support/organizations).

This allows the developers to work with the database with their tools and in their local development environments as if the database were running locally even when the database has multiple availability zones.

{% hint style="success" %}
We have a [video tutorial available at YouTube](https://link.remote.it/youtube/azure). Written step by step guide is coming soon.
{% endhint %}

{% embed url="<https://youtu.be/L1REB9l6-DE>" %}


# Zero Trust Google Cloud Access

Use a Google Compute Engine instance as a jump server to reach databases, Kubernetes and other VPC services with no inbound rules and no open ports.

You can use a Compute Engine instance as a Jump server to other services running in the same VPC, such as a database or Kubernetes cluster. You can also add Remote.It access to any services which are running on an existing Compute Engine instance. Setup only takes a couple of minutes. You can do all of this without any inbound rules in the security groups, thereby blocking all ingress traffic and eliminating open ports to the internet.

With the target services setup such as databases, storage and web applications, you can simply add authorized users via email address in the Remote.It application. This works well with your remote workers and contractors by eliminating the need for IP allow lists to be maintained. It also works on CGNAT connections where your team may be connected via a cellular or satellite carrier where IP addresses are not known or are transient. For more information on Organizations, [click here](https://link.remote.it/support/organizations).

This allows the developers to work with the database with their tools and in their local development environments as if the database were running locally even when the database has multiple availability zones.

{% hint style="success" %}
We have a [video tutorial available at YouTube](https://link.remote.it/youtube/gcp). Written step by step guide is coming soon.
{% endhint %}

{% embed url="<https://youtu.be/08iVlL8JWVU>" %}


# MCP Server Overview

The hosted Remote.It MCP server lets AI assistants like Claude inventory devices, open connections, manage services and run scripts on your fleet.

The Remote.It MCP server lets AI assistants like Claude work with your Remote.It account directly — inventory your devices, open and close connections, manage services and networks, and (when enabled) run scripts on your fleet, all through natural conversation.

It is a hosted [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server: there is nothing to install or run locally. You add it to your AI assistant as a connector, sign in with your Remote.It account, and the assistant gains a set of Remote.It tools it can use on your behalf.

{% hint style="warning" %}
**Preview release.** The MCP server is currently in preview at:

```
https://mcp.demo.remote.it/mcp
```

This URL will change when the server is fully released. Check back here for the final address.
{% endhint %}

## What can it do?

Once connected, you can ask your AI assistant things like:

* "Which of my devices are offline right now?"
* "Connect to SSH on my office Raspberry Pi"
* "How much bandwidth did my gateway use this week?"
* "Tag all my lab devices and share them with <alex@example.com>"
* "Run the update script on every device tagged `production`"

The assistant translates these into calls to Remote.It tools — the same operations available in the [web portal](https://app.remote.it) and [Desktop app](/software/desktop), scoped to your account and permissions. See the [Tool Reference](/mcp-server/tools) for the full list.

## How access works

* **Sign in with OAuth — no API keys.** When your assistant first uses the connector, you sign in through your browser with your normal Remote.It account (including social sign-in and 2FA). You never paste keys or secrets into the assistant.
* **You choose what to grant.** The consent screen lets you limit what the assistant can do — for example, read-only access to devices without the ability to connect or make changes. See [Permissions & Safety](/mcp-server/permissions-and-safety).
* **Your existing permissions still apply.** The assistant can never do more than your Remote.It account can. Organization roles and device permissions are enforced on every call.
* **Destructive actions are confirm-gated.** Deleting devices, running scripts, and similar operations require an explicit confirmation step.

## Get started

You'll need:

* **A Remote.It account** — [sign up for a free account](https://app.remote.it/#/sign-up) that will let you access up to 5 devices.
* **An MCP-capable AI assistant**, such as Claude.

Then:

* [Connect Claude](/mcp-server/connect-claude) — add the connector to Claude on web, desktop, mobile, or Claude Code
* [Tool Reference](/mcp-server/tools) — every tool the server exposes
* [Permissions & Safety](/mcp-server/permissions-and-safety) — scopes, consent, and safety gates

The server works with any MCP client that supports the Streamable HTTP transport and OAuth 2.1 authorization, so other MCP-capable apps can connect the same way.


# Connect Claude

Add Remote.It as a connector in Claude so it can inventory and manage your devices in conversation, using OAuth sign-in with no API keys.

This guide adds Remote.It as a connector in Claude, so Claude can see and manage your devices in conversation.

{% hint style="warning" %}
**Preview release.** Use the preview URL below for now. It will change when the MCP server is fully released.

```
https://mcp.demo.remote.it/mcp
```

{% endhint %}

## Claude web & desktop

Custom connectors are configured once in your Claude settings and are then available in Claude on the web (claude.ai), the desktop apps, and mobile.

{% hint style="info" %}
Custom connectors require a paid Claude plan (Pro, Max, Team, or Enterprise). On Team and Enterprise plans, an admin may need to add the connector for the organization.
{% endhint %}

{% stepper %}
{% step %}

## Add the connector

Open [claude.ai](https://claude.ai) and go to **Settings** → **Connectors**, then click **Add custom connector**. Enter a name (e.g. `Remote.It`) and the server URL:

```
https://mcp.demo.remote.it/mcp
```

Click **Add**.
{% endstep %}

{% step %}

## Sign in to Remote.It

Claude opens a browser window to sign in. Use your normal Remote.It account (social sign-in and 2FA work as usual), then review the consent screen — this is where you choose what the assistant may do (see [Permissions & Safety](/mcp-server/permissions-and-safety)).
{% endstep %}

{% step %}

## Enable it in a conversation

Back in Claude, start a new conversation and make sure the Remote.It connector is enabled in the tools menu (the sliders icon in the chat input).
{% endstep %}
{% endstepper %}

Try it out:

> Which of my devices are online?

## Claude Code

Add the server with one command:

```bash
claude mcp add --transport http remoteit https://mcp.demo.remote.it/mcp
```

The first time a Remote.It tool is used, Claude Code walks you through the same browser sign-in. Use `/mcp` inside Claude Code to check connection status or re-authenticate.

## Other MCP clients

Any MCP client that supports the **Streamable HTTP** transport with **OAuth 2.1** authorization can connect using the same URL — no client registration or API keys required. Consult your client's documentation for adding a remote MCP server.

## Troubleshooting

* **Sign-in window doesn't appear** — pop-up blockers can suppress the OAuth window. Allow pop-ups for your Claude client and retry.
* **Claude says it has no Remote.It tools** — check that the connector is enabled for the current conversation in the tools menu, then start a new conversation.
* **"No devices found" but you have devices** — you may have granted limited access at sign-in. Remove the connector and add it again to re-run consent with broader access.
* **Connector stopped working** — during the preview period the server URL may change. Check this page for the current URL.


# Tool Reference

Every tool the Remote.It MCP server exposes to your AI assistant — devices, connections, services, networks and scripting — and which ones need approval.

The tools the Remote.It MCP server exposes to your AI assistant. You normally never call these directly — the assistant chooses them based on what you ask — but knowing what's available helps you know what you can ask for.

All tools operate within your account's permissions and the scopes you granted at sign-in (see [Permissions & Safety](/mcp-server/permissions-and-safety)). Tools marked ⚠ are destructive or execute code, and require an explicit confirmation step before they run.

## Account & context

| Tool            | Description                                                                                                   |
| --------------- | ------------------------------------------------------------------------------------------------------------- |
| `whoami`        | Your identity, active organization, and permissions                                                           |
| `graphql_query` | Read-only access to the full [GraphQL API](/developer-tools/api) for anything not covered by a dedicated tool |
| `search_schema` | Search the GraphQL schema by keyword to discover available data                                               |

## Devices & services

| Tool                                | Description                                                          |
| ----------------------------------- | -------------------------------------------------------------------- |
| `list_devices`                      | List and filter devices (state, platform, tags, and more)            |
| `get_device`                        | Full detail for one device, including its services                   |
| `get_device_sessions`               | Connection history for a device — durations, bandwidth used, latency |
| `claim_device`                      | Claim a new device by claim code                                     |
| ⚠ `delete_device`                   | Remove a device from your account                                    |
| `share_device`                      | Share a device with another Remote.It user                           |
| `transfer_device`                   | Transfer device ownership to another account                         |
| `add_service`                       | Add a service (SSH, HTTP, RDP, …) to a device                        |
| `update_service` / `rename_service` | Change a service's configuration or name                             |
| ⚠ `remove_service`                  | Remove a service from a device                                       |

## Connections

| Tool                    | Description                                                                                     |
| ----------------------- | ----------------------------------------------------------------------------------------------- |
| `open_connection`       | Open a connection to a service and return the endpoint to use                                   |
| `close_connection`      | Close an open connection                                                                        |
| `set_connect_link`      | Create or update a persistent public [connect link](/features/connection-options) for a service |
| ⚠ `remove_connect_link` | Remove a connect link                                                                           |

## Organization: tags & networks

| Tool                                                   | Description                                        |
| ------------------------------------------------------ | -------------------------------------------------- |
| `list_tags` / `add_tags` / `remove_tags`               | View and manage device tags                        |
| `list_networks`                                        | List your [networks](/features/connection-options) |
| `create_network` / `update_network`                    | Create or modify a network                         |
| ⚠ `delete_network`                                     | Delete a network                                   |
| `add_network_connection` / `remove_network_connection` | Add or remove services in a network                |

## Scripting & jobs

Scripting tools are only available when your account and the target devices have the Scripting permission. Executing a script always requires confirmation. See [Device Scripting](/developer-tools/device-scripting).

| Tool                          | Description                                        |
| ----------------------------- | -------------------------------------------------- |
| `list_scripts` / `get_script` | Browse your uploaded scripts                       |
| `create_script`               | Upload a new script                                |
| ⚠ `run_script`                | Execute a script on selected devices or tags       |
| `list_jobs` / `get_job`       | Track script job status per device                 |
| `get_job_logs`                | Read the output a script reported from each device |
| `cancel_job`                  | Cancel a running job                               |
| ⚠ `delete_job`                | Delete a finished job's records                    |

## Products (OEM & bulk provisioning)

For accounts using [bulk provisioning](/oem-and-bulk-provisioning/overview).

| Tool                                             | Description                              |
| ------------------------------------------------ | ---------------------------------------- |
| `list_products`                                  | List your products                       |
| `create_product` / `update_product`              | Create or modify a product definition    |
| ⚠ `delete_product`                               | Delete a product                         |
| `transfer_product`                               | Transfer a product to another account    |
| `add_product_service` / `remove_product_service` | Manage the services a product provisions |


# Permissions & Safety

How the Remote.It MCP server protects your infrastructure — OAuth 2.1 scopes, your existing account permissions, and confirmation gates on risky operations.

Giving an AI assistant access to your infrastructure deserves clear guardrails. The Remote.It MCP server is built around three layers of protection: **OAuth scopes** you grant at sign-in, **your existing account permissions**, and **confirmation gates** on dangerous operations.

## OAuth sign-in — no API keys

The MCP server uses standard OAuth 2.1 authorization. When your assistant connects for the first time, you sign in to Remote.It in your own browser — with your usual credentials, social sign-in, and 2FA. The assistant only ever receives a scoped access token; your password and account keys are never shared with it.

You can revoke access at any time by removing the connector from your AI client.

## Scopes: choose what to grant

At sign-in, the consent screen shows the access being requested. Device access is split into independent scopes, so you can grant exactly as much as you're comfortable with:

| Scope            | Allows the assistant to…                                                       |
| ---------------- | ------------------------------------------------------------------------------ |
| `device:read`    | View devices, services, networks, tags, and history                            |
| `device:connect` | Open and close connections to services                                         |
| `device:write`   | Modify devices, services, networks, tags, and sharing                          |
| `device:execute` | Use scripting tools (still gated by the Scripting permission and confirmation) |

A token that lacks a scope simply cannot perform those operations — for example, a read-only grant lets the assistant inventory and monitor your fleet but never connect to it or change it.

{% hint style="info" %}
**Scopes only subtract — they never add.** Granted scopes are intersected with what your Remote.It account can already do. An assistant signed in to a member account with view-only role in an organization gets view-only access to that organization's devices, no matter what scopes were granted.
{% endhint %}

## Organization roles still apply

Every tool call is checked against the same [organization roles and permissions](/features/organizations) that govern the web portal and Desktop app. Device visibility, connect rights, management rights, and scripting rights per organization all carry through unchanged.

## Confirmation gates

Tools that are destructive or execute code require the assistant to pass an explicit confirmation flag, which well-behaved assistants like Claude will only do after checking with you. These include:

* Deleting a device, network, product, or job records
* Removing a service or connect link
* Running a script on devices

## Scripting is opt-in by permission

Script execution is the highest-impact capability, so it stacks every gate:

1. Your granted scopes must include `device:execute`.
2. Your account role must have the **Scripting** permission for the organization, and it applies per target device.
3. Every `run_script` call requires explicit confirmation.

If any layer is missing, scripting tools are simply unavailable to the assistant.

{% hint style="warning" %}
Even with guardrails, treat an AI assistant with write access like any other operator on your account: grant the least access that does the job, use read-only scopes for monitoring use cases, and review what your assistant proposes before confirming destructive actions.
{% endhint %}


# OEM & Bulk Provisioning Overview

Bulk registration methods for OEMs shipping devices at scale — register into your own account with pre-configured services, or into an end user's account.

These methods of installation and registration only apply to devices which will serve as connection endpoints and NOT as connection initiators. Do not worry, we are working on the initiator feature.

These are the scenarios supported:

* [Registration with Pre-configured Services](/oem-and-bulk-provisioning/auto-registration-into-your-account/registration-with-pre-configured-services): Devices which are the same hardware, software and service configuration that will be registered into your account.
* [Registration into a User's Account](/oem-and-bulk-provisioning/registration-into-a-users-account): Devices which have the same hardware and OS architecture, but other installed software and service configurations may be different, but you wish to be registered into your account or another user's account (other user's accounts can be different for each device) - this may be the case for something like a jumpbox or router. In this case, the user will need to additionally setup services using the Desktop Application after registration.


# Auto Registration into Your Account

Two ways to register manufactured devices into your own Remote.It account — a production image written at manufacturing time, or a per-device field command.

You can register devices to your account using two methods:

1. **Production Image:** Create a production image to load onto multiple devices during manufacturing. These devices will automatically register when you determine. This method is more complex and recommended for experienced software developers.
2. **Field Production or Installation Individually:** Execute a command on each device to install with a custom name, pre-defined services (device template), and, if desired, a fixed version.

Both methods require a [Product](/oem-and-bulk-provisioning/auto-registration-into-your-account/create-a-product).


# Create a Product

Define a Remote.It product — the reusable service template (HTTPS, HTTP, SSH, RDP and more) applied to every device you bulk register.

## **Product Creation**

1. Visit[ app.remote.it](https://app.remote.it) or the Desktop and go to the sidebar and press → Products.
2. Click **+ Create** in the top-right. (If you don't have any products yet, you can also use the **+ Create Your First Product** button in the center of the page.)
3. Enter a **Product Name** and select a **Platform**, then click **Create Product**. The product is created in **Draft** status with no services defined.
4. On the product page, click the **+** next to **SERVICE** to add a service.
5. In the **New service** panel:

   * Choose the protocol using the tabs — **HTTPS**, **HTTP**, **SSH**, **RDP**, or **More** for additional service types.
   * Enter the service's connection details in the field provided. What you enter depends on the service type you selected — for web protocols like **HTTPS** or **HTTP**, enter the full URL (for example, `https://127.0.0.1` or `https://localhost:8001/api/dashboard`); for **SSH**, **RDP**, and similar, enter the host name or IP address of the target device.
   * Optionally enter a **Service Name**.
   * The **Enable service** checkbox (checked by default) sets whether the service is active: when enabled, it comes online and is reachable; when disabled, it's added to the product but stays offline until you enable it. In most cases, leave it enabled.
   * Click **Save**.

   Repeat for each service you want included. At least one service must be defined before the product can be locked.
6. When all services are defined, turn on the **Lock Product** toggle to lock the product for bulk registration.

{% hint style="warning" %}
Locking is permanent — **once a product is locked, it cannot be unlocked.** To change a product's service configuration, create a new product. Services on devices that are already registered can still be managed individually through the Desktop application or at [app.remote.it](https://app.remote.it).
{% endhint %}

### Registration Code

After the product is locked, its **Registration Code** is displayed on the product page with a **Copy** button. This code identifies the account and service configuration that devices will register with.


# Production Image

Build a single production OS image that auto-registers every device it is flashed to, with services pre-configured at manufacturing time.

Create a production image of the same OS and hardware to load onto multiple devices during manufacturing. These devices will automatically register when you determine. This method is more complex and recommended for experienced software developers. You can delay registration if desired for a custom device name. Please contact Remote.It Support at <support@remote.it> if you need this option.

{% hint style="warning" %}
This method is supported for any platforms which can install the [Device Package](/software/device-package/supported-platforms#device_package_supported_platforms) and only supports the device to be used as connection endpoints and not as an initiator of connections. If you need outbound connections as well, please contact <support@remote.it> before proceeding.
{% endhint %}

* The device will be registered to the same account
* The device will be configured with the same services which were defined
* The Remote.It version will be fixed until you create a new production image
* The device will register using the HOSTNAME of the device unless custom naming procedures are used (you can rename the device in Remote.It later)

## Setup

Using a device which will serve to generate your production image, we will install the device package and test the setup of the device including services and connections. Then you will remove the Remote.It identity files to prepare it for use as a production image.

### 1. Create the registration file

{% hint style="info" %}
Create a file in /etc/remoteit called "registration" (no extension) with nothing in it to prevent the device from registering to your account before you are ready. This is essential in case the device is turned on with internet connection to prevent the device from registering with remote.it prematurely. And please make sure no other files in /etc/remoteit when installing the package.
{% endhint %}

```bash
sudo mkdir -p /etc/remoteit
sudo touch /etc/remoteit/registration
```

### 2. Install Remote.It on Your Device for the Production Image

1. [Create your Product](/oem-and-bulk-provisioning/auto-registration-into-your-account/create-a-product)
2. Run the one-line command below on your production image device, without the Registration Code:

```bash
R3_VERSION="XXX" sh -c "$(curl -L https://downloads.remote.it/remoteit/install_agent.sh)"
```

<br>

| Variable Name | Option Type | Description                                                                                                                                                           |
| ------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| R3\_VERSION   | String      | (Optional) Device package version to install. If not defined, then latest release is used. (This will be the same for all devices created from your production image) |

### 3. Set the Registration Code

Write the Registration Code to your registration file which will be used to register the device to your account with services.

```bash
echo YOUR-REGISTRATION-CODE | sudo tee /etc/remoteit/registration
```

{% hint style="warning" %}
DO NOT REBOOT. This is the last step before creating your production image. If your device is rebooted after this code is written, it will register to your account and you will need to remove /etc/remoteit/config.json on your production image.
{% endhint %}

Devices will register with the HOSTNAME. Modify the HOSTNAME prior to first boot with network connection for unique names.

If you want the device to register with a custom name, other processes will be needed contact <support@remote.it>.

### 4. Start production

{% hint style="warning" %}
Before creating your image, make sure to remove the device identifier file /etc/remoteit/config.json if it exists. **This file cannot be present on your production image.**
{% endhint %}

You are now ready to use this device as an image for the rest of your devices. For example, on a Raspberry Pi you can copy the SD card and insert it into another Raspberry Pi.

When these devices are booted with connection to the internet, they will automatically be registered into the account which created the product definition with the defined services enabled.

Again, custom naming must be in place prior to registration.

## Workflows for Updating State and Other Attributes

Sometimes you want to have processes on your backend know about your devices and services. Things like state and potentially update device name or other meta data. In these cases, you can combine this registration flow with [webhooks ](https://docs.remote.it/developer-tools/webhooks)and using our [GraphQL API](https://docs.remote.it/developer-tools/api).

It is not recommended to put your access key and secrets on your edge devices since this can be problematic if you need to rotate keys. Instead have your backend system make the API requests.

See the below diagram

<figure><img src="/files/oPSynSUV7AOgjC3s39IB" alt="Registration and state flow diagram showing a backend system making API requests on behalf of edge devices"><figcaption></figcaption></figure>


# Field Production

The simplest bulk registration method — run a one-line command on each device to install Remote.It with a custom name and pre-defined services.

This is a method to register multiple devices into your account with a pre-defined set of services. This is the easiest method.

**One-line command**\
Run a command on each device to install, which will allow a custom name, pre-defined services (device template), and optionally, a fixed version.

## 1. Create a Product

[Follow the steps to create a product](/oem-and-bulk-provisioning/auto-registration-into-your-account/create-a-product) which defines the services which you want on your devices

## 2. Run your installation

Using the code you created in the previous step, run the one line code. Optionally add the arguments for the device name and software version.

| Variable Name          | Option Type | Description                                                                                                                                   |
| ---------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| R3\_REGISTRATION\_CODE | String      | Registration Code which defines the account and services for the device                                                                       |
| R3\_DEVICE\_NAME       | String      | (Optional) Device name to appear in Remote.It. If not defined, then R3\_DEVICE\_NAME environment variable followed by device HOSTNAME is used |
| R3\_VERSION            | String      | (Optional) Device package version to install. If not defined, then the latest release is used.                                                |

Run the code on each device (example shows all 3 options). If an option is not needed, remove it.

{% code overflow="wrap" %}

```bash
R3_REGISTRATION_CODE="YOUR-REGISTRATION-CODE" R3_VERSION="XXX" R3_DEVICE_NAME="My Device" sh -c "$(curl -L https://downloads.remote.it/remoteit/install_agent.sh)"
```

{% endcode %}

{% hint style="success" %}
As an alternative to using variables as command-line arguments as shown above, Device Package version 5.4.2 and later supports overriding device name, model name, and serial number values using an env file (/etc/remoteit/r3.env). By preparing this file before you run the installation command, you can override each piece of information.
{% endhint %}

```bash
sudo mkdir -p /etc/remoteit
sudo vi /etc/remoteit/r3.env
```

Example contents of r3.env:

```
R3_DEVICE_NAME=sample_device
R3_DEVICE_MODEL=sample_model
R3_DEVICE_SERIAL=sample_serial
```

Using a file with the example above and running the one-line installation command (shown below), the following device will be created. The R3\_REGISTRATION\_CODE is the Registration Code which defines the account and services for the device.

{% code overflow="wrap" %}

```bash
R3_REGISTRATION_CODE="YOUR-REGISTRATION-CODE" sh -c "$(curl -L https://downloads.remote.it/remoteit/install_agent.sh)
```

{% endcode %}

<figure><img src="/files/N4SIRQHh043h1GUkXN2i" alt="Terminal output from running the field production registration command on a device"><figcaption></figcaption></figure>


# Registration into a User's Account

Ship devices that register themselves into your customer's Remote.It account on first boot, using a license key written to the device registration file.

This method of device setup allows for manufacturing or mass setup of devices which have the same platform and OS distribution. This can support complete image writes. Once the customer receives their device, there would be a mechanism to get the customer's account license key written to the device's registration file on the system.\
This method will result in the following when the device boots and connects to the internet for the first time after the registration file is present:

* The device will be registered to the customer's account
* The device will need to be configured with appropriate services for their use.

This method is supported for any platforms which can install the [Device Package](/software/device-package/supported-platforms#device_package_supported_platforms).

## Setup

Using a device which will be used in your production line, install the device package and test the setup of the device including services and connections before creating master device or image with the bellow procedure. This is merely to test that the installation and functionality of remote.it are as desired.

### 1. Install remote.it package on your device with empty "registration" file

Download the compatible package for your device from the [Device Package](/software/device-package/installation#supported-platforms).

{% hint style="info" %}
Create a file in /etc/remoteit called "registration" (no extension) with nothing in it before installing the package. This is essential in case the device is turned on with internet connection to prevent the device from registering with remote.it prematurely. And please make sure no other files in /etc/remoteit when installing the package.
{% endhint %}

```bash
sudo mkdir -p /etc/remoteit
sudo touch /etc/remoteit/registration 
```

Install the package onto your device.

```bash
sudo apt install ./remoteit-4.14.1.armhf.rpi.deb
```

### 2. Copy the image onto another device

For example, if this were a raspberry pi, you would copy the SD card onto a new SD card and insert it into the new device

If this device is something you will deliver to a customer, you may want to have a local interface on the device which will take the input of the customer's license key, write it to the /etc/remoteit/registration file and execute /usr/share/remoteit/refresh.sh. (steps for the user to get their key can be found below) Upon reboot and first time online this device will automatically register to the account to which the license belongs. Then the user will be able to add services to the remoteit device using the Desktop Application.

### 3. User receives the device and registers his account

The user will need to have the remote.it desktop application installed on a device. [There are distributions for Windows, Mac, and Linux](/software/desktop/overview-and-installation). Then they can create an account from there if they do not already have one.

The user will need to retrieve their remote.it license from the Desktop Application, click "...More", then click on "Licensing". Then copy the License Key.<br>

<figure><img src="/files/-Mj6tMt2IAsRsba6DE81" alt="The Licensing panel in the Remote.It Desktop application showing the License Key"><figcaption></figcaption></figure>

The user will need to have the license key written to the /etc/remoteit/registration file either manually or via an interface that you provide on the device received.

Once the license key has been written to the device's /etc/remoteit/registration file, then the device can be refreshed (execute /usr/share/remoteit/refresh.sh) and when the device is able to reach the internet (wifi, cellular or ethernet connection), it will register to the user's account

### 4. User configures the device via the desktop application

The user may need to click the refresh the application icon for the device to appear in the device list.

Following the [directions here](/software/device-package/installation#4-set-up-services-on-your-device), the user can add and remove services via the desktop application. You may want to provide your user


