# Vagon Documentation

This page has been prepared to provide detailed guidance for Vagon services:&#x20;

* [Vagon Streams](#vagon-streams-documentation)
* [Vagon Cloud Computer](#vagon-cloud-computer-documentation)
* [Vagon Teams](#vagon-teams-documentation)

## Vagon Streams Documentation

Vagon Streams provides scalable application streaming for Unreal Engine and Unity applications with RTX-ready NVIDIA GPUs globally.&#x20;

Check out the documentation to learn how to create scalable application streaming, native pixel streaming, and native render streaming experiences in minutes with Vagon Streams, and how you can use  Streams APIs and SDKs. For further assistance, you can contact us via <streams@vagon.io>.

<table data-card-size="large" data-view="cards" data-full-width="false"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><h3>Streams Documentation</h3></td><td><a href="/files/ANzIV3wh3P2CUiurqyjp">/files/ANzIV3wh3P2CUiurqyjp</a></td><td><a href="/spaces/aBZSLkY0LBQ4VmKzrByg">/spaces/aBZSLkY0LBQ4VmKzrByg</a></td></tr><tr><td><h3>Streams Features</h3></td><td><a href="/files/024tnxQpkoMQOXUK0H93">/files/024tnxQpkoMQOXUK0H93</a></td><td><a href="https://vagon.io/streams">https://vagon.io/streams</a></td></tr></tbody></table>

***

## Vagon Cloud Computer Documentation

Vagon Cloud Computer provides high-performance cloud computers for creative professionals with performance flexibility and integrated features to enhance their creative workflow.

Check out the documentation page below to get further assistance for your Vagon Cloud Computer experience. For further assistance, you can contact us via <support@vagon.io>.

<table data-card-size="large" data-view="cards" data-full-width="false"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><h3>Cloud Computer Help Center</h3></td><td><a href="/files/PTexP7SwpZwNvrYUFd8B">/files/PTexP7SwpZwNvrYUFd8B</a></td><td><a href="/spaces/Ik5pU0cI7R3ijTTHUx6M">/spaces/Ik5pU0cI7R3ijTTHUx6M</a></td></tr><tr><td><h3>Cloud Computer Features</h3></td><td><a href="/files/fIuHYCG4xlH44eXsfNN9">/files/fIuHYCG4xlH44eXsfNN9</a></td><td><a href="https://vagon.io/cloud-computer">https://vagon.io/cloud-computer</a></td></tr></tbody></table>

***

## Vagon Teams Documentation

Vagon Teams allows companies to leverage cloud computers for their teams with an easy-to-use dashboard and Teams APIs for custom machine and team orchestration. Create projects & work on your tasks without hardware limits, share files, and collaborate seamlessly with Vagon Teams computers.

Check out the documentation page to learn how you can utilize cloud workstations for your company with Vagon Teams, and Vagon Teams APIs. For further assistance, you can contact us via <teams@vagon.io>.

<table data-card-size="large" data-view="cards" data-full-width="false"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><h3>Teams Documentation</h3></td><td><a href="/files/pNQjuqXQ7CHLtwbDM5kI">/files/pNQjuqXQ7CHLtwbDM5kI</a></td><td><a href="/spaces/qzIIXvR8ySP07f6jrVdc">/spaces/qzIIXvR8ySP07f6jrVdc</a></td></tr><tr><td><h3>Teams Features</h3></td><td><a href="/files/BkUNCOQ0y6QbeGXyDpdB">/files/BkUNCOQ0y6QbeGXyDpdB</a></td><td><a href="https://vagon.io/teams">https://vagon.io/teams</a></td></tr></tbody></table>


# Introduction

This documentation provides detailed information about Vagon Streams, and its solutions on Unreal Engine Pixel Streaming, Unity Render Streaming, and Application Streaming.

{% embed url="<https://www.youtube.com/watch?v=1aEoDPfniCM>" %}
Vagon Streams - Introduction
{% endembed %}

## Vagon Streams

Vagon Streams allows you to stream applications on any device with no code. Make any application accessible on any device globally, including but not limited to Unreal Engine and Unity applications.

![Stream your applications from any device with Vagon Streams](/files/PsxT4fYz7y6H52cWWHci)

In this documentation, you will find information about how to stream your application from a browser window and how you can customize your application streaming experience with the advanced features of Vagon Streams.

### Unreal Engine Pixel Streaming Documentation

{% content-ref url="/pages/bDCGKqkY7JDFepmMJIvc" %}
[Unreal Engine Pixel Streaming](/streams/unreal-engine-pixel-streaming)
{% endcontent-ref %}

### Unity Render Streaming Documentation

{% content-ref url="/pages/iFQAhGqToYBwxGQlaMY6" %}
[Unity Render Streaming](/streams/unity-render-streaming)
{% endcontent-ref %}

### Vagon Application Streaming Documentation

{% content-ref url="/pages/Gi7cQEEfhbZtJ4snJFKp" %}
[Vagon Application Streaming](/streams/vagon-application-streaming)
{% endcontent-ref %}

### Definitions

* **`Application` -** Compiled & portable (dependencies included) software build containing an executable file.
* **`Pixel Streaming`** - Technology to allow Unreal Engine developers to stream compiled `Application's` video and audio from a remote GPU-enabled computer.
* **`Vagon Streams`** - Technology to allow anyone to stream any kind of `Application` (including but not limited to Unreal Engine and Unity apps) with microphone, audio, gamepad, and advanced features as a fully customizable experience for any device with no code.
* **`Developer`** - An application developer who uses Vagon Streams.
* **`Visitor`** - Application users who use the streamed application through Vagon Streams. The audience of the **`Developer`**.
* **`Stream Machine`** - Vagon Streams machine, which runs & streams the selected application on the cloud. Can be accessed via **`Stream Link`** or via API integration.
* **`Stream Session`** - Th&#x65;**`Stream Machine`** lifetime that starts with the **`waiting`** state and ends with the **`terminated`** state for each Stream.
* **`Visitor Session`** - The timespan that starts when a visitor connects to the **`Stream Machine`** and ends when the visitor leaves the session.
* **`Stream Status`** - Status of the remote Vagon Streams machine, updates are instant.
* **`Stream`** - Orchestrator to manage capacity & provision for the **`Stream Machine`**&#x73; of **`Developer`** .
* **`Stream Link`** - Single and unique link to access and distribute **`Stream`**.
* **`Region`** - Selected service locations for **`Stream Machine`**&#x73; to stream an **`Application`**.
* **`Capacity`** - A maximum number of concurrently running **`Stream Machine`**&#x73; per region according to **`Stream`** settings.

{% hint style="info" %}
**Good to know:** Besides using the dashboard, you can also upload & update your app via the [Streams CLI](/streams/tools-and-services/vagon-streams-cli), and customize & manage your streams via the [Streams API](/streams/integrations/streams-api-services).
{% endhint %}


# Unreal Engine Pixel Streaming

Scalable & Native Unreal Engine Pixel Streaming solution with no-code integration

## What is Unreal Engine Pixel Streaming?

Unreal Engine Pixel Streaming is a solution that enables real-time rendering on a cloud server, streaming fully rendered graphics to a client device. This eliminates intensive computations on the client, reducing processing demands and revolutionizing high-performance graphics industries.

To learn more about its applicable usage areas, you can check our further Pixel Streaming guide for a [detailed explanation of Unreal Engine Pixel Streaming](https://vagon.io/blog/what-is-pixel-streaming).

## How to use Unreal Engine Pixel Streaming?

[Vagon Streams](https://vagon.io/streams/features/unreal-engine-pixel-streaming) allows Unreal Engine developers to set up a scalable Pixel Streaming infrastructure, enabling them to share their applications globally.

While it is possible to deploy Pixel Streaming-enabled Unreal Engine applications on public and private cloud services for interactive streaming, this process requires advanced expertise in cloud infrastructure and a manual integration process for each remote machine used for streaming.

Unreal Engine Pixel Streaming support on Vagon Streams leverages the full functionality of Pixel Streaming, including audio and microphone support, as well as Unreal Engine/JS SDK integrations.

<figure><img src="/files/81Am39Rfac3H5OZHSzlS" alt=""><figcaption><p>Scalable Pixel Streaming on Vagon Streams</p></figcaption></figure>

### #1 - Enable Pixel Streaming Plugin

Add Pixel Streaming plugin to your Unreal Engine project, and create your application build. You don't need to manually manage any pixel streaming plugin configuration. System will handle the whole TURN and WebRTC configurations on behalf of you to set up Pixel Streaming experience with your application.

### #2 - Upload Your Application and Create a Stream Link

Now, you can upload your application build folder in .zip format to Vagon Streams dashboard. Our system will automatically check the Unreal Engine version of your application, and its Pixel Streaming support and optimize it for the best experience.

In case you need further instructions, you can check [How to Start Streaming](/streams/guides/how-to-start-streaming) page for a step-by-step guide.

<figure><img src="/files/RxOMJoXyZiqZFRPSxBSH" alt=""><figcaption><p>Application Upload from Dashboard</p></figcaption></figure>

{% hint style="info" %}
Pixel Streaming support is only available for the Unreal Engine experiences built for Windows operating system.
{% endhint %}

### #3 - Activate Pixel Streaming from Dashboard

After adding Pixel Streaming plugin, packaging your project, and uploading your build to your Vagon Dashboard; you only need to activate Pixel Streaming on the Stream Configurations page.

Navigate to the **Stream Configurations** page from the gear icon next to your Stream link and activate the Pixel Streaming toggle.

<figure><img src="/files/QcOzxD6e3jkEOuiGkhPN" alt=""><figcaption><p>Pixel Streaming Configuration from Dashboard</p></figcaption></figure>

### #4 - Start Streaming Your App with Pixel Streaming

Then, you will only need to click on the Stream link, and the system will automatically stream your application with Pixel Streaming technology.

You can use the Stream link on any device, and configure the Stream settings from your dashboard easily.

{% hint style="info" %}
Additional feature support can vary depending on the selected streaming protocol, please check the related feature page to ensure the coverage.
{% endhint %}


# Unity Render Streaming

Scalable & Verified Unity Render Streaming solution with no-code integration

## What is Unity Render Streaming?

Unity Render Streaming is a breakthrough technology that enables high-quality 3D content to be interactively streamed directly to web browsers and mobile devices without requiring downloads or installations. This allows real-time interactive streaming with complex models and environments.

<figure><img src="/files/AIDUyiEjNI8mlAadXNLN" alt=""><figcaption></figcaption></figure>

To learn more about Unity Render Streaming, you can check our [Unity Render Streaming Complete Guide](https://vagon.io/blog/unity-render-streaming-overcome-limitations-with-vagon-streams) for a detailed explanation.

## Unity Verified Streaming Solution - Vagon Streams

As [Vagon Streams](https://vagon.io/streams/features/unity-streaming), we are proud to announce that [**Vagon Streams is an official Unity Verified Solution**](https://vagon.io/blog/vagon-streams-becomes-a-unity-verified-solution), and Vagon Streams official plugin is also accessible from [Unity Asset Store](https://assetstore.unity.com/packages/add-ons/vagon-streams-application-streaming-248734).

{% embed url="<https://www.youtube.com/watch?v=NgCyvIVv42A>" %}
Vagon Streams - Unity Verified Solution
{% endembed %}

## How to use Unity Render Streaming?

### Preparing Application for Unity Render Streaming

Instead of the complicated configurations, you can easily use Unity Render Streaming by enabling the official Unity Render Streaming Plugin in your project, however, it does not allow users to set custom bitrate and FPS rates and it can cause streaming quality issues.

So, as Vagon Streams, we developed an extended version of Unity Render Streaming plugin which has support for high-quality streaming quality preferences.

{% hint style="info" %}
Both Vagon Unity Render Streaming Plugin, and official Unity Render Streaming Plugin can be used to enable Render Streaming on your project, however, **we highly recommend you use Vagon Render Streaming Plugin** for better streaming quality.
{% endhint %}

### #1 - Enable Render Streaming Plugin in Unity

1. Select **Window > Package Manager** from the menu bar in the **Unity Editor**.

![Install Package Manager from menu bar](https://docs.unity3d.com/Packages/com.unity.renderstreaming@3.1/manual/images/install_select_packman_menu.png)

2. If you would like to use Vagon Render Streaming Plugin for a better streaming quality, follow the steps below. Or, if you would like to use Unity Render Streaming plugin, jump to the 3rd step.

a. Click **+** button and select **Add package from git URL**.

b. Type the git URL below to activate Vagon Render Streaming plugin in your project.

```
https://github.com/vagonhq/VagonUnityRenderStreaming.git
```

{% hint style="info" %}
If you would like to get the git URL manually, you can visit the [Github project page](https://github.com/vagonhq/VagonUnityRenderStreaming), and copy the HTTPS link by clicking on the **Code** button on the page.
{% endhint %}

<figure><img src="/files/Had9MxjEsj9C1hhka9vP" alt="" width="563"><figcaption><p>Select add package from git URL</p></figcaption></figure>

3. If you would like to use official Unity Render Streaming plugin, follow the steps below.

a. Click **+** button and select **Add package by Name**.

![Select add package by name](https://docs.unity3d.com/Packages/com.unity.renderstreaming@3.1/manual/images/install_select_add_package_by_name.png)

b. Type the package name below to activate Render Streaming plugin in your project.

```
com.unity.renderstreaming
```

4. After you activate the plugin **Render Streaming Wizard** window will appear automatically. Click on **Fix All** button.

![Input system backend](https://docs.unity3d.com/Packages/com.unity.renderstreaming@3.1/manual/images/wizard_fixall.png)

### #2 - Upload Your Application and Create a Stream link

Upload your build in .zip format to Vagon Streams dashboard.

In case you need further instructions, you can check \[[How to Start Streaming](/streams/guides/how-to-start-streaming)]\(guides/how-to-start-streaming.md) page for a step-by-step guide.

<figure><img src="/files/RxOMJoXyZiqZFRPSxBSH" alt="" width="563"><figcaption><p>Application Upload from Dashboard</p></figcaption></figure>

{% hint style="info" %}
Unity Render Streaming support is only available for the Unity experiences built for Windows operating system.
{% endhint %}

### #3 - Activate Unity Render Streaming

After activating Render Streaming inside your project, creating your build, and [uploading it to your Vagon Dashboard](broken://pages/2JPXJUAt3oOW3t7UHlfR); you only need to activate Unity Render Streaming on the Stream Configurations page.

<figure><img src="/files/RDVO01DbsVdpVaUeHlEU" alt=""><figcaption><p>Unity Render Streaming</p></figcaption></figure>

### #4 - Start Streaming Your App with Render Streaming

Then, you will only need to click on the Stream link, and the system will automatically stream your application with Render Streaming technology.

You can use the Stream link on any device, and configure the Stream settings from your dashboard easily.

{% hint style="info" %}
Additional feature support can vary depending on the selected streaming protocol, please check the related feature page to ensure the coverage.
{% endhint %}

## Unity Render Streaming Troubleshooting

#### Unity Render Streaming Low Streaming Quality

When you face streaming quality issues on Render Streaming-enabled Unity projects, it might be because of Unity Render Streaming plugin. We highly recommend you use the Vagon Render Streaming plugin which provides high-quality streaming experience.

#### Unity Render Streaming Inputs Not Working

Unity Render Streaming only supports **Unity New Input System**, if your project supports Old Input System or Both configurations, it won't work properly.

You can solve the Inputs Not Working problem by activating Unity New Input System in your project.


# Vagon Application Streaming

Scalable application streaming for all kinds of applications globally. With Vagon's own interactive streaming protocol, any application can be streamed on any device in minutes.

## What is Application Streaming?

[Application Streaming](https://vagon.io/streams/features/application-streaming) is an on-demand software distribution method where the application itself is streamed inside the browser with no need to install the application locally. With this method, applications can be accessible on any device, without any hardware limitations real time.

In addition to well-known interactive streaming solutions like Unreal Engine Pixel Streaming and Unity Render Streaming, all legacy applications can be streamed with [application streaming technology](https://vagon.io/blog/what-is-application-streaming) and make accessible without limitations.

## How to use Application Streaming?

Application Streaming is the default protocol for interactive streaming on Vagon Streams, and no additional steps or integration is needed to stream your app with Application Streaming.

The streaming quality of Application Streaming technology adapts itself according to the user's network condition by ensuring 30FPS streaming quality in any network condition. It also supports 4K, 60FPS streaming quality which can be configured from Vagon Dashboard.

Both **Windows** and **Linux** applications can utilize [Application Streaming](https://vagon.io/streams/features/application-streaming) technology with the same feature capabilities.

### #1 - Upload Your Application and Create a Stream link

Start by uploading the application build folder in .zip format to the Vagon Streams dashboard.

In case you need any assistance, you can check [How to Start Streaming](/streams/guides/how-to-start-streaming) page for a step-by-step guide.

<figure><img src="/files/RxOMJoXyZiqZFRPSxBSH" alt=""><figcaption><p>Application Upload from Dashboard</p></figcaption></figure>

### #2 - Start Streaming Your Application

Then, you will only need to click on the Stream link, and the system will automatically stream your application with application streaming technology.

You can use the Stream link on any device, and configure the Stream settings from your dashboard easily.

{% hint style="info" %}
Additional feature support can vary depending on the selected streaming protocol, please check the related feature page to ensure the coverage.
{% endhint %}


# Application Bundles

Application Bundles allows you to serve multiple applications from a single Stream Machine. With this method, you can create a bundle of your existing applications, and create a Stream link for each of your applications, but use a single capacity method for those applications because all are bundled in one package.

<figure><img src="/files/MmYoILvrmDRlWPrB02h8" alt=""><figcaption><p>Create Application Bundle</p></figcaption></figure>

## **Application Bundles Example Scenario**

Let's say you have 10 different applications and Stream links, and you are using the [Instant Installation](/streams/guides/connection-optimizations#instant-installation) + [Balanced Method](/streams/guides/setup-types#balanced-capacity-management) for each of them to optimize connection times.

When you bundle those 10 applications and create a Stream for this bundle, you will have a separate link for each application, but you will keep only one Stream reserve in the Balanced mode, which will be more cost-efficient.


# How to Start Streaming

Check the step-by-step video guide below to learn how to upload an application and create your first Stream.

{% embed url="<https://www.youtube.com/watch?v=EkGl_KGlhbU>" %}
Vagon Streams: Create Your First Stream
{% endembed %}

You can also follow the steps below to upload your first application to start streaming your application.

## How to Upload Application to Vagon Streams

Let's walk through the application together and explore the features of Vagon Streams.

<figure><img src="/files/dxHbSGYcbxZ8Woi8ah5E" alt=""><figcaption><p>Upload Application to Vagon Streams</p></figcaption></figure>

### #1 - Application Type Selection <a href="#h_026681f342" id="h_026681f342"></a>

<figure><img src="/files/L19tvaPZsuGdL1SvWR5o" alt=""><figcaption><p>Windows and Linux Supported</p></figcaption></figure>

### **#2 - Upload Application Folder** <a href="#h_026681f342" id="h_026681f342"></a>

You can simply start by dragging and dropping to upload your application file to your Vagon Streams dashboard.

*The upload process will depend on your local connection speed, but we are doing our best to make this process faster for you.*

<figure><img src="/files/ohEnscaBjzx7vkN444EZ" alt=""><figcaption><p>Upload App Build</p></figcaption></figure>

{% hint style="success" %}
**Preparing a Compressed File**

While uploading your project to Vagon Streams, **you must consider the important points listed below**.

* The compressed file must be in .zip format.
* The compressed file must include all necessary project components and the main executable file in .exe format.
* The main executable file must be inside the compressed file root directory.
  {% endhint %}

### **#3 - Application Executable & Details** <a href="#h_1906d8f03b" id="h_1906d8f03b"></a>

After uploading your compressed file, the initial modal window will appear on the screen. The system will list the executable files inside your compressed build, and you can choose the file you would like to run automatically for your Streams.

<figure><img src="/files/3V7GnXqNIZZuJJc4E5gN" alt=""><figcaption><p>Vagon Streams - General Settings</p></figcaption></figure>

Following the executable file selection, you can give a name to your application and upload an application logo for it.

{% hint style="info" %}
Application Name will only be used inside the dashboard, and it won't be visible to your visitors.
{% endhint %}

{% hint style="info" %}
For the Basic and Pro plans, the application logo will only be displayed on the dashboard, however, for the Enterprise plan, the Vagon Streams logo will be replaced with the uploaded application logo on the application connection page.
{% endhint %}

### **#4 - Choose a Performance to Run** <a href="#h_3e41551947" id="h_3e41551947"></a>

According to your application requirements, you can choose the best performance for it. If you need more performance options, contact us.

<figure><img src="https://lh5.googleusercontent.com/prIRzTUR_M6vl4PSDsbMTkN98S3FtuzarqUmWJAZg4yLCTMWzXaZkMY_3htMZtgwhk2LRF-nC3xyT852sIKCDNyD5GTbV0-tNKR1t_FIH478bGdAdkpFRPr9d4l0e9mRUGr5n53KKcXSL6c28mSKHsU" alt=""><figcaption><p>Vagon Streams - Performance Options</p></figcaption></figure>

### **#5 - Set Up Controls** <a href="#h_acda92a816" id="h_acda92a816"></a>

After setting the general settings and performance selection, you have to choose the cursor control preferences for your application.

### **Mouse Control**

If your application is optimized and developed for the mouse cursor inputs, you can choose the Mouse Control mode.

### **360**° **View Control**

If your application is optimized and developed for 360° view control like first-person shooter games, you can choose the 360° View Control mode.

<figure><img src="/files/0whMYzcndsTAhGEnbmUm" alt=""><figcaption><p>Vagon Streams - Cursor Controls</p></figcaption></figure>

### **#6 - Application is Ready!** <a href="#h_36a1359741" id="h_36a1359741"></a>

Your application is ready to create Streams now! Let's move forward with the Stream Link creation process.

<figure><img src="/files/K05u6wtbcaKEIEfgeVcG" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
All your application content and components must be archived in a .zip format with the portable executable (.exe) of your application build.
{% endhint %}

## How to Create Streams Link to Stream Apps

After uploading your application, it's time to create your Stream Link to share your application with your users! Here is how you can create your first Stream link.

### #1 - Choose the Application

If you haven't created a Stream yet, you can directly start by choosing the application you would like to stream from the Streams tab. Otherwise, use the **`+ New Stream`** button to start.

Then, you can create multiple Stream links for your applications.

<figure><img src="/files/F0hVFKYqYCleRlfpbLGq" alt=""><figcaption></figcaption></figure>

### #2 - Set Coverage

Depending on the location of your visitors, you can choose available service locations for your Streams between the 20 different regions Vagon Streams can be used. When your visitors try to connect to your Stream, the nearest location will be assigned for them to provide the best experience.

<figure><img src="/files/6JqkHE51yV7tzZJCV2Gc" alt=""><figcaption></figcaption></figure>

### #3 - Select Capacity Management Method

Capacity Management Methods allow you to manage visitor load and experience according to your use case. They will ease the integration process for you and manage your `Stream Machines` on behalf of you based on your selection.

Depending on your needs, you can choose the Capacity Management Method and then proceed to finalize the Stream creation process.

<figure><img src="/files/JdDTPEOEaKoMetgIqGgI" alt=""><figcaption></figcaption></figure>

### #4 - Stream Your Application

All set! Now you are ready to share your application with a single link with no code integration.

Just copy the Single Link, and share it with your users, that's all!

Do you need to embed it on your website or your platform? Just use the iframe code we created for you.

<figure><img src="/files/9zX32NBM2XtB6YegqvP8" alt=""><figcaption></figcaption></figure>


# Performance Types

You can find detailed information about the hardware specs of the performance options that your application is launched with.

### DLSS 3 & RTX Enabled Performances

The latest generation performance options have DLSS 3 Frame Generation feature enabled NVIDIA L4 GPUs.

|           | Starter - G2            | Pro - G2                |
| --------- | ----------------------- | ----------------------- |
| Core      | 4 cores                 | 8 cores                 |
| Memory    | 16GB RAM                | 32GB RAM                |
| GPU       | 24GB NVIDIA L4 GPUs     | 24GB NVIDIA L4 GPUs     |
| Processor | AMD EPYC 7R13 Processor | AMD EPYC 7R13 Processor |

### RTX Enabled Performances

The latest generation performance options have RTX-enabled NVIDIA A10G GPUs and AMD processors inside.

|           | Starter - G2                       | Pro - G2                           |
| --------- | ---------------------------------- | ---------------------------------- |
| Core      | 4 cores                            | 8 cores                            |
| Memory    | 16GB RAM                           | 32GB RAM                           |
| GPU       | 24GB NVIDIA A10G GPUs              | 24GB NVIDIA A10G GPUs              |
| Processor | 2nd generation AMD EPYC Processors | 2nd generation AMD EPYC Processors |

### OptiX & CUDA Enabled Performances

The first-generation performance options have OptiX & CUDA-enabled NVIDIA Tesla T4 GPUs and Intel processors inside.

|           | Starter                         | Pro                             |
| --------- | ------------------------------- | ------------------------------- |
| Core      | 4 cores                         | 8 cores                         |
| Memory    | 16GB RAM                        | 32GB RAM                        |
| GPU       | 16GB NVIDIA Tesla T4 GPUs       | 16GB NVIDIA Tesla T4 GPUs       |
| Processor | 3.1GHz Intel Cascade Processors | 3.1GHz Intel Cascade Processors |

### Performance Region Availability

Performance type availability can vary depending on the region selections. You can see the performance availability for each region from the table below.

{% hint style="danger" %}
When provisioning Stream Machines via APIs, VagonPinger results must be filtered by regions according to the selected performance type availability, and then request a machine by the related endpoint.
{% endhint %}

{% hint style="info" %}
The performance selection may limit the region coverage selection according to the performance availability in selected regions. Please check the [Coverage](/streams/guides/worldwide-coverage) page to learn more about region coverage.
{% endhint %}

<table><thead><tr><th width="237.03515625"></th><th width="166.8203125"></th><th width="183.0859375"></th><th></th></tr></thead><tbody><tr><td><strong>Region</strong></td><td><strong>G1 Performance</strong></td><td><strong>G2 Performance</strong></td><td><strong>G3 Performance</strong></td></tr><tr><td>Dublin</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Frankfurt</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Stockholm</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>North Virginia</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Oregon</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>California</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Ohio</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Montreal</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Sao Paulo</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Cape Town</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Mumbai</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Bahrain</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Dubai</td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Singapore</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Jakarta</td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Tokyo</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Hong Kong</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Seoul</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Sydney</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Paris*</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Milan*</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>London*</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr></tbody></table>

\*Regions are not publicly available for now.


# Streams

Streams let you share your uploaded application with your audience as a single link.

`Streams` are the automated orchestrators that manage the `Stream Machine` provisioning for your application streaming experiences.

Each `Stream` has its own `Stream Link` to enable `Developers` to embed application streaming experiences into their platform or website.

`Streams` can manage the capacity with three different approaches according to your use case in the regions you choose to serve your applications.

{% embed url="<https://www.youtube.com/watch?v=5eA6GTgPVRw>" %}
Vagon Streams: Run & Connect to Your Stream
{% endembed %}

Streams can be managed from the dashboard by following [How to Start Streaming](/streams/guides/how-to-start-streaming) guide, or using [Streams API Services](/streams/integrations/streams-api-services)to create custom flows.


# Setup Types

While creating a `Stream`, you have to choose the setup type for your `Stream`.

Setup types allow you to manage your Stream coverage & capacity without any coding requirements. According to your setup selection, the system will automatically orchestrate Stream Machines.

{% embed url="<https://www.youtube.com/watch?v=MBmBh8Y9cIM>" %}

## Automated Setup

Automated Setup is the **recommended** setup type by Vagon. It allows you to stream your applications **worldwide** with a **few seconds of connection time** in the **most cost-efficient** way.

* **Faster connection** via globally pre‑warmed Vagon pool servers.
* **On‑demand billing,** since you are charged only for your active stream usage.
* **Single data center fee** for the whole global coverage of Vagon pool.

**Usage Areas:** Online apps, Showcases, Product Configurators, and all medium traffic use cases

{% hint style="info" %}
Automated Setup is only available for Enterprise Plan users. You can request a weekly Enterprise Plan Trial from your dashboard.
{% endhint %}

## Advanced Setup

Advanced Setup offers you full control over regional coverage and capacity management details of your stream by allowing you to choose between different management methods listed below.

#### Cost Optimized Method

Cost Optimized method will manage your Stream Machines in a cost-efficient way.

The system will only start a Stream Machine when a visitor connects to your Stream, and terminate the Stream Machine based on the limitation settings after a visitor session.

As the system will start a new Stream Machine for each new visitor, connection times will be around 2 minutes for your visitors.

**Usage Areas:** Internally Developed Application Demo

#### Balanced Method

Balanced method will manage your Stream Machines to keep the balance between both cost efficiency and availability perspectives.

The system will keep a defined number of idle Reserved Stream Machines and keep them active for your visitors as long as the stream is running. When a visitor connects to an idle Reserved Stream Machine or leaves a Stream Machine, the system will scale up and down to maintain the number of idle Reserved Stream Machines to balance your budget and availability.

**Usage Areas:** Showcase & Product Configurator Applications for Sales Teams, Online Product Demos

#### Availability Optimized Method

Availability Optimized method will automatically run all your available capacities in each region and keep them ready for your visitors to provide less than 10 seconds of connection times.

**Usage Areas:** Live Events, Virtual Exhibitions


# Worldwide Coverage

Vagon Streams is available in 19 regions globally, and we are continuously adding new regions. While creating `Streams`, you must choose the location of your `Stream Machines`.

<figure><img src="https://lh4.googleusercontent.com/gY7f_FnKhnS0OgLi1HgHBivqxEFd-RSy2VfT4CRslhCN9AbWKkvqPdfqjBLTT3lNIrHq_EtaHfTEDQin8-jiGR8cPWeBUVbgOqxoexTjpSjLx6hIFtGJGQTt0pQsQKhZebCNA-IISMEa7Y8_raQLMHA" alt=""><figcaption><p>Vagon Streams Region Coverage</p></figcaption></figure>

According to your selection, `Streams` will orchestrate your `Stream Machines`. Choose the nearest available region for your visitors, and stream your application in the selected region according to your capacity management selection up to your capacity limits.

{% hint style="warning" %}
Region Coverage selection is important to provide a low latency experience for your visitors. Please be sure that you choose the closest regions according to the physical location of your visitors.
{% endhint %}

{% hint style="info" %}
If you are integrating Streams via Streams API, you can use VagonPinger.js to determine the best region for your users on the client side.
{% endhint %}

### Performance Region Availability

Performance type availability can vary depending on the region selections. You can see the performance availability for each region from the table below.

{% hint style="danger" %}
When provisioning Stream Machines via APIs, VagonPinger results must be filtered by regions according to the selected performance type availability, and then request a machine by the related endpoint.
{% endhint %}

{% hint style="info" %}
The performance selection may limit the region coverage selection according to the performance availability in selected regions. Please check the [Coverage](/streams/guides/worldwide-coverage) page to learn more about region coverage.
{% endhint %}

<table><thead><tr><th width="237.03515625"></th><th width="166.8203125"></th><th width="183.0859375"></th><th></th></tr></thead><tbody><tr><td><strong>Region</strong></td><td><strong>G1 Performance</strong></td><td><strong>G2 Performance</strong></td><td><strong>G3 Performance</strong></td></tr><tr><td>Dublin</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Frankfurt</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Stockholm</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>North Virginia</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Oregon</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>California</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Ohio</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Montreal</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Sao Paulo</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Cape Town</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Mumbai</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Bahrain</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Dubai</td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Singapore</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Jakarta</td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Tokyo</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Hong Kong</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>Seoul</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Sydney</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Paris*</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Milan*</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="26d4">⛔</span></td></tr><tr><td>London*</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr></tbody></table>

\*Regions are not publicly available for now.


# Connection Optimizations

## Instant Installation :zap:

Stream initialization process is composed of two main steps: Stream Machine boot and application installation. Regardless of your project file size, **Instant Installation** eliminates the application installation process.

**Instant Installation** will reduce your connection times by up to 60% depending on your project size.

Regardless of your application size, performance or regions you’ve selected, your audience will be able to connect to your experience immediately, from anywhere.

<figure><img src="/files/gOCb2jQkeg0ylCKc8GrC" alt=""><figcaption></figcaption></figure>

Imagine you have a 50 GB of application build, which generally takes 2-3 minutes to connect with the Cost Optimized capacity method. When you enable **Instant Installation** option for your stream, regardless of its massive size, **the application installation process will be eliminated entirely** and take no time similar to lightweight projects.

{% hint style="info" %}
Instant Installation :zap: gives the best results when it's used with Balanced and Availability Optimized [Capacity Methods](/streams/guides/setup-types).
{% endhint %}

{% hint style="warning" %}
When Instant Installation is enabled for the first time, the system will take a few minutes to optimize your application.
{% endhint %}


# Application Cache Memory

Vagon Streams is designed to collect continuous feedback on the application performance and optimize it according to performance selection.

Each time you upload a new build to the Vagon Dashboard or switch performance groups (different GPU series), the system generates a virtual cache memory for the application.

After each visitor session, the system automatically collects application-generated shader & asset files and uses them for future sessions to optimize the application connectivity.

If the cache files are ready for an application, an "Optimized" badge will appear on its card.

<figure><img src="/files/GcauqUK5NDGYTevnEZq9" alt=""><figcaption></figcaption></figure>


# Region Optimization

Vagon maintains a pool of pre-warmed machines in high-traffic regions to minimize connection times for all users, regardless of whether they use the Cost Optimized method. These pre-warmed resources are available to all Vagon users without requiring a [Premium Feature Plan](/streams/configurations/premium-feature-plans).

When Region Optimization is enabled, the system prioritizes assigning a pre-warmed machine based on the user's physical location. It first checks for available pre-warmed machines in the selected main region(s). If a pre-warmed machine is available in the user's primary region, it is immediately assigned to the user.

If no pre-warmed machines are available in the primary region(s), Vagon checks predefined satellite regions. If a pre-warmed machine is available in a nearby satellite region, it is immediately assigned to minimize connection time for the user.

If no pre-warmed machines are available in either the main or satellite regions, Vagon automatically provisions a regular machine in the user's main region.

<figure><img src="/files/iYLEpvgsH1p67Z0pifg4" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
A daily data center fee will be applied if the system assigns a Stream Machine from a satellite region.
{% endhint %}


# Configurations

Stream Configurations allow you to configure & customize your experience from your dashboard according to your unique requirements.

<figure><img src="/files/YPwFWuEPsI0jvsUbFhHn" alt=""><figcaption></figcaption></figure>

{% content-ref url="/pages/WMtUDsWLH3BJXfZm2OwW" %}
[Premium Feature Plans](/streams/configurations/premium-feature-plans)
{% endcontent-ref %}

{% content-ref url="/pages/kxUwYYFLMeEzVXsR5Lnk" %}
[Application Versioning](/streams/configurations/application-versioning)
{% endcontent-ref %}

{% content-ref url="/pages/U2NJuy5AwtxzPaSzl8Lj" %}
[Basics](/streams/configurations/basics)
{% endcontent-ref %}

{% content-ref url="/pages/DNLcuwQpjy4nIjyipEpE" %}
[Limitations](/streams/configurations/limitations)
{% endcontent-ref %}

{% content-ref url="/pages/uKlZbWWdyGycA5MGvcsW" %}
[Accessibility](/streams/configurations/accessibility)
{% endcontent-ref %}

{% content-ref url="/pages/EArVH6yixMQTM6hfAlek" %}
[Availability](/streams/configurations/availability)
{% endcontent-ref %}

{% content-ref url="/pages/WKYltoYlZLa5wMub4uZb" %}
[Launch Parameters](/streams/configurations/launch-parameters)
{% endcontent-ref %}

{% content-ref url="/pages/CeG3rQgqEUwvm96aRIOS" %}
[Visitor Data Collection](/streams/configurations/visitor-data-collection)
{% endcontent-ref %}

{% content-ref url="/pages/O8oTXtYjPx36akMLKozF" %}
[Customize - Connection Page](/streams/configurations/customize-connection-page)
{% endcontent-ref %}

{% content-ref url="/pages/YkobbWilJ2H9nFUEuOTo" %}
[Stream Files](/streams/configurations/stream-files)
{% endcontent-ref %}

{% content-ref url="/pages/0lsDupZkFEpfSuGeBYpx" %}
[Advanced](/streams/configurations/advanced)
{% endcontent-ref %}


# Premium Feature Plans

Premium features include white labeling, application versioning, custom stream URLs, visitor stats, port access, budget limits, password protection, and many more.

You can manage your Streams plan straight from your dashboard.

Explore the complete feature comparison table [here](https://app.vagon.io/stream/settings), and activate your plan to access premium features.

<figure><img src="/files/ODojsBV5uvIpd94SDq8X" alt=""><figcaption></figcaption></figure>

## Feature Comparison List

<table><thead><tr><th width="293">Feature</th><th width="159">Basic</th><th width="156">Pro</th><th>Enterprise</th></tr></thead><tbody><tr><td>Application Count</td><td>25 Apps</td><td>50 Apps</td><td>Custom</td></tr><tr><td>Single Application Size</td><td>25 GB per app</td><td>50 GB per app</td><td>125 GB per app</td></tr><tr><td><a href="/pages/kxUwYYFLMeEzVXsR5Lnk">Application Versioning</a></td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/GHpS0JqEUn1MLGledU6a#instant-installation">Instant Installation</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Machine Pool Utilization</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Custom Stream URL</td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/O8oTXtYjPx36akMLKozF">White Labeled Streams</a></td><td>-</td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Dark Mode</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Custom Connection Messages</td><td>-</td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/R2BULHaSfuWTWtxYyLOB">API Integration</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Multiple Administrators</td><td>-</td><td>Up to 5 Users</td><td>20+ Users</td></tr><tr><td><a href="/pages/Ya530ubohCBqXgHhjLeo">Application Bundle</a></td><td>2 Apps / Bundle</td><td>5 Apps / Bundle</td><td>Unlimited</td></tr><tr><td>Concurrent Capacity per Stream Link</td><td>25 per Region</td><td>50 per Region</td><td>Custom</td></tr><tr><td><a href="/pages/L0KN8jeGmoF6FHc9JEw5">Region Coverage</a></td><td>20+ Regions</td><td>20+ Regions</td><td>25+ Regions</td></tr><tr><td><a href="/pages/uKlZbWWdyGycA5MGvcsW#enable-port-access">Port Access</a></td><td>-</td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/DNLcuwQpjy4nIjyipEpE#stream-budget">Stream Budget Limiting</a></td><td>-</td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/YNVTOq9MsSE4bklD6Eov">Application Budget Limiting</a></td><td>-</td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/CeG3rQgqEUwvm96aRIOS">Visitor Email Collection</a></td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/CeG3rQgqEUwvm96aRIOS">Visitor Device Stats</a></td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/EArVH6yixMQTM6hfAlek">Scheduled Stream Availability</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Audio / Microphone Support</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/DNLcuwQpjy4nIjyipEpE#auto-turn-off-duration">Stream Auto Turn Off</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/DNLcuwQpjy4nIjyipEpE#session-duration-limit">Session Duration Limit</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td><a href="/pages/YkobbWilJ2H9nFUEuOTo">Streams Files</a></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Premium Support</td><td>-</td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr><tr><td>Roadmap Contribution</td><td>-</td><td>-</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span></td></tr></tbody></table>


# Application Versioning

<img src="https://docs.vagon.io/~gitbook/image?url=https%3A%2F%2F957593864-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FaBZSLkY0LBQ4VmKzrByg%252Fuploads%252FkASsSG44MFuaZ7JarK3K%252Fimage.png%3Falt%3Dmedia%26token%3D56f303c6-9407-4b83-989e-b3cdb343a976&#x26;width=768&#x26;dpr=4&#x26;quality=100&#x26;sign=690837e0&#x26;sv=2" alt="" data-size="line">

When you need to update your previously uploaded Application build version by keeping your Stream link and application configurations the same without the need to create a new Stream link each time, you can use the Application Versions feature to upload new versions for an existing application.

<figure><img src="https://docs.vagon.io/~gitbook/image?url=https%3A%2F%2F957593864-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FaBZSLkY0LBQ4VmKzrByg%252Fuploads%252FsdgfvWml6zuVA2Sy5VX7%252Fimage.png%3Falt%3Dmedia%26token%3Dab8013b3-8bf3-42e4-b9e3-2524c6b64f0c&#x26;width=768&#x26;dpr=4&#x26;quality=100&#x26;sign=89c3f53&#x26;sv=2" alt=""><figcaption></figcaption></figure>

You can easily switch between the versions you've uploaded with just a few clicks, and upload new versions for an existing app.

When you upload a new build, it will be automatically assigned as the **Active** version and all your existing Streams will be updated to use this version. If you need to switch back to a previous version, you can also activate it from the same window.


# Basics

## Coverage

You can update the available regions for your Stream link.

{% content-ref url="/pages/L0KN8jeGmoF6FHc9JEw5" %}
[Worldwide Coverage](/streams/guides/worldwide-coverage)
{% endcontent-ref %}

## Capacity Management

You can update the Capacity Management Method of your Stream link, to determine how to orchestrate Stream Machine provisioning process.

{% content-ref url="/pages/egr31no4at0lYs6fI1RS" %}
[Setup Types](/streams/guides/setup-types)
{% endcontent-ref %}

### Reserved Capacity

The number of idle Stream Machines that will be kept running for your visitors. Defines the number of Stream Machines for each selected region.

Reserved Capacity selection is only available for the **Balanced** Method.

### Concurrent Capacity

Maximum number of Stream Machines that can be started concurrently. Defines the number of Stream Machines for each selected region.

### Independent Capacities

When capacities are needed to be configured for each region, both Reserved and Concurrent Capacities can be managed separately.

<figure><img src="/files/vhkX2LqeEL1pDGyD9DNe" alt=""><figcaption><p>Stream Configurations - Basics</p></figcaption></figure>

## Instant Installation :zap:

Instant Installation feature creates a ready-to-use version of your application and entirely eliminates the installation time of your application. Check out the detailed guide in [Connection Optimizations](/streams/guides/connection-optimizations#instant-installation)section.

When the toggle is first enabled, a blinking grey lightning icon will appear next to the Stream link representing the preparation process, which can take up to 5 minutes. When it's completed it will turn into a permanent green lightning icon to represent it's ready.

## Unreal Engine Pixel Streaming

This toggle will only be visible for Pixel Streaming plugin added Unreal Engine applications. When the toggle is enabled, the system will use [Unreal Engine Pixel Streaming](/streams/unreal-engine-pixel-streaming)technology to interactively stream applications.

## Multitenant Pixel Streaming

This toggle will only be visible when the Pixel Streaming toggle is enabled. When it's enabled, the system will create a selected number of virtual tenants inside a Stream Machine, divide the total performance of the host machine into tenants, and serve apps from those tenants. [Multitenant Pixel Streaming](/streams/custom-flows/multi-tenant-streaming) feature allows you to serve your app to multiple users from a single Stream Machine.

## Unity Render Streaming

As a Unity Verified Solution, Vagon also supports native Unity Render Streaming technology. This toggle will be only visible for Unity Render Streaming plugin added Unity applications. When the toggle is enabled, the system will use [Unity Render Streaming](/streams/unity-render-streaming) technology to interactively stream applications.


# Limitations

<figure><img src="/files/cNHn6cBDUZ9TKkqQf6sG" alt=""><figcaption><p>Stream Configurations - Limitations</p></figcaption></figure>

## Session Duration Limit

After creating your `Stream`, you can set a session duration limit for your `Visitor Sessions`. Session Duration Limit allows you to limit visitor session durations.

According to your preference, the system will inform the visitor 1 minute before the expiration, and then redirect them to another page when the session is expired to make your Stream available for the next users.

## Auto Turn-Off Duration

Auto Turn-Off Duration allows you to automatically turn off `Stream Machines` after the configured span of an idle period. Auto Turn Off Duration provides you with the flexibility to manage your `Streams` by preventing unexpected usages.

According to your selection, the system will monitor your Stream Machines, and after the selected time of availability of the `Stream Machine,` it will be terminated.

{% hint style="warning" %}
Auto Turn Off Duration is not available for Availability Optimized Streams, and the reserved Streams Machines in Balanced Streams.
{% endhint %}

## Idle Time Duration

You can set an **Idle Duration Limit** for your stream to kill an idle visitor session automatically if there is no user action within a specified time.

Depending on your duration selection, visitor sessions will be terminated if users don't interact with your stream for the specified time period. That way, you'll be able to prevent unintentional usages caused by forgotten tabs or web pages.

## Stream Budget Limit

<div align="left"><figure><img src="/files/Q6jum2ktNg3RYlu3t7K9" alt="" width="96"><figcaption></figcaption></figure></div>

Stream Budget Limit gives you the opportunity to budget for your Streams.

When a stream hits the budget limit, the system will automatically pause the related Streams to prevent unexpected expenses.


# Accessibility

<figure><img src="/files/DmESN34OzMPUYWNDXYTn" alt=""><figcaption><p>Stream Configurations - Accessibility</p></figcaption></figure>

Accessibility features can be configured from `Streams Dashboard` for each Stream. Selection will be automatically applied to Stream Sessions according to your selections.

## Audio

`Audio ON` - Stream Session starts in audio-enabled mode, and visitors can turn it off from the dock menu.

`Audio OFF` - Stream Session starts in audio-disabled mode, and visitors cannot turn it on.

`Users Can Select` - Stream Session starts in audio-disabled mode, and visitors can configure the selection from the dock menu in their Stream Sessions.

## Microphone

`Microphone ON` - Stream Session starts in microphone-enabled mode, and visitors can't turn it off.

`Microphone OFF` - Stream Session starts in microphone-disabled mode, and visitors can't turn it on.

`Users Can Select` - Stream Session starts in microphone-disabled mode, and visitors can configure the selection from the dock menu in their Stream Sessions.

## Custom Screen Resolution

`Scale to Screen Resolution` - Stream experience will be scaled up/down according to the window/screen resolution of the visitor's device. If the visitors don't use the experience in full-screen mode, it can cause scaling issues because this selection won't keep the aspect ratio for the Stream.

`720p Resolution` - Stream experience will be set for 720p screen resolution and scaled up/down by keeping the 16:9 aspect ratio.

`1080p Resolution` - Stream experience will be set for 1080p screen resolution and scaled up/down by keeping the 16:9 aspect ratio.

`4K Resolution` - Stream experience will be set for 4K screen resolution and scaled up/down by keeping the 16:9 aspect ratio.

{% hint style="info" %}
Higher Screen Resolution selections may cause high bandwidth usage for your visitors.
{% endhint %}

## Keyboard Layout

If your app requires a unique keyboard layout for your visitors, you can set a custom keyboard layout for your `Stream Machines`.

Available keyboard layouts are listed below:

* `English - US - QWERTY`
* `English - UK - QWERTY`
* `Dutch - QWERTY`
* `French - AZERTY`
* `German - QWERTY`
* `Spanish - QWERTY`
* `Turkish - QWERTY`
* `Norwegian - QWERTY`
* `Italian - QWERTY`
* `Japanese - QWERTY`

## On Screen Game Controller

You can add on-screen game controllers on top of your experience, and let your users control your experience with them. This feature will provide you the opportunity to make your experience ready for mobile/tablet devices without any additional integration, you just need to map the required keys to PS4 Game Controller Stick keys in your application.

You can set the visibility of the game controller according to your needs from configuration settings.

{% hint style="warning" %}
While configuring the application key mappings for game controller support please apply the following Product ID and Device ID.

**Vendor ID:** 0x054C

**Product ID:** 0x05C4
{% endhint %}

<figure><img src="/files/n8sOzUtgHMI7ooHDvbeW" alt=""><figcaption><p>Vagon Streams On Screen Game Controller</p></figcaption></figure>

## Enable Port Access

<div align="left"><figure><img src="/files/Q6jum2ktNg3RYlu3t7K9" alt="" width="96"><figcaption></figcaption></figure></div>

You can activate ports within your Stream Machines for advanced communication and enabling Port Access inside Stream Machines will give you the opportunity to set up unique experiences like [Multiplayer Experiences](https://vagon.io/blog/how-to-create-multiplayer-unreal-engine-experiences/) and more.

Imagine using a Vagon Streams machine as the host for your multiplayer adventures or effortlessly sending data to a separate application via ports.

Check out our latest blog post to learn [how to start multiplayer session by using the Unreal Engine Collab Viewer](https://vagon.io/blog/how-to-create-multiplayer-unreal-engine-experiences/) project template and Vagon Streams.

<figure><img src="/files/2SR5CepReXw1U7V94xFs" alt=""><figcaption></figcaption></figure>

When you need to get the Stream Machine IP address, you can get this information from the Stats page in your dashboard.

<figure><img src="/files/IwYlV6UA1lHoD8nEqiYj" alt=""><figcaption></figcaption></figure>


# Availability

Schedule Availability feature enables Vendors to manage their Stream availability.

Hierarchically, Stream Status is above the Schedule Availability feature and overwrites the Stream schedule. Stream Link status must be active to apply scheduled availability.

When your Stream status is active, according to your Schedule Availablity preference, your visitors will access your Stream or be redirected to the Stream is Expired page.

When your Stream status is paused, visitors will be redirected to the Steam is Expired page independently from your Schedule Availability preference.

### Always Available Streams

Streams Link will be accessible according to your Stream Link status.

<figure><img src="/files/NPWJzhp2SQFR1pdmNapB" alt=""><figcaption><p>Stream Configurations - Availability</p></figcaption></figure>

### Start & End Date Defined Streams

Streams Link will be accessible between the selected dates and hours if your stream status is active.

<figure><img src="/files/wfI9wFVVH0KaAEtyg4e4" alt=""><figcaption></figcaption></figure>

### Working Hours

Streams Link will be accessible between the defined hours on the selected days if your stream status is active.

<figure><img src="/files/m4GTyvXGgJWpZZ5y3ApN" alt=""><figcaption></figcaption></figure>


# Launch Parameters

<figure><img src="/files/t3t1KcjKkrxmdxZE7xUc" alt=""><figcaption><p>Stream Configurations - Launch</p></figcaption></figure>

You can set launch parameters for your Streams from Stream Configurations and also via URL Parameters.

URL Parameters will allow you to apply Launch Parameters for each Stream Session. If you are looking for a solution to push parameters for each Visitor (Stream Session), it will be a good fit for you.

If you need to push static parameters for your application (connection port values, screen mode, screen size, etc.), you can directly set those launch parameters via Streams Configurations.

The launch parameters you configured will be applied while your application is running on Vagon Streams.

{% hint style="danger" %}
Launch Parameters may cause initialization issues when they are configured wrong. Be sure that your configuration has been tested locally before applying those parameters to your Vagon Streams experience.
{% endhint %}


# Visitor Data Collection

<figure><img src="https://lh4.googleusercontent.com/rm3vbznYoeH7iAgJoZupl88WhdLKZH_GMDLoJIn5zQykpim8iaSWBilmyFiGQAFISDyczumTRm9Fhxd04ompgP3xGHwqfUybZbw2SCnJSsjfZf-tCqy1yIq3dRp6TgQKzAJrLkNf6fDjM5IqlbR_hl4" alt=""><figcaption><p>Stream Configurations - Visitors</p></figcaption></figure>

## Collect Visitor Data

<div align="left"><figure><img src="/files/BMXS9T8M4mcG1BU5K7nn" alt="" width="48"><figcaption></figcaption></figure></div>

When the **Collect Visitor Data** is enabled, your visitors will be asked to share their email addresses before joining the Stream.

You will be able to collect visitor data and track connected user data from the Stats > Visitor tab inside your Streams Dashboard.

![](/files/CwxhTlpJZMmBB8tb6p7x)

### Visitor Data Collection via URL Parameters

In addition to the Visitor Data Collection page, you can collect user information by sending user email addresses via URL Parameters.

After your Streams URL, you just need to add `visitor_email` parameter and send the user email as the parameter value at the end of your URL. You can find the sample URL below.

`https://streams.vagon.io/streams/<STREAM_ID>?visitor_email=streams@vagon.io`

{% hint style="info" %}
If you are using both URL Parameters and Visitor Data inside your URL, be sure that you separated them via `&` sign to prevent issues.
{% endhint %}

## Connections Stats

<div align="left"><figure><img src="/files/BMXS9T8M4mcG1BU5K7nn" alt="" width="48"><figcaption></figcaption></figure></div>

When you enable **Connection Stats**, you will be able to monitor your visitor device and connection performance information on your Stats page.

**Visitor Stats** are also available through our Streams API which gives you the option to embed your streaming data to your own dashboard or system.

<figure><img src="/files/byX0OKnZiMqGtz8Ii7le" alt=""><figcaption><p>Vagon Streams Stats Page</p></figcaption></figure>

## Password Protection

<div align="left"><figure><img src="/files/Q6jum2ktNg3RYlu3t7K9" alt="" width="96"><figcaption></figcaption></figure></div>

When you enable **Password Protection** for your Streams, your users will be asked for a password to join your Stream, and visitors without the password will not be able to connect to your experience.

<figure><img src="/files/DHQjuSKodmhKflSoHl78" alt=""><figcaption></figcaption></figure>

## Visitor Authentication (SSO)

When you enable **Visitor Authentication (SSO)**, visitors must sign in with your identity provider — **Microsoft Entra**, **Auth0**, or **Google** — before they can connect to your Stream. This limits access to authenticated visitors only.

Visitor Authentication is an **Enterprise** feature available on individual Streams. For the full setup and per-provider integration steps, see the dedicated guide.

{% content-ref url="/pages/ZLISCWZgzuAFGhxGouvr" %}
[Visitor Authentication](/streams/custom-flows/visitor-authentication)
{% endcontent-ref %}


# Customize - Connection Page

Vagon Streams allows you to customize the connection pages for Unreal Engine Pixel Streaming, Unity Render Streaming and Vagon Application Streaming experiences from Streams Dashboard.

<figure><img src="https://lh4.googleusercontent.com/UOSHGJk5HulP_gCpTIsVkjxw3HMjekysEEQJLonlz2vXCAoVuW_YcP98E4ZBrC2CeMuL4nji7xP0hu9fFHuyMpyhLmDpB31qjaNC3ZwbjHaQEvTt72WZJLXElGxGBmAKQwCPgZ__hzvIHK7FbJI4pi0" alt=""><figcaption><p>Stream Configurations - Customize</p></figcaption></figure>

There are two modes of Connection Pages for Basic Plans, dark mode and light mode.

### Light Mode

![](/files/cDBLIeS3GcO1rPSbRHMo)

### Dark Mode

![](/files/xfpKQulCK49gBi0hnHvR)

### Show Play Page

Play Page is required for the Pixel Streaming and Render Streaming enabled Streams as default. Also, because modern browsers require at least a user interaction to start audio/microphone, we automatically activate this page before initialization of a Stream when audio or microphone is enabled for a Stream.

Even though we highly recommend keeping this page active before the Stream, this page can be disabled from the Stream Configurations.

{% hint style="info" %}
Disabling Play Page can cause audio and microphone initialization issues on some browsers.
{% endhint %}

### Accessibility Dock Position

Dock Menu is the tiny menu area that is visible bottom-center of your Streaming area to manage audio \&microphone settings and enable full screen. The place of this menu can be set from the Stream Configurations page.

## Branded Connection Page

<div align="left"><figure><img src="/files/Q6jum2ktNg3RYlu3t7K9" alt="" width="96"><figcaption></figcaption></figure></div>

In addition to default connection page alternatives, Enterprise users can customize the Connection Page background, and add their company/product logo to the connection page via Streams Dashboard.

![](/files/iGPy0m9kp6eGbPxTtQxP)

### Connection Messages

Each connection message can be updated from the Stream Configurations page with Enterprise Plan.


# Stream Files

Stream Files gives the ability to add extra storage to your Stream Machines. You can,

* upload files to your Stream Machine directly and let your application to use them internally without needing any cloud storage integration.
* let your users import their files to your application, work on it, and finally let them download files from your application without any additional requirements.

## Preloaded Stream Files

Uploaded files will be transferred to Stream Machine after installing your application inside.

Preloaded files will be stored under the `T:\PreloadedFiles` folder, and your application will access them from this folder.

Preloaded Files will be uploaded automatically and stored for all your Stream Sessions. they won't be deleted as long as you keep them uploaded in your Stream Configurations page.

System will trigger Preloaded Files Uploaded message with the following returned object when the transfer is completed.

```json
{
  "$type": "22"
}
```

## Let Users Upload & Download Files

When this feature is enabled, your users will be able to transfer their files to the `Visitor Session` via drag and drop, and download the files that are saved in the `T:\Temp Files` directory.

<figure><img src="/files/HrbhwzH1qgJDXf6BRi0e" alt=""><figcaption><p>Stream Configurations - Stream Files</p></figcaption></figure>

Streams Files offers a complete experience for design apps and all others. If you need a custom workflow or want to learn more about it, don’t hesitate to contact us.

## File & Content Management via AWS, Azure, or Google Cloud

If your application requires a custom file integration like uploading an in-Stream created file and letting users download them, or periodically uploading saved project/game files to a cloud storage, you can do this with Vagon Streams as well.

Because Vagon Streams machines have a public internet connection inside, you can upload created files to AWS (or other CSPs), get a download link for the uploaded files, and then [open this link in a new tab with our Unreal Engine / Unity SDKs](#how-to-setup-a-file-pipeline-using-a-cloud-service-provider-inside-application-via-aws-azure-or-goog) to initiate the download.

Because this flow will be maintained on your application side, it will be a more convenient approach for both you and your users. However, of course, it requires additional integration and custom development.


# Advanced

## Auto Start Application

System will wait for a visitor connection to launch the application when it's disabled. When enabled, the application will be started automatically as soon as the stream machine is initiated without waiting for any user to connect to the Stream Machine. Enabling this setting may result in missing the initial scenes of the application for the connected user because it's already initiated.

This configuration is disabled as default.

## Restart Application for Each Visitor

Application will be restarted for each unique visitor when it's enabled.

When disabled, the application and its data won't be reset between visitor sessions and the application will keep running even if a new user connects to the Stream.

Disabling this may lead to session data being shared across sessions, this configuration is enabled as default.

## Collect Application Logs

System will collect application logs for debug (logging) enabled Unreal Engine and Unity builds, and make them accessible after each Visitor Session from the Stats page.

When the Auto Collection is enabled, the system will try to auto-detect the log path to collect the application logs. If you set a different application log, you can set a custom path by disabling the Auto Collect toggle as well.

<figure><img src="/files/3RqZ3WDOcNmc8ZzdoDQA" alt=""><figcaption><p>Stream Configurations - Advanced</p></figcaption></figure>


# Application Budget Limit

<div align="left"><figure><img src="/files/Q6jum2ktNg3RYlu3t7K9" alt="" width="96"><figcaption></figcaption></figure></div>

<figure><img src="/files/wkux2kPesDQVsInH7NJs" alt=""><figcaption></figcaption></figure>

Application Budget Limit gives you the opportunity to set application level budgets for your Streams.

When a stream or application hits its limit, the system will automatically pause all running Streams to prevent unexpected expenses.

You can set application-level budgets from your application card and stream-level budgets through the Stream Configurations page.


# Client-side Communication

Establish real-time communication pipeline between Unity and Unreal Engine apps and the web pages.

Vagon Streams allows the establish end-to-end message communication between applications and the client side with custom UI interactions.

By using the events and functions listed in [Javascript SDK](/streams/integrations/client-side-communication/javascript-sdk) page, you can create custom web UIs on top of your application and easily send custom messages for your project requirements.

In addition to the client-side messages, you can send messages from the application to a custom web UI with [Unreal Engine SDK](/streams/integrations/client-side-communication/unreal-engine-sdk)and [Unity SDK](/streams/integrations/client-side-communication/unity-sdk) functionalities.

Besides the predefined message types for specific actions, it's possible to transmit any custom message between the client side and the application side as well.

## Unreal Engine Pixel Streaming Client-side Communication

1. Integrate [Unreal Engine SDK](/streams/integrations/client-side-communication/unreal-engine-sdk) inside the project, and map the events by using Pixel Streaming messaging functionalities.
2. Embed your Vagon Streams link into a web page as an iframe.
3. Add Vagon Javascript SDK to your web page by [following the guide](/streams/integrations/client-side-communication/javascript-sdk).
4. Send and receive messages between the client side and your application.

## Unity Render Streaming Client-side Communication

* Integrate [Unity SDK](/streams/integrations/client-side-communication/unity-sdk) depending on your engine inside the project, and map the events by using Pixel Streaming messaging functionalities.
* Embed your Vagon Streams link into a web page as an iframe.
* Add Vagon Javascript SDK to your web page by [following the guide](/streams/integrations/client-side-communication/javascript-sdk).
* Send and receive messages between the client side and your application.

## Vagon Application Streaming Client-side Communication

* Integrate [Unreal Engine SDK](/streams/integrations/client-side-communication/unreal-engine-sdk) or [Unity SDK](/streams/integrations/client-side-communication/unity-sdk) depending on your engine inside the project, and map the events by using Pixel Streaming messaging functionalities.
* Embed your Vagon Streams link into a web page as an iframe.
* Add Vagon Javascript SDK to your web page by [following the guide](/streams/integrations/client-side-communication/javascript-sdk).
* Send and receive messages between the client side and your application.


# Javascript SDK

You can use Streams JS SDK to send messages from the client side to your application.

Embed the script code between the `<head> </head>` tags inside the page you embedded your Streams Link via iframe.

```html
<script src="https://app.vagon.io/vagonsdk.js"></script>
```

{% hint style="info" %}
Despite you added the JS SDK script between the tags in your client code, if you can not establish a connection, please be sure that you copied the iFrame tag from the Vagon Streams dashboard.

If you manually created your iFrame code by adding your Streams Link, please check that you applied the id tag and other required iFrame properties correctly from the sample code below.

```html
<iframe id="vagonFrame" allow="microphone  *; clipboard-read *; clipboard-write *; encrypted-media *;" src="_Stream_URL_"/>
```

{% endhint %}

<figure><img src="/files/wZ22pVDbgRVJruvxo23K" alt=""><figcaption></figcaption></figure>

Then you will be able to use the JS methods to create your custom user experience for your application Stream.

**Demo HTML**

```html
<!DOCTYPE html>
<html>
	<head>
		<script src="https://app.vagon.io/vagonsdk.js"></script>
	</head>
	<body>
		<iframe id="vagonFrame" style="height:100vh; width: 100vw;" allow="microphone  *; clipboard-read *; clipboard-write *; encrypted-media *;" src="__Stream_URL__"/>
	</body>
</html>
```

## Unreal Engine Pixel Streaming EmitUI Messages

You can use both EmitUI and [Client Side Messaging](#client-side-integration-functions) functionalities for Unreal Engine Pixel Streaming enabled Stream links.

### emitUIInteraction

```javascript
window.Vagon.emitUIInteraction("payload")
```

### emitCommand

```javascript
window.Vagon.emitCommand("payload")
```

### onResponse

```javascript
function onResponse(data) {
  console.log(data)
}

window.Vagon.onResponse(onResponse);
```

## Client-side Integration Functions

Client-side Integration Functionalities and events have support for all types of Streaming you can use inside Vagon Streams.

### **isConnected**

```javascript
window.Vagon.isConnected()
```

Connection status, returns boolean.

### **sendApplicationMessage**

```javascript
window.Vagon.sendApplicationMessage("Hello My Application!") 
```

Sends the related message to your application.

### resizeFrame

```javascript
window.Vagon.resizeFrame()
```

Updates the streaming resolution and matches the iframe height and width when initiated.

### focusIframe

<pre class="language-javascript"><code class="lang-javascript"><strong>window.Vagon.focusIframe()
</strong></code></pre>

Keeps the browser window focused on the streaming iframe. In case you are facing issues with keyboard inputs, you can use this method.

### showKeyboard

```javascript
window.Vagon.showKeyboard()
```

If your visitors are using your Applications on mobile/tablet devices, you can also allow them to type with the on-screen keyboard inside Vagon Streams.

### hideKeyboard

```javascript
window.Vagon.hideKeyboard()
```

When the focus changes from the text input, you can hide the on-screen keyboard button from the screen as well.

### enableGameMode

```javascript
window.Vagon.enableGameMode()
```

Activates 360 View cursor mode inside an active Stream.

### disableGameMode

```javascript
window.Vagon.disableGameMode()
```

Disable 360 View cursor mode inside an active Stream.

### keepAlive

```javascript
window.Vagon.keepAlive()
```

Reset Idle Timer by sending a simulated user input when the Idle Duration Limit is active.

### shutdown

```javascript
window.Vagon.shutdown()
```

Shut down the Stream Machine and terminate the related session immediately.

### setQuality

```javascript
window.Vagon.setQuality(quality)
```

Quality parameters can be set as "standard", "moderate" or "high". Session will be refreshed automatically after the quality is set.

### getSessionInformation

```javascript
window.Vagon.getSessionInformation()
```

Triggers the `onSessionInformation` event, data must be collected via `onSessionInformation` event.

### setVideoVolume

```javascript
window.Vagon.setVideoVolume(0.5)
```

Set the sound of your Stream link between 0 to 1.

### startStream

```javascript
window.Vagon.startStream()
```

Starts the Stream programmatically, triggering the same flow as clicking the play button on the connection page: it begins video and audio playback and activates the microphone when the Stream is configured for it. This lets you build your own custom play button or auto-start experience instead of using the default one.

{% hint style="warning" %}
Browsers block unmuted playback and microphone capture without a user gesture. Call `startStream()` from within a user interaction (for example, your own button's click handler), and make sure the iframe is embedded with the required permissions:

```html
<iframe id="vagonFrame" allow="autoplay; microphone *; camera *; fullscreen; clipboard-read *; clipboard-write *; encrypted-media *;" src="__Stream_URL__"/>
```

{% endhint %}

## Client-side Integration Events

*All events except onApplicationMessage, onConnected and onDisconnected are only available in Enterprise Plan.*

### **onApplicationMessage**

Prints out the message sent from the application, for application-side integration please check Unreal Engine and Unity SDKs.

```javascript
window.Vagon.onApplicationMessage(evt => {
	console.log(evt.message);
});
```

### onPointerLockChange

Prints out the message when the pointer lock (360 View Mode) state changes.

```javascript
window.Vagon.onPointerLockChange((locked) => {
    console.log(`Pointer Lock is Active: ${locked}`);
});
```

### onInitialization

Prints out the message during the Stream initialization process.

```javascript
window.Vagon.onInitialization(() => {
	console.log("Application is Initializing");
});
```

### onPreparingAssets

Prints out the message during the pixel streaming asset preparation process. Only available in Pixel Streaming enabled Streams.

```javascript
window.Vagon.onPreparingAssets(() => {
	console.log("Application is Preparing Assets");
});
```

### **onInstalling**

Prints out the message when application is on installing state.

```javascript
window.Vagon.onInstalling(() => {
	console.log("Application Installing");
});
```

### **onConnected**

Prints out the message when user is connected.

```javascript
window.Vagon.onConnected(() => {
	console.log("User Connected");
});
```

### **onDisconnected**

Prints out the message when user is disconnected.

```javascript
window.Vagon.onDisconnected(() => {
	console.log("User Disconnected");
});
```

### **onInactive**

Prints out the message when user is inactive. Only available when Idle Duration Limit is active.

```javascript
window.Vagon.onInactive(() => {
	console.log("User Inactive");
});
```

### **onInstallationFailed**

Prints out the message when app installation is failed.

```javascript
window.Vagon.onInstallationFailed(() => {
	console.log("App Installation is Failed");
});
```

### **onFailed**

Prints out the message when connection is failed.

```javascript
window.Vagon.onFailed(() => {
	console.log("Connection is Failed");
});
```

### **onPlayButtonClicked**

Prints out the message when user clicks on the play button in the connection page.

```javascript
window.Vagon.onPlayButtonClicked(() => {
	console.log("Play button is clicked");
});
```

### onSessionInformation

Prints out the message when connection is failed.

```javascript
window.Vagon.onSessionInformation((session_data) => {
	console.log(session_data);
});
```

**Sample Session Data**

```json
{
  "session": {
    ping: 150, // Available for Session Data Collection enabled Streams.
    os: "windows", // Available for Session Data Collection enabled Streams.
    device_type: "desktop", // Available for Session Data Collection enabled Streams.
  },
  "machine": {
    "status": "runinng",
    "friendly_status": "ready",
    "connection_status": "connected",
    "region": "dublin",
    "uid": "05545648-c292-4ef4-b571-d10797f83069",
    "application_id": 1,
    "stream_id": 1,
    "machine_id": 1,
    
  }
}
```


# Unreal Engine SDK

You have to establish a WebSocket connection between your Unreal Engine application and your client-side to let them communicate with each other.

{% hint style="info" %}
If you will send/receive messages from the client side, you have to embed your project into your platform with the iFrame and also integrate the [Streams JS SDK](/streams/integrations/client-side-communication/javascript-sdk) as well.
{% endhint %}

## How to Setup Websocket Connection in Unreal Engine

{% embed url="<https://youtu.be/l9TTmtDBTWY?t=154>" %}

You have to set the Web Socket address as a constant URL like this:

```cpp
FString WebSocketAddress = "ws://127.0.0.1:7788”;
```

and, you have to send Header parameters while initializing the Web Socket connection like this:

```cpp
TMap<FString, FString> WsUpgradeHeaders;
WsUpgradeHeaders.Add(TEXT("Host"), TEXT("127.0.0.1:7788"));
WebSocket = FWebSocketsModule::Get().CreateWebSocket(WebSocketAddress, TEXT("ws"), WsUpgradeHeaders);
```

## Integration with Plugins

### [Zephyr Entertainment](https://www.unrealengine.com/marketplace/en-US/profile/Zephyr+Entertainment)'s Blueprint WebSockets Plugin

First of all, you have to set up the plugin and integrate it into your application by following the [plugin integration guidelines](https://docs.google.com/document/d/1EXeESlA3gbdMkv2n9b5hhK5mhQTMLh-9aGH3XV_pdYs/edit). Also, you can directly use their [Blueprint template](https://blueprintue.com/blueprint/398kr_cz/) and configure it according to the unique flow of your application.

After integrating the plugin according to their guidelines, **you have to replace&#x20;**<mark style="color:blue;">**Create**</mark> <mark style="color:blue;">**WebSocket**</mark>**&#x20;connection with&#x20;**<mark style="color:blue;">**Create WebSocket with Headers**</mark>**&#x20;connection** to an additional header to your Blueprint.

Then, you have to set the Server URL as `ws://127.0.0.1:7788` and set the Header parameters as below,

* **Key:** `HOST`
* **Value:** [`127.0.0.1:7788`](http://127.0.0.1:7788/)

### [Pandores](https://www.unrealengine.com/marketplace/en-US/profile/Pandores)'s BlueprintWebSocket Plugin

First of all, you have to set up the plugin and integrate it into your application by following the [plugin integration guidelines](https://github.com/Pandoa/BlueprintWebSocket/blob/master/README.md), and configure it according to the unique flow of your application.

While integrating the Blueprint flow you have to Set Header and attach this header while creating Web Socket Connection.

You have to set the Server URL as `ws://127.0.0.1:7788` and set the Header parameters as,

* **Key:** `HOST`
* **Value:** [`127.0.0.1:7788`](http://127.0.0.1:7788/)

<figure><img src="/files/7TrL4KFQrddq8yaESN9T" alt=""><figcaption></figcaption></figure>

## Predefined Actions

### Open a Link in a New Browser Page

You can initiate action to open a specific URL from the default browser of your visitor from inside your application. You should send a Websocket message by following the format below, message should be JSON formatted plain text message.

```
{\"$type\":\"8\",\"Url\":\"https://www.vagon.io\"}
```

```json
{
  "$type": "8",
  "Url": "https://www.vagon.io"
}
```

{% hint style="info" %}
When your build is working with Vagon Streams, there is a prebuilt Web Socket server to send/receive your messages, so you don't need to create a separate Web Socket server in your application.

However, if you are testing your build locally you might need to change the URLs shared below to your local Web Socket server to send/receive your messages.
{% endhint %}

### Show On-Screen Keyboard Button

If your visitors are using your Applications on mobile/tablet devices, you can also allow them to type with the on-screen keyboard inside Vagon Streams. The good part is, you can manage the visibility of the on-screen keyboard button directly from your application, and trigger actions to show the keyboard button when the visitor focuses on an input inside the application. To show the On Screen Keyboard Button, you should send a Websocket message by following the format below, message should be JSON formatted plain text message.

```
{\"$type\":\"9\"}
```

```json
{
  "$type": "9"
}
```

### Hide On-Screen Keyboard Button

When the focus changes from the input, you can hide the on-screen keyboard button from the screen as well. Again, you should send a Websocket message by following the format below, message should be JSON formatted plain text message.

```
{\"$type\":\"10\"}
```

```json
{
  "$type": "10"
}
```

### Enable 360 View Mode

Independently from Application Configurations, you can enable 360 View Mode inside your application by sending the following message via Websocket.

After sending this message, 360 View Mode will be activated with the first mouse click on Stream.

```
{\"$type\":\"11\"}
```

```json
{
  "$type": "11"
}
```

### Disable 360 View Mode

Independently from Application Configurations, you can disable 360 View Mode inside your application by sending the following message via Websocket.

```
{\"$type\":\"12\"}
```

```json
{
  "$type": "12"
}
```

### Keep Stream Alive - Reset Idle Timer

When the Idle Duration Limit is active, you can reset the Idle Timer by sending the message below via Websocket.

```
{\"$type\":\"13\"}
```

```json
{
  "$type": "13"
}
```

### Turn Off Stream Machine

You can send the following message via Websocket to turn off the Stream Machine which is running the related application.

```
{\"$type\":\"14\"}
```

```json
{
  "$type": "14"
}
```

### Resize Frame / Stream

Updates the streaming resolution and matches the iframe height and width when initiated.

```
{\"$type\":\"16\"}
```

```json
{
  "$type": "16"
}
```

### Set Streaming Quality

Quality parameters can be set as "standard", "moderate" or "high". Session will be refreshed automatically after the quality is set.

```
{\"$type\":\"17\",\"Quality\":\"standard\"}
```

```json
{
  "$type": "17",
  "Quality": "standard"
}
```

### Request Session Information

Triggers the `Session Information` event, data must be collected via `Session Information` event.

```
{\"$type\":\"18\"}
```

```json
{
  "$type": "18"
}
```

### Request Machine ID

Triggers the `Machine ID Information` event, data must be collected via `Machine ID Information` event.

```
{\"$type\":\"25\"}
```

```json
{
  "$type": "25"
}
```

## Returned Objects

Message responses will be returned as JSON-formatted string to WebSocket onMessage events. Additional parsing operation may be required.

### Session Information Event

```json
{
  "$type": "19",
  "session": {
    "ping": 150,
    "os": "windows",
    "device_type": "desktop"
  },
  "machine": {
    "status": "runinng",
    "friendly_status": "ready",
    "connection_status": "connected",
    "region": "dublin",
    "uid": "05545648-c292-4ef4-b571-d10797f83069",
    "application_id": 1,
    "stream_id": 1,
    "machine_id": 1
  }
}
```

### Connection Information

`isConnected` returns `true` when user joins to the Session, returns `false` when leaves the session.

```json
{
  "$type": "15",
  "isConnected": true
}
```

### Machine ID Information Event

```json
{
  "$type": "26",
  "id": 1
}
```


# Unity SDK

To establish a connection between your Unity application and your client-side. You have to establish a websocket connection first.

Connect to websocket url `ws://localhost:7788/` using your engine's built-in websocket client.

After establishing the connection, the messages you send to the websocket will be received on the JS side and vice-versa.

### How to Setup Websocket Connection in Unity

{% embed url="<https://www.youtube.com/watch?v=13HnJPstnDM>" %}

### Predefined Actions

#### Open Link in a New Browser Page

You can initiate action to open a specific URL from the default browser of your visitor from inside your application. You should send a Websocket message by following the format below, message should be JSON formatted plain text message.

```json
{
  "$type": "8",
  "Url": "https://www.vagon.io"
}
```

### Show On-Screen Keyboard Button

If your visitors are using your Applications on mobile/tablet devices, you can also allow them to type with the on-screen keyboard inside Vagon Streams. The good part is, you can manage the visibility of the on-screen keyboard button directly from your application, and trigger actions to show the keyboard button when the visitor focuses on an input inside the application. To show the On Screen Keyboard Button, you should send a Websocket message by following the format below, message should be JSON formatted plain text message.

```
{\"$type\":\"9\"}
```

```json
{
  "$type": "9"
}
```

### Hide On-Screen Keyboard Button

When the focus changes from the input, you can hide the on-screen keyboard button from the screen as well. Again, you should send a Websocket message by following the format below, message should be JSON formatted plain text message.

```
{\"$type\":\"10\"}
```

```json
{
  "$type": "10"
}
```

### Enable 360 View Mode

Independently from Application Configurations, you can enable 360 View Mode inside your application by sending the following message via Websocket.

After sending this message, 360 View Mode will be activated with the first mouse click on Stream.

```
{\"$type\":\"11\"}
```

```json
{
  "$type": "11"
}
```

### Disable 360 View Mode

Independently from Application Configurations, you can disable 360 View Mode inside your application by sending the following message via Websocket.

```
{\"$type\":\"12\"}
```

```json
{
  "$type": "12"
}
```

### Keep Stream Alive - Reset Idle Timer

When the Idle Duration Limit is active, you can reset the Idle Timer by sending the message below via Websocket.

```
{\"$type\":\"13\"}
```

```json
{
  "$type": "13"
}
```

### Turn Off Stream Machine

You can send the following message via Websocket to turn off the Stream Machine which is running the related application.

```
{\"$type\":\"14\"}
```

```json
{
  "$type": "14"
}
```

### Resize Frame / Stream

Updates the streaming resolution and matches the iframe height and width when initiated.

```
{\"$type\":\"16\"}
```

```json
{
  "$type": "16"
}
```

### Set Streaming Quality

Quality parameters can be set as "standard", "moderate" or "high". Session will be refreshed automatically after the quality is set.

```
{\"$type\":\"17\",\"Quality\":\"standard\"}
```

```json
{
  "$type": "17",
  "Quality": "standard"
}
```

### Request Session Information

Triggers the `Session Information` event, data must be collected via `Session Information` event.

```
{\"$type\":\"18\"}
```

```json
{
  "$type": "18"
}
```

### Request Machine ID

Triggers the `Machine ID Information` event, data must be collected via `Machine ID Information` event.

```
{\"$type\":\"25\"}
```

```json
{
  "$type": "25"
}
```

## Returned Objects

Message responses will be returned as JSON-formatted string to WebSocket onMessage events. Additional parsing operation may be required.

### Session Information Event

```json
{
  "$type": "19",
  "session": {
    "ping": 150,
    "os": "windows",
    "device_type": "desktop",
  },
  "machine": {
    "status": "runinng",
    "friendly_status": "ready",
    "connection_status": "connected",
    "region": "dublin",
    "uid": "05545648-c292-4ef4-b571-d10797f83069",
    "application_id": 1,
    "stream_id": 1,
    "machine_id": 1,
  }
}
```

### Connection Information

`isConnected` returns `true` when user joins to the Session, returns `false` when leaves the session.

```json
{
  "$type": "15",
  "isConnected": true
}
```

### Machine ID Information Event

```json
{
  "$type": "26",
  "id": 1
}
```


# URL Parameters

If your application needs a client-side integration to pass parameters or any other information to communicate with your application, you can pass dynamic launch flags for each session.

For example, in order to add `-token MY_TOKEN` flag to your application launch flags for a specific `Stream Session`, you should only add `?launchFlags=-token%20MY_TOKEN` at the end of the Stream URL with the parameter, you would like to send. Please note that the launch flags should be URL safe.

```
https://app.vagon.io/stream/_STREAM_ID_?launchFlags=-token%20MY_TOKEN
```

{% hint style="warning" %}
URL Parameters are applied for each Stream Session individually while the Stream Session is starting up. It won't affect any other `Stream Session`.
{% endhint %}

## Launch Parameter Reset - Start New Session with Different Launch Parameters

Launch parameters are set for each user session separately and stored in local storage to apply the same launch arguments if any connection or initialization issue during the connection phase.

If your use case requires sending different launch arguments to the same Stream session, you have to add a `newSession=true` parameter at the end of your Stream URL to reset previous launch arguments.

If you are using `launchFlags` with your Stream URL, you can use both of them by adding & between them.

```
https://app.vagon.io/stream/_STREAM_ID_?launchFlags=-token%20MY_TOKEN&newSession=true
```

{% hint style="info" %}
URL parameters are only supported for the Streams using [Vagon Application Streaming](/streams/vagon-application-streaming). URL Parameter support will be added for Pixel Streaming and Render Streaming projects in the future.
{% endhint %}


# Streams API Services

Streams API is designed to provide full customization and management flexibility to Developers, who are looking for a scalable Pixel Streaming solution to stream applications from any device without any installation.

{% hint style="warning" %}
At least one application must be uploaded and at least one Stream must be created from Streams Dashboard to start using Streams API.
{% endhint %}

By using Streams API you can

* list all your `Applications` you uploaded from `Streams Dashboard`,
* list all `Streams` for `Applications` which you created from `Streams Dashboard`,
* manage `Streams` `Capacities`,
* create and remove `Visitor` data to monitor `Visitor Sessions` from `Streams Dashboard`,
* start, assign and stop `Stream Machines`.

{% content-ref url="/pages/F2oQimW2Xgn4UXbfl2kS" %}
[Authentication](/streams/integrations/streams-api-services/authentication)
{% endcontent-ref %}

{% content-ref url="/pages/bXeXDwQ3GD4pu4rxFzDz" %}
[API Documentation](/streams/integrations/streams-api-services/api-documentation)
{% endcontent-ref %}

{% hint style="info" %}
Streams API only allows you to manage your Streams manually. You can customize your Streams experience from Streams Dashboard on the Stream Configurations page.
{% endhint %}

{% embed url="<https://help.vagon.io/en/articles/6078421-how-to-customize-your-vagon-stream-for-the-best-experience>" %}


# Authentication

### Get your API keys

Before starting API integration for your Streams, your application must be uploaded, and the Stream for the application must be created from the Vagon Dashboard.

* **API Public Key:** you can get it from Vagon Dashboard for each Streams.
* **API Secret:** you can get it from Vagon Dashboard for each Streams.
* **Application ID:** you can get it from Vagon Dashboard for each Streams. Stated as `_Application_ID_` in the document.
* **Region:** Region coverage can be set from Vagon Dashboard for each Streams.

![Share View from the Streams page inside Vagon Streams Dashboard](/files/OotrGFu2tGia9nBXN95U)

### Authentication <a href="#id-1-client-authentication" id="id-1-client-authentication"></a>

The client must be authenticated by using **API Public** and **Secret** **keys** with HMAC authentication, by using the SHA256 algorithm.

* Every API call requires to be authenticated via the Authorization header.
* **Header format**\
  `Authorization: HMAC {key}:{signature}:{nonce}:{timestamp}`
* Signature payload is calculated as\
  `payload = "{api key}{request method}{request path}{timestamp}{nonce}{request body}"`
* `request path` shouldn't include the base API endpoint. For example if you sending a GET request to `https://api.vagon.io/app-stream-management/v2/applications` the `request path` should be `/app-stream-management/v2/applications`
* Request body should be an empty string for `GET` requests.
* Signature is calculated as the\
  `signature = HMAC(SHA256, payload, api secret)`
* Signature should be in HexaDecimal format
* The nonce is a random string value and the timestamp is the current UTC timestamp (milliseconds).


# API Documentation

## **Applications**

<mark style="color:blue;">`GET`</mark> `https://api.vagon.io/app-stream-management/v2/applications`

Returns all applications in Developer account. Application IDs will be used for other endpoints.

#### Query Parameters

| Name                                        | Type | Description |
| ------------------------------------------- | ---- | ----------- |
| page<mark style="color:red;">\*</mark>      | 1    |             |
| per\_page<mark style="color:red;">\*</mark> | 100  |             |

#### Headers

| Name                                            | Type                                       | Description |
| ----------------------------------------------- | ------------------------------------------ | ----------- |
| Authorization<mark style="color:red;">\*</mark> | HMAC {key}:{signature}:{nonce}:{timestamp} |             |
| Content-Type                                    | application/json                           |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "applications": [
    {
      "id": "11421",
      "type": "application",
      "attributes": {
        "id": 11421,
        "name": "Test Application",
        "status": "active",
        "banner_url": null,
        "logo_url": null,
        "friendly_status": "no_streams",
        "os": "windows",
        "active_executable": {
          "id": "122411",
          "type": "executable",
          "attributes": {
            "executable_name": "Application",
            "launch_arguments": null,
            "restart_arguments": null,
            "file": "Application.zip",
            "version": 1,
            "active": true,
            "created_at": "2024-03-07T14:40:23.744Z",
            "images": []
          }
        },
        "performance": "Pro - G2",
        "enterprise": null,
        "pro": null
      }
    }
  ],
  "count": 7,
  "page": 1,
  "client_code": 200,
  "timestamp": "2024-03-27T10:29:25Z"
}
```

{% endtab %}

{% tab title="404: Not Found" %}

```json
{
  "message": "Not Found",
  "client_code": 404,
  "timestamp": "2024-03-27T10:11:43Z"
}
```

{% endtab %}

{% tab title="401: Unauthorized " %}

```json
```

{% endtab %}
{% endtabs %}

## **Streams**

Streams endpoints allow you to manage your Stream Machines according to your custom workflow.

You have to create a Stream link from `Vagon Dashboard` to use `Streams` endpoints to manage your `Streams Machines`.

<mark style="color:blue;">`GET`</mark> `https://api.vagon.io/app-stream-management/v2/streams`

Returns all Streams and Streams details under the selected application

#### Query Parameters

| Name                                              | Type   | Description |
| ------------------------------------------------- | ------ | ----------- |
| page                                              | 1      |             |
| per\_page                                         | 100    |             |
| application\_id<mark style="color:red;">\*</mark> | String |             |

#### Headers

| Name          | Type                                       | Description |
| ------------- | ------------------------------------------ | ----------- |
| Content-Type  | application/json                           |             |
| Authorization | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "streams": [
    {
      "id": "138681",
      "type": "stream",
      "attributes": {
        "id": 138681,
        "name": "Stream",
        "status": "active",
        "uid": "416d2b18-90av-a71k-2034-9f282c3f8603",
        "resolution": "res_1080p",
        "collect_info": false,
        "dark_mode": null,
        "password_protection": false,
        "sound": "user_can_activate",
        "microphone": "user_can_activate",
        "launch_arguments": null,
        "dock_position": "bottom",
        "keyboard_layout": null,
        "user_session_data": false,
        "boost_enabled": false,
        "pixel_streaming_enabled": false,
        "port_access_enabled": false,
        "maximum_session_duration": "off",
        "idle_duration": "off",
        "auto_turn_off_duration": "5_min",
        "application": {
          "id": "11421",
          "type": "application",
          "attributes": {
            "id": 11421,
            "name": "Test Application",
            "status": "active",
            "banner_url": null,
            "logo_url": null,
            "friendly_status": "live",
            "os": "windows",
            "active_executable": {
              "id": "122411",
              "type": "executable",
              "attributes": {
                "executable_name": "Application",
                "launch_arguments": null,
                "restart_arguments": null,
                "file": "Application.zip",
                "version": 1,
                "active": true,
                "created_at": "2024-03-07T14:40:26.896Z",
                "images": []
              }
            },
            "performance": "Pro - G2",
            "enterprise": null,
            "pro": null
          }
        },
        "in_active_time_range": true
      }
    }
  ],
  "count": 2,
  "page": 1,
  "client_code": 200,
  "timestamp": "2024-03-27T10:36:47Z"
}
```

{% endtab %}

{% tab title="404: Not Found" %}

```json
{
	"message": "Not Found",
	"client_code": 404,
	"timestamp": "2024-03-27T10:11:43Z"
}
```

{% endtab %}
{% endtabs %}

## **Stream Machines**

<mark style="color:blue;">`GET`</mark> `https://api.vagon.io/app-stream-management/v2/streams/{stream_id}/machines`

Returns all Stream Machines and their status under the Streams

#### Path Parameters

| Name                                         | Type   | Description |
| -------------------------------------------- | ------ | ----------- |
| stream\_id<mark style="color:red;">\*</mark> | String |             |

#### Query Parameters

| Name      | Type | Description |
| --------- | ---- | ----------- |
| page      | 1    |             |
| per\_page | 10   |             |

#### Headers

| Name                                            | Type                                       | Description |
| ----------------------------------------------- | ------------------------------------------ | ----------- |
| Content-Type                                    | application/json                           |             |
| Authorization<mark style="color:red;">\*</mark> | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "machines": [
    {
      "id": "9462282",
      "type": "machine",
      "attributes": {
        "start_at": "2024-03-27T08:48:46.948Z",
        "end_at": "2024-03-27T08:55:12.763Z",
        "status": "stopped",
        "friendly_status": "off",
        "connection_status": "terminated",
        "region": "dublin",
        "uid": "4df05d4e-af92-ad82-2034-2f2cc0f57ea2",
        "cost": "0.182",
        "duration": 385,
        "application_name": "Test Application",
        "application_id": 1151,
        "stream_id": 1364,
        "stream_name": "Stream #2240",
        "machine_type": "Pro - G2",
        "public_ip_address": null
      }
    }
  ],
  "count": 5,
  "page": 1,
  "client_code": 200,
  "timestamp": "2024-03-27T10:39:43Z"
}
```

{% endtab %}

{% tab title="404: Not Found" %}

```json
{
  "message": "Not Found",
  "client_code": 404,
  "timestamp": "2024-03-27T10:40:45Z"
}
```

{% endtab %}
{% endtabs %}

#### **Stream Machine Status Details**

<table><thead><tr><th width="272.97701149425285">Stream Machine Status</th><th>Details</th></tr></thead><tbody><tr><td><strong><code>waiting</code></strong></td><td>Stream is still booting up and preparing for connection.</td></tr><tr><td><strong><code>available</code></strong></td><td>Stream is ready for assigning and then connecting.</td></tr><tr><td><strong><code>assigned</code></strong></td><td>Stream is assigned to a User, but not connected yet.</td></tr><tr><td><strong><code>connected</code></strong></td><td>Stream is connected, and there is an active session.</td></tr><tr><td><strong><code>terminated</code></strong></td><td>Stream is turned off, and terminated.</td></tr><tr><td><strong><code>proxy-in-migration</code></strong></td><td>Stream is getting ready for the next visitor.</td></tr></tbody></table>

{% hint style="info" %}
When you use the generated iframe or URL link from the Streams Dashboard, all Stream Machine operations will be done by Streams itself according to your preferences.
{% endhint %}

## **Start Stream Machine**

<mark style="color:green;">`POST`</mark> `https://api.vagon.io/app-stream-management/v2/streams/{stream_id}/start-machine`

Starts a Stream Machine under the given Streams.

#### Path Parameters

| Name                                         | Type   | Description |
| -------------------------------------------- | ------ | ----------- |
| stream\_id<mark style="color:red;">\*</mark> | String |             |

#### Headers

| Name                                            | Type                                       | Description |
| ----------------------------------------------- | ------------------------------------------ | ----------- |
| Content-Type<mark style="color:red;">\*</mark>  | application/json                           |             |
| Authorization<mark style="color:red;">\*</mark> | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

#### Request Body

<table><thead><tr><th width="155.66015625">Name</th><th width="149.55078125">Type</th><th>Description</th></tr></thead><tbody><tr><td>region<mark style="color:red;">*</mark></td><td>String</td><td><p>Stream Machine Location.</p><p>Available regions can be checked via <a data-mention href="/pages/WHCix5hLA8f2W0go9FjO">/pages/WHCix5hLA8f2W0go9FjO</a>page for the selected performance type, and the regions must be active in Stream Configurations.</p></td></tr><tr><td>regions</td><td>Array of String</td><td>Alternative Stream Machine Locations, only available for Automated Setup.</td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "94683",
  "type": "machine",
  "attributes": {
    "start_at": "2024-03-27T10:52:13.858Z",
    "end_at": null,
    "status": "pending",
    "friendly_status": "turning_on",
    "connection_status": "waiting",
    "region": "dublin",
    "uid": "11a17688-221c-4707-94dd-a2af9116d7d0",
    "cost": "0.0",
    "duration": 0,
    "application_name": "Test Application",
    "application_id": 1143,
    "stream_id": 1381,
    "stream_name": "Stream #1381",
    "machine_type": "Starter",
    "public_ip_address": null
  },
  "client_code": 200,
  "timestamp": "2024-03-27T10:52:15Z"
}
```

{% endtab %}

{% tab title="404: Not Found" %}

```json
{
  "client_code": 404,
  "message": "Not Found",
  "timestamp": "2024-03-27T10:53:28Z"
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
  "client_code": 4601,
  "message": "Insufficient Capacity",
  "timestamp": "2024-03-27T10:54:53Z"
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
  "client_code": 4603,
  "message": "Region must be activated",
  "timestamp": "2024-03-27T10:56:06Z"
}
```

{% endtab %}

{% tab title="400: Bad Request" %}

```json
{
  "client_code": 4609,
  "message": "Stream is not active",
  "timestamp": "2024-03-27T10:59:53Z"
}
```

{% endtab %}

{% tab title="400: Bad Request" %}

```json
{
  "client_code": 4610,
  "message": "Stream capacity management method must be Cost Optimized - on_demand",
  "timestamp": "2024-03-27T10:57:19Z"
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
This endpoint can only be used with **Cost Optimized** Streams. For **Availability Optimized** or **Balanced** Streams, the system will automatically handle the capacity management.

Capacity Management configuration can be updated via Streams Dashboard.

If you try to start a Stream Machine for **Availability Optimized** or **Balanced** streams, you will get a **4610** error from the endpoint.
{% endhint %}

<table><thead><tr><th>Region Name</th><th>Parameter Value</th><th data-hidden></th></tr></thead><tbody><tr><td>Dublin</td><td>dublin</td><td></td></tr><tr><td>North Virginia</td><td>north_virginia</td><td></td></tr><tr><td>Oregon</td><td>oregon</td><td></td></tr><tr><td>Ohio</td><td>ohio</td><td></td></tr><tr><td>Montreal</td><td>montreal</td><td></td></tr><tr><td>California</td><td>california</td><td></td></tr><tr><td>Sao Paolo</td><td>sao_paolo</td><td></td></tr><tr><td>Stockholm</td><td>stockholm</td><td></td></tr><tr><td>Frankfurt</td><td>frankfurt</td><td></td></tr><tr><td>Bahrain</td><td>bahrain</td><td></td></tr><tr><td>Mumbai</td><td>mumbai</td><td></td></tr><tr><td>Seoul</td><td>seoul</td><td></td></tr><tr><td>Tokyo</td><td>tokyo</td><td></td></tr><tr><td>Singapore</td><td>singapore</td><td></td></tr><tr><td>Sydney</td><td>sydney</td><td></td></tr><tr><td>Jakarta</td><td>jakarta</td><td></td></tr><tr><td>Dubai</td><td>uae</td><td></td></tr><tr><td>Cape Town</td><td>cape_town</td><td></td></tr><tr><td>Hong Kong</td><td>hong_kong</td><td></td></tr></tbody></table>

## **Assign Stream Machine**

After running the Stream, Developer must assign the session to a User. As a response of this request, the system will automatically assign a Stream to the User, API will return a Session Link, and the client will be able to give access to the User by embedding Session Link to an iframe.

<mark style="color:green;">`POST`</mark> `https://api.vagon.io/app-stream-management/v2/streams/{stream_id}/assign-machine`

Assigns an available Streams Machine to your Visitor

#### Path Parameters

| Name                                         | Type   | Description |
| -------------------------------------------- | ------ | ----------- |
| stream\_id<mark style="color:red;">\*</mark> | String |             |

#### Headers

| Name                                           | Type                                       | Description |
| ---------------------------------------------- | ------------------------------------------ | ----------- |
| Content-Type<mark style="color:red;">\*</mark> | application/json                           |             |
| Authorization                                  | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

#### Request Body

<table><thead><tr><th width="131.9140625">Name</th><th width="165.13671875">Type</th><th>Description</th></tr></thead><tbody><tr><td>region<mark style="color:red;">*</mark></td><td>String</td><td><p>Stream Machine Location.</p><p>Available regions can be checked via <a data-mention href="/pages/WHCix5hLA8f2W0go9FjO">/pages/WHCix5hLA8f2W0go9FjO</a>page for the selected performance type, and the regions must be active in Stream Configurations.</p></td></tr><tr><td>regions</td><td>Array of String</td><td>Alternative Stream Machine Locations, only available for Automated Setup.</td></tr><tr><td>user_id</td><td>String</td><td><code>user_id</code> can be generated via Create Visitor endpoint</td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "client_code": 200,
  "connection_link": "https://sb-app.vagon.io/stream/bf96fb3b-9420-asf2-8dc5-b8477fd52303",
  "machine": {
    "id": "946869128",
    "type": "machine",
    "attributes": {
      "start_at": "2024-03-27T11:05:42.144Z",
      "end_at": null,
      "status": "pending",
      "friendly_status": "turning_on",
      "connection_status": "assigned",
      "region": "dublin",
      "uid": "bf96fb3b-9420-asf2-8dc5-b8477fd52303",
      "cost": "0.0",
      "duration": 0,
      "application_name": "Test Application",
      "application_id": 1143,
      "stream_id": 1381,
      "stream_name": "Stream #138241",
      "machine_type": "Pro - G2",
      "public_ip_address": null
    }
  },
  "message": null,
  "timestamp": "2024-03-27T11:05:49Z"
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
  "client_code": 4603,
  "message": "Region must be activated",
  "timestamp": "2024-03-27T11:06:35Z"
}
```

{% endtab %}

{% tab title="404: Not Found" %}

```json
{
  "client_code": 404,
  "message": "Not Found",
  "timestamp": "2024-03-27T11:08:03Z"
}
```

{% endtab %}
{% endtabs %}

## **Stop Stream Machine**

<mark style="color:green;">`POST`</mark> `https://api.vagon.io/app-stream-management/v2/streams/stop-machine`

Turns off a running Streams Machine

#### Headers

| Name                                            | Type                                       | Description |
| ----------------------------------------------- | ------------------------------------------ | ----------- |
| Content-Type<mark style="color:red;">\*</mark>  | application/json                           |             |
| Authorization<mark style="color:red;">\*</mark> | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

#### Request Body

| Name                                          | Type   | Description |
| --------------------------------------------- | ------ | ----------- |
| machine\_id<mark style="color:red;">\*</mark> | String |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "client_code": 200,
  "timestamp": "2024-03-27T11:10:38Z"
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
  "client_code": 400,
  "timestamp": "2024-03-27T11:10:44Z"
}
```

{% endtab %}
{% endtabs %}

## **Create User**

Developer must create User(s) to give access to a Stream for each User. You can provide an email address to identify your Users, or you can send the request by leaving that parameter blank.

Sending an email is not a mandatory field, but it will help you to track User usage.

<mark style="color:green;">`POST`</mark> `https://api.vagon.io/app-stream-management/v2/users`

Creates Visitor information to monitor their Streams usages

#### Headers

| Name          | Type                                       | Description |
| ------------- | ------------------------------------------ | ----------- |
| Content-Type  | application/json                           |             |
| Authorization | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

#### Request Body

| Name  | Type                 | Description                                               |
| ----- | -------------------- | --------------------------------------------------------- |
| email | <visitor@vendor.com> | Email address of the user, who will connect to the Stream |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "7D4F4EA7F4",
  "type": "user",
  "attributes": {
    "email": "team@vagon.io"
  },
  "client_code": 200,
  "timestamp": "2024-03-27T11:18:26Z"
}
```

{% endtab %}

{% tab title="401: Unauthorized " %}

```json
{
  "message": "Parameter must match email format",
  "client_code": 400,
  "timestamp": "2024-03-27T11:19:06Z"
}
```

{% endtab %}
{% endtabs %}

## **Remove User**

<mark style="color:red;">`DELETE`</mark> `https://api.vagon.io/app-stream-management/v2/users/{user_id}`

Delete a previously created Visitor record

#### Path Parameters

| Name     | Type   | Description |
| -------- | ------ | ----------- |
| user\_id | String |             |

#### Headers

| Name          | Type                                       | Description |
| ------------- | ------------------------------------------ | ----------- |
| Content-Type  | application/json                           |             |
| Authorization | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "client_code": 200,
  "timestamp": "2024-03-27T11:20:09Z"
}
```

{% endtab %}

{% tab title="404: Not Found " %}

{% endtab %}
{% endtabs %}

## **Stream Machine Stats**

<mark style="color:blue;">`GET`</mark> `https://api.vagon.io/app-stream-management/v2/machines`

Retrieve all running and previously active Stream Machines with stats

#### Query Parameters

| Name            | Type                   | Description                            |
| --------------- | ---------------------- | -------------------------------------- |
| start\_at       | yyyy-MM-dd'T'HH:mm:ssZ | ***Sample:*** 2023-09-15T06:42:36.564Z |
| end\_at         | yyyy-MM-dd'T'HH:mm:ssZ | ***Sample:*** 2023-09-15T06:42:36.564Z |
| page            | Integer                | ***Default:*** 1                       |
| per\_page       | Integer                | ***Default:*** 20                      |
| application\_id | Integer                |                                        |
| stream\_id      | Integer                |                                        |

#### Headers

| Name                                            | Type                                       | Description |
| ----------------------------------------------- | ------------------------------------------ | ----------- |
| Content-Type<mark style="color:red;">\*</mark>  | application/json                           |             |
| Authorization<mark style="color:red;">\*</mark> | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "machines": [
    {
      "id": "94688",
      "type": "machine",
      "attributes": {
        "start_at": "2024-03-27T11:05:42.144Z",
        "end_at": "2024-03-27T11:10:29.548Z",
        "status": "stopped",
        "friendly_status": "off",
        "connection_status": "terminated",
        "region": "dublin",
        "uid": "bf96fb3b-edc3-43ce-8dc5-b8477fd52303",
        "cost": "0.13",
        "duration": 287,
        "application_name": "Test Application",
        "application_id": 1143,
        "stream_id": 1381,
        "stream_name": "Stream #1381",
        "machine_type": "Pro - G2",
        "public_ip_address": null
      }
    }
  ],
  "count": 6,
  "page": 1,
  "client_code": 200,
  "timestamp": "2024-03-27T11:21:44Z"
}
```

{% endtab %}

{% tab title="400: Bad Request" %}

```
// Returns when application_id and stream_id are requested at the same time
```

{% endtab %}
{% endtabs %}

## **Single Stream Machine Stats**

<mark style="color:blue;">`GET`</mark> `https://api.vagon.io/app-stream-management/v2/machines/{machine_uid}`

Retrieve a specific Stream Machines with stats.

#### Headers

| Name                                            | Type                                       | Description |
| ----------------------------------------------- | ------------------------------------------ | ----------- |
| Content-Type<mark style="color:red;">\*</mark>  | application/json                           |             |
| Authorization<mark style="color:red;">\*</mark> | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "94688",
  "type": "machine",
  "attributes": {
    "start_at": "2024-03-27T11:05:42.144Z",
    "end_at": "2024-03-27T11:10:29.548Z",
    "status": "stopped",
    "friendly_status": "off",
    "connection_status": "terminated",
    "region": "dublin",
    "uid": "bf96fb3b-edc3-43ce-8dc5-b8477fd52303",
    "cost": "0.13",
    "duration": 287,
    "application_name": "Test Application",
    "application_id": 1143,
    "stream_id": 1381,
    "stream_name": "Stream #1381",
    "machine_type": "Pro - G2",
    "public_ip_address": null
  },
  "client_code": 200,
  "timestamp": "2024-03-27T11:21:44Z"
}
```

{% endtab %}
{% endtabs %}

## **Visitor Session Stats**

<mark style="color:blue;">`GET`</mark> `https://api.vagon.io/app-stream-management/v2/sessions`

Retrieve all Visitor Sessions with additional stats

#### Query Parameters

| Name            | Type                   | Description                            |
| --------------- | ---------------------- | -------------------------------------- |
| start\_at       | yyyy-MM-dd'T'HH:mm:ssZ | ***Sample:*** 2023-09-15T06:42:36.564Z |
| end\_at         | yyyy-MM-dd'T'HH:mm:ssZ | ***Sample:*** 2023-09-15T06:42:36.564Z |
| page            | Integer                | ***Default:*** 1                       |
| per\_page       | Integer                | ***Default:*** 20                      |
| application\_id | Integer                |                                        |
| stream\_id      | Integer                |                                        |

#### Headers

| Name                                            | Type                                       | Description |
| ----------------------------------------------- | ------------------------------------------ | ----------- |
| Content-Type<mark style="color:red;">\*</mark>  | application/json                           |             |
| Authorization<mark style="color:red;">\*</mark> | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "sessions": [
    {
      "id": "9150",
      "type": "vendor_customer_session",
      "attributes": {
        "start_at": "2024-03-11T08:03:47.735Z",
        "end_at": "2024-03-11T08:07:17.645Z",
        "region": "dublin",
        "ping": 98,
        "audio_state": "muted",
        "audio_input": {
          "kind": "audioinput",
          "label": "",
          "groupId": "",
          "deviceId": "default"
        },
        "audio_output": {
          "kind": "audiooutput",
          "label": "",
          "groupId": "",
          "deviceId": "default"
        },
        "duration": 4,
        "readable_duration": "4 minutes",
        "city": null,
        "country": null,
        "os": null,
        "device_type": null,
        "customer": "CUS_9150",
        "application_name": "Test Application",
        "application_id": 1143,
        "stream_id": 1369,
        "stream_name": "Stream #1369",
        "machine_type": "Pro - G2"
      }
    }
  ],
  "count": 23,
  "page": 1,
  "next_page": 2,
  "client_code": 200,
  "timestamp": "2024-03-27T11:25:44Z"
}
```

{% endtab %}

{% tab title="404: Not Found " %}

{% endtab %}

{% tab title="400: Bad Request" %}

```
// Returns when application_id and stream_id are requested at the same time
```

{% endtab %}
{% endtabs %}

<table><thead><tr><th>Attributes</th><th width="283.3333333333333">Values</th><th>Description</th></tr></thead><tbody><tr><td>start_at</td><td>2023-09-14T14:00:39.834Z</td><td></td></tr><tr><td>end_at</td><td>2023-09-14T14:03:09.894Z</td><td></td></tr><tr><td>region</td><td>dublin</td><td></td></tr><tr><td>ping</td><td>78.625</td><td></td></tr><tr><td>audio_state</td><td><code>muted</code><br><code>playing</code><br><code>not_collected</code></td><td></td></tr><tr><td>audio_input</td><td><pre class="language-json"><code class="lang-json">{
  "kind": "audioinput",
  "label": "",
  "groupId": "",
  "deviceId": ""
}
</code></pre></td><td></td></tr><tr><td>audio_output</td><td><pre class="language-json"><code class="lang-json">{
  "kind": "audioinput",
  "label": "",
  "groupId": "",
  "deviceId": ""
}
</code></pre></td><td></td></tr><tr><td>duration</td><td>3</td><td>minutes</td></tr><tr><td>readable_duration</td><td>3 minutes</td><td></td></tr><tr><td>city</td><td>San Francisco</td><td><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> Data Collection must be enabled</td></tr><tr><td>country</td><td>US</td><td><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> Data Collection must be enabled</td></tr><tr><td>os</td><td>Windows 11</td><td><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> Data Collection must be enabled</td></tr><tr><td>device_type</td><td>desktop</td><td><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> Data Collection must be enabled</td></tr><tr><td>customer</td><td>CUS_625289</td><td><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> Email Collection must be enabled for Visitor Email address</td></tr><tr><td>application_name</td><td>AwesomeApp</td><td></td></tr><tr><td>application_id</td><td>870</td><td></td></tr><tr><td>stream_id</td><td>587</td><td></td></tr><tr><td>stream_name</td><td>Stream #587</td><td></td></tr><tr><td>machine_type</td><td>Pro - G2</td><td></td></tr></tbody></table>

## **Configure Application Settings**

<mark style="color:orange;">`PUT`</mark> `https://api.vagon.io/app-stream-management/v2/applications/{application_id}`

Configure existing application settings.

#### Path Parameters

| Name            | Type   | Description |
| --------------- | ------ | ----------- |
| application\_id | String |             |

#### Headers

| Name          | Type                                       | Description |
| ------------- | ------------------------------------------ | ----------- |
| Content-Type  | application/json                           |             |
| Authorization | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

#### Request Body

| Name                     | Type    | Options                                                                                                                       |
| ------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
| application\_name        | String  |                                                                                                                               |
| key\_mapping\_selection  | String  | `click` `game_mode`                                                                                                           |
| changeable\_key\_mapping | Boolean |                                                                                                                               |
| machine\_type\_id        | Integer | <p><code>Starter - 9</code></p><p><code>Pro - 17</code></p><p><code>Starter G2 - 12</code></p><p><code>Pro G2 - 13</code></p> |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "1143",
  "type": "application",
  "attributes": {
    "id": 1143,
    "name": "Test Application",
    "status": "active",
    "banner_url": null,
    "logo_url": null,
    "friendly_status": "live",
    "os": "windows",
    "active_executable": {
      "id": "1222",
      "type": "executable",
      "attributes": {
        "executable_name": "Application",
        "launch_arguments": null,
        "restart_arguments": null,
        "file": "Application.zip",
        "version": 1,
        "active": true,
        "created_at": "2024-03-07T14:40:26.896Z",
        "images": []
      }
    },
    "performance": "Pro - G2",
    "enterprise": null,
    "pro": null
  },
  "client_code": 200,
  "timestamp": "2024-03-27T11:35:18Z"
}
```

{% endtab %}

{% tab title="404: Not Found " %}

```json
{
  "message": "Not Found",
  "client_code": 404,
  "timestamp": "2024-03-27T11:37:44Z"
}
```

{% endtab %}
{% endtabs %}

## **Configure Stream Settings**

<mark style="color:orange;">`PUT`</mark> `https://api.vagon.io/app-stream-management/v2/streams/{stream_id}`

Configure existing Stream settings.

#### Path Parameters

| Name       | Type   | Description |
| ---------- | ------ | ----------- |
| stream\_id | String |             |

#### Headers

| Name          | Type                                       | Description |
| ------------- | ------------------------------------------ | ----------- |
| Content-Type  | application/json                           |             |
| Authorization | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

#### Request Body

<table><thead><tr><th width="266">Name</th><th width="252">Type</th><th>Options</th></tr></thead><tbody><tr><td>resolution</td><td>String</td><td><code>res_scale</code> <code>res_720p</code> <code>res_1080p</code> <code>res_2160p</code></td></tr><tr><td>name</td><td>String</td><td></td></tr><tr><td>sound</td><td>String</td><td><code>off</code> <code>activate_on_start</code> <code>user_can_activate</code></td></tr><tr><td>microphone</td><td>String</td><td><code>off</code> <code>activate_on_start</code> <code>user_can_activate</code></td></tr><tr><td>auto_turn_off_duration</td><td>String</td><td><code>off</code> <code>immediately</code> <code>2_min</code> <code>5_min</code> <code>30_min</code> <code>1_hour</code> <code>3_hour</code> <code>6_hour</code></td></tr><tr><td>maximum_session_duration</td><td>String</td><td><code>off</code> <code>5_min</code> <code>10_min</code> <code>15_min</code> <code>30_min</code> <code>1_hour</code></td></tr><tr><td>idle_duration</td><td>String</td><td><code>off</code> <code>1_min</code> <code>5_min</code> <code>10_min</code></td></tr><tr><td>launch_arguments</td><td>String</td><td></td></tr><tr><td>dark_mode</td><td>Boolean</td><td></td></tr><tr><td>collect_info</td><td>Boolean</td><td></td></tr><tr><td>password</td><td>String</td><td></td></tr><tr><td>password_protection</td><td>String</td><td></td></tr><tr><td>dock_position</td><td>String</td><td><code>hide</code> <code>bottom</code> <code>top</code> <code>left</code></td></tr><tr><td>keyboard_layout</td><td>String</td><td></td></tr><tr><td>user_session_data</td><td>Boolean</td><td></td></tr><tr><td>boost_enabled</td><td>Boolean</td><td></td></tr><tr><td>pixel_streaming_enabled</td><td>Boolean</td><td></td></tr><tr><td>port_access_enabled</td><td>Boolean</td><td></td></tr><tr><td>capacity_type</td><td>String</td><td><code>on_demand</code> <code>balanced</code> <code>always_on</code></td></tr><tr><td>capacities</td><td>Array of Objects</td><td><pre><code>[
  {
    "region": "dublin",
    "total_capacity": "5"
  }
]
</code></pre></td></tr><tr><td>restart_application</td><td>Boolean</td><td></td></tr><tr><td>auto_start_application</td><td>Boolean</td><td></td></tr><tr><td>collect_application_logs</td><td>Boolean</td><td></td></tr><tr><td>game_engine</td><td>String</td><td><code>unreal</code> <code>unity</code></td></tr><tr><td>project_name</td><td>String</td><td>Required for Unreal Engine Apps</td></tr><tr><td>company_name</td><td>String</td><td>Required for Unity Apps</td></tr><tr><td>product_name</td><td>String</td><td>Required for Unity Apps</td></tr><tr><td>region_optimization</td><td>Boolean</td><td></td></tr><tr><td>show_play_page</td><td>Boolean</td><td></td></tr><tr><td>vispr3_streaming</td><td>Boolean</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "1364",
  "type": "stream",
  "attributes": {
    "id": 1364,
    "name": "Stream Name",
    "status": "active",
    "uid": "57f01de3-910a-aa25-2055-cf4a6aef093c",
    "resolution": "res_1080p",
    "collect_info": false,
    "dark_mode": null,
    "password_protection": false,
    "sound": "user_can_activate",
    "microphone": "off",
    "launch_arguments": null,
    "dock_position": "bottom",
    "keyboard_layout": null,
    "user_session_data": false,
    "boost_enabled": false,
    "pixel_streaming_enabled": false,
    "port_access_enabled": false,
    "maximum_session_duration": "off",
    "idle_duration": "off",
    "auto_turn_off_duration": "5_min",
    "restart_application": false,
    "auto_start_application": true,
    "collect_application_logs": true,
    "game_engine": "unity",
    "project_name": "project_name",
    "company_name": "company_name",
    "product_name": "product_name",
    "region_optimization": true,
    "show_play_page": false
    "application": {
      "id": "1151",
      "type": "application",
      "attributes": {
        "id": 1151,
        "name": "Test Application",
        "status": "active",
        "banner_url": null,
        "logo_url": null,
        "friendly_status": "live",
        "os": "windows",
        "active_executable": {
          "id": "1230",
          "type": "executable",
          "attributes": {
            "executable_name": "Application",
            "launch_arguments": null,
            "restart_arguments": null,
            "file": "Application.zip",
            "version": 1,
            "active": true,
            "created_at": "2024-03-08T11:56:45.103Z",
            "images": []
          }
        },
        "performance": "Starter",
        "enterprise": null,
        "pro": null
      }
    },
    "in_active_time_range": true
  },
  "client_code": 200,
  "timestamp": "2024-03-27T09:24:35Z"
}
```

{% endtab %}

{% tab title="404: Not Found " %}

```json
{
  "message": "Not Found",
  "client_code": 404,
  "timestamp": "2024-03-27T11:37:44Z"
}
```

{% endtab %}
{% endtabs %}

## **Stream Configurations**

<mark style="color:blue;">`GET`</mark> `https://api.vagon.io/app-stream-management/v2/streams/{{stream_uid}}`

Retrieve most recent Stream configurations.

#### Path Parameters

| Name        | Type   | Description |
| ----------- | ------ | ----------- |
| stream\_uid | String |             |

Headers

| Name                                            | Type                                       | Description |
| ----------------------------------------------- | ------------------------------------------ | ----------- |
| Content-Type<mark style="color:red;">\*</mark>  | application/json                           |             |
| Authorization<mark style="color:red;">\*</mark> | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "1384",
  "type": "stream",
  "attributes": {
    "id": 1384,
    "status": "active",
    "uid": "75313492-95a9-4acd-82d1-f20a154d8d3c",
    "resolution": "res_1080p",
    "collect_info": false,
    "dark_mode": null,
    "password_protection": false,
    "sound": "user_can_activate",
    "microphone": "user_can_activate",
    "launch_arguments": null,
    "dock_position": "bottom",
    "keyboard_layout": null,
    "user_session_data": false,
    "boost_enabled": false,
    "pixel_streaming_enabled": false,
    "port_access_enabled": false,
    "maximum_session_duration": "off",
    "idle_duration": "off",
    "auto_turn_off_duration": "5_min",
    "capacities": [
      {
        "id": "dublin",
        "type": "vendor_capacity",
        "attributes": {
          "region": "dublin",
          "machine_type_id": 11,
          "capacity_type": "on_demand",
          "reserve_capacity": 0,
          "total_capacity": 10,
          "used_capacity": 1,
          "assignable_machine_count": 0
        }
      }
    ],
    "texts": {
      "initializing_text": "Initializing Stream",
      "session_expired_text": "Session expired, you can reconnect again.",
      "invalid_email_text": "Visitor information is invalid, contact your system admin.",
      "invalid_password_text": "Stream password is incorrect.\nCheck the password or contact your system admin.",
      "not_active_text": "Stream is not active at the moment.\nContact your system admin to check availability.",
      "reconnect_text": "Connection expired, you can reconnect again.",
      "queue_text": "Waiting in queue",
      "installing_application_text": "Installing Application",
      "connecting_text": "Connecting...",
      "idle_text": "Connection expired due to inactivity. \nYou can reconnect again."
    },
    "application": {
      "id": "1144",
      "type": "application",
      "attributes": {
        "id": 1144,
        "name": "Test Application",
        "status": "active",
        "banner_url": null,
        "logo_url": null,
        "friendly_status": "live",
        "os": "windows",
        "active_executable": {
          "id": "1223",
          "type": "executable",
          "attributes": {
            "executable_name": "Application",
            "launch_arguments": null,
            "restart_arguments": null,
            "file": "Application.zip",
            "version": 1,
            "active": true,
            "created_at": "2024-03-07T14:41:13.719Z",
            "images": []
          }
        },
        "performance": "Starter",
        "enterprise": null,
        "pro": null
      }
    },
    "in_active_time_range": true
  },
  "client_code": 200,
  "timestamp": "2024-03-27T13:24:19Z"
}
```

{% endtab %}

{% tab title="404: Not Found " %}

```json
{
  "message": "Not Found",
  "client_code": 404,
  "timestamp": "2024-03-27T11:37:44Z"
}
```

{% endtab %}
{% endtabs %}

## **Create Stream**

<mark style="color:green;">`POST`</mark> `https://api.vagon.io/app-stream-management/v2/streams`

Creates Stream with provided configurations.

#### Headers

| Name          | Type                                       | Description |
| ------------- | ------------------------------------------ | ----------- |
| Content-Type  | application/json                           |             |
| Authorization | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

#### Request Body

<table><thead><tr><th width="249">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>application_id</td><td>String</td><td></td></tr><tr><td>capacities</td><td>Array of Objects</td><td><pre><code>[
  {
    "region": "dublin",
    "total_capacity": "5"
  }
]
</code></pre></td></tr><tr><td>capacity_type</td><td>String</td><td><code>on_demand</code> <code>balanced</code> <code>always_on</code></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "1385",
  "type": "stream",
  "attributes": {
    "id": 1385,
    "status": "active",
    "uid": "4c3771e7-a875-40aa-b5ea-bbb2a429a34e",
    "resolution": "res_1080p",
    "collect_info": false,
    "dark_mode": null,
    "password_protection": false,
    "sound": "user_can_activate",
    "microphone": "user_can_activate",
    "launch_arguments": null,
    "dock_position": "bottom",
    "keyboard_layout": null,
    "user_session_data": false,
    "boost_enabled": false,
    "pixel_streaming_enabled": false,
    "port_access_enabled": false,
    "maximum_session_duration": "off",
    "idle_duration": "off",
    "auto_turn_off_duration": "5_min",
    "capacities": [
      {
        "id": "dublin",
        "type": "vendor_capacity",
        "attributes": {
          "region": "dublin",
          "machine_type_id": 11,
          "capacity_type": "on_demand",
          "reserve_capacity": 0,
          "total_capacity": 5,
          "used_capacity": 0,
          "assignable_machine_count": 0
        }
      }
    ],
    "texts": {
      "initializing_text": "Initializing Stream",
      "session_expired_text": "Session expired, you can reconnect again.",
      "invalid_email_text": "Visitor information is invalid, contact your system admin.",
      "invalid_password_text": "Stream password is incorrect.\nCheck the password or contact your system admin.",
      "not_active_text": "Stream is not active at the moment.\nContact your system admin to check availability.",
      "reconnect_text": "Connection expired, you can reconnect again.",
      "queue_text": "Waiting in queue",
      "installing_application_text": "Installing Application",
      "connecting_text": "Connecting...",
      "idle_text": "Connection expired due to inactivity. \nYou can reconnect again."
    },
    "application": {
      "id": "1144",
      "type": "application",
      "attributes": {
        "id": 1144,
        "name": "Test Application",
        "status": "active",
        "banner_url": null,
        "logo_url": null,
        "friendly_status": "live",
        "os": "windows",
        "active_executable": {
          "id": "1223",
          "type": "executable",
          "attributes": {
            "executable_name": "Application",
            "launch_arguments": null,
            "restart_arguments": null,
            "file": "Application.zip",
            "version": 1,
            "active": true,
            "created_at": "2024-03-07T14:41:13.719Z",
            "images": []
          }
        },
        "performance": "Starter",
        "enterprise": null,
        "pro": null
      }
    },
    "in_active_time_range": true
  },
  "client_code": 200,
  "timestamp": "2024-03-27T13:27:54Z"
}
```

{% endtab %}

{% tab title="404: Not Found" %}

```json
{
  "message": "Not Found",
  "client_code": 404,
  "timestamp": "2024-03-27T11:37:44Z"
}
```

{% endtab %}
{% endtabs %}

## **Delete Stream**

#### Delete Stream

<mark style="color:red;">`DELETE`</mark> `https://api.vagon.io/app-stream-management/v2/streams/{stream_id}`

Delete a previously created Stream

#### Path Parameters

| Name       | Type   | Description |
| ---------- | ------ | ----------- |
| stream\_id | String |             |

#### Headers

| Name          | Type                                       | Description |
| ------------- | ------------------------------------------ | ----------- |
| Content-Type  | application/json                           |             |
| Authorization | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "client_code": 200,
  "timestamp": "2024-03-27T11:20:09Z"
}
```

{% endtab %}

{% tab title="404: Not Found " %}

```json
{
  "message": "Not Found",
  "client_code": 404,
  "timestamp": "2024-03-27T11:37:44Z"
}
```

{% endtab %}
{% endtabs %}

## **Activate Stream**

<mark style="color:orange;">`PUT`</mark> `https://api.vagon.io/app-stream-management/v2/streams/{stream_id}/activate`

Activate / run an existing Stream to make it available.

#### Path Parameters

| Name       | Type   | Description |
| ---------- | ------ | ----------- |
| stream\_id | String |             |

#### Headers

| Name          | Type                                       | Description |
| ------------- | ------------------------------------------ | ----------- |
| Content-Type  | application/json                           |             |
| Authorization | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "1384",
  "type": "stream",
  "attributes": {
    "id": 1384,
    "status": "active",
    "uid": "75313492-95a9-4acd-82d1-f20a154d8d3c",
    "resolution": "res_1080p",
    "collect_info": false,
    "dark_mode": null,
    "password_protection": false,
    "sound": "user_can_activate",
    "microphone": "user_can_activate",
    "launch_arguments": null,
    "dock_position": "bottom",
    "keyboard_layout": null,
    "user_session_data": false,
    "boost_enabled": false,
    "pixel_streaming_enabled": false,
    "port_access_enabled": false,
    "maximum_session_duration": "off",
    "idle_duration": "off",
    "auto_turn_off_duration": "5_min",
    "capacities": [
      {
        "id": "dublin",
        "type": "vendor_capacity",
        "attributes": {
          "region": "dublin",
          "machine_type_id": 11,
          "capacity_type": "on_demand",
          "reserve_capacity": 0,
          "total_capacity": 10,
          "used_capacity": 1,
          "assignable_machine_count": 0
        }
      }
    ],
    "texts": {
      "initializing_text": "Initializing Stream",
      "session_expired_text": "Session expired, you can reconnect again.",
      "invalid_email_text": "Visitor information is invalid, contact your system admin.",
      "invalid_password_text": "Stream password is incorrect.\nCheck the password or contact your system admin.",
      "not_active_text": "Stream is not active at the moment.\nContact your system admin to check availability.",
      "reconnect_text": "Connection expired, you can reconnect again.",
      "queue_text": "Waiting in queue",
      "installing_application_text": "Installing Application",
      "connecting_text": "Connecting...",
      "idle_text": "Connection expired due to inactivity. \nYou can reconnect again."
    },
    "application": {
      "id": "1144",
      "type": "application",
      "attributes": {
        "id": 1144,
        "name": "Test Application",
        "status": "active",
        "banner_url": null,
        "logo_url": null,
        "friendly_status": "live",
        "os": "windows",
        "active_executable": {
          "id": "1223",
          "type": "executable",
          "attributes": {
            "executable_name": "Application",
            "launch_arguments": null,
            "restart_arguments": null,
            "file": "Application.zip",
            "version": 1,
            "active": true,
            "created_at": "2024-03-07T14:41:13.719Z",
            "images": []
          }
        },
        "performance": "Starter",
        "enterprise": null,
        "pro": null
      }
    },
    "in_active_time_range": true
  },
  "client_code": 200,
  "timestamp": "2024-03-27T13:29:21Z"
}
```

{% endtab %}

{% tab title="400: Bad Request" %}

{% endtab %}
{% endtabs %}

## **Pause Stream**

<mark style="color:orange;">`PUT`</mark> `https://api.vagon.io/app-stream-management/v2/streams/{stream_id}/pause`

Pause / stop an existing Stream to make it unavailable.

#### Path Parameters

| Name       | Type   | Description |
| ---------- | ------ | ----------- |
| stream\_id | String |             |

#### Headers

| Name          | Type                                       | Description |
| ------------- | ------------------------------------------ | ----------- |
| Content-Type  | application/json                           |             |
| Authorization | HMAC {key}:{signature}:{nonce}:{timestamp} |             |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "1384",
  "type": "stream",
  "attributes": {
    "id": 1384,
    "status": "paused",
    "uid": "75313492-95a9-4acd-82d1-f20a154d8d3c",
    "resolution": "res_1080p",
    "collect_info": false,
    "dark_mode": null,
    "password_protection": false,
    "sound": "user_can_activate",
    "microphone": "user_can_activate",
    "launch_arguments": null,
    "dock_position": "bottom",
    "keyboard_layout": null,
    "user_session_data": false,
    "boost_enabled": false,
    "pixel_streaming_enabled": false,
    "port_access_enabled": false,
    "maximum_session_duration": "off",
    "idle_duration": "off",
    "auto_turn_off_duration": "5_min",
    "capacities": [
      {
        "id": "dublin",
        "type": "vendor_capacity",
        "attributes": {
          "region": "dublin",
          "machine_type_id": 11,
          "capacity_type": "on_demand",
          "reserve_capacity": 0,
          "total_capacity": 10,
          "used_capacity": 1,
          "assignable_machine_count": 0
        }
      }
    ],
    "texts": {
      "initializing_text": "Initializing Stream",
      "session_expired_text": "Session expired, you can reconnect again.",
      "invalid_email_text": "Visitor information is invalid, contact your system admin.",
      "invalid_password_text": "Stream password is incorrect.\nCheck the password or contact your system admin.",
      "not_active_text": "Stream is not active at the moment.\nContact your system admin to check availability.",
      "reconnect_text": "Connection expired, you can reconnect again.",
      "queue_text": "Waiting in queue",
      "installing_application_text": "Installing Application",
      "connecting_text": "Connecting...",
      "idle_text": "Connection expired due to inactivity. \nYou can reconnect again."
    },
    "application": {
      "id": "1144",
      "type": "application",
      "attributes": {
        "id": 1144,
        "name": "Test Application",
        "status": "active",
        "banner_url": null,
        "logo_url": null,
        "friendly_status": "live",
        "os": "windows",
        "active_executable": {
          "id": "1223",
          "type": "executable",
          "attributes": {
            "executable_name": "Application",
            "launch_arguments": null,
            "restart_arguments": null,
            "file": "Application.zip",
            "version": 1,
            "active": true,
            "created_at": "2024-03-07T14:41:13.719Z",
            "images": []
          }
        },
        "performance": "Starter",
        "enterprise": null,
        "pro": null
      }
    },
    "in_active_time_range": true
  },
  "client_code": 200,
  "timestamp": "2024-03-27T13:29:21Z"
}
```

{% endtab %}

{% tab title="400: Bad Request" %}

{% endtab %}
{% endtabs %}

## Vagon Pinger.js

Vagon Pinger allows you to find the best region to find the lowest latency location for a better experience for your `Visitors`.

Import VagonPinger to your project by adding the following code piece to your code. Then, use the `bestRegion` parameter value for `Start Streams` and/or `Assign Streams` endpoints.

```javascript
// Import the VagonPinger class
import VagonPinger from "https://app.vagon.io/helpers/VagonPinger.js";

// Ping all regions and log the results
VagonPinger.getRegionPings()
  .then(({ regionPings, bestRegion }) => {
    console.log("Region pings:", regionPings);
    console.log("Best region:", bestRegion);
  })


// Ping specific regions and log the results
VagonPinger.getRegionPings(["dublin", "frankfurt", "north_virginia"])
  .then(({ regionPings, bestRegion }) => {
    console.log("Region pings:", regionPings);
    console.log("Best region:", bestRegion);
  })
```


# Connect over Corporate Networks

Vagon Streams utilizes WebRTC connection over a P2P network to provide the best experience for users.

In some cases, due to internal blocklists and applied firewall rules on company networks, users connecting over Enterprise networks may face connection or streaming performance issues.

To solve this issue, users or/and their network teams must add the following IP addresses to their internal IP allow list to get the best experience over those network conditions.

{% hint style="info" %}
There are multiple IP addresses listed for each region. Even though we suggest adding all IP addresses listed below to the IP allow list, you can use them according to the Region coverage as well.
{% endhint %}

```
//Ports to be Allowed

TCP/UDP/443
TCP/UDP/3478
UDP/49152-65535


//Region IP Addresses

Dublin
108.128.247.206
46.137.22.30

Frankfurt
3.123.182.185
3.125.217.59

Bahrain
16.24.43.27
15.184.80.107

Cape Town
13.246.89.106
13.246.82.38

Hong Kong
18.163.244.69
16.163.189.112

Jakarta
43.218.251.226
43.218.236.41

Montreal
15.222.119.181
15.222.215.145

Mumbai
52.66.125.80
43.205.41.95

North California
184.169.195.7
54.176.31.58

North Virginia
34.195.8.219
35.168.183.190

Ohio
18.223.93.86
3.23.58.161

Oregon
34.210.127.58
52.34.237.101

Seoul
43.202.200.112
13.124.82.177

Singapore
52.74.82.212
54.254.155.254

Sao Paulo
18.229.122.185
54.232.250.161

Stockholm
13.50.181.92
51.20.204.79

Sydney
13.210.52.72
52.65.67.168

Tokyo
18.178.188.247
35.74.75.36

UAE
3.29.45.126
3.28.83.21

// Regions Available Upon Request

Paris
13.36.49.150
15.237.4.42

London
13.41.27.70
18.170.147.31

Milan
15.160.78.213
18.102.194.212
```


# Run Multiple Files & Scripts

<div align="left"><figure><img src="/files/Q6jum2ktNg3RYlu3t7K9" alt="" width="96"><figcaption></figcaption></figure></div>

Vagon Streams allows you to run multiple files and scripts (.bat, Powershell, etc.) before, or after running the application itself. With this feature, it's possible to create custom flows like authenticating the application, resetting the application cache, transferring the user data to another platform or storage service for persistent storage, and more.

<figure><img src="/files/1Xy5Hwi6OK4oDSd4OYuf" alt=""><figcaption></figcaption></figure>

### How to Run Scripts & Executables for Streams

<figure><img src="/files/j3g5JcVwqfXoGyJI4kQq" alt=""><figcaption></figcaption></figure>

1. Choose the script or the executable file you would like to run.
2. Choose when you want to run via Run Schedule: **Before App Starts** or **After App Starts**
3. Choose the running trigger via Frequency: **Once for Each Stream Machine** or **On Every Visitor Session**
4. **Add New File / Script,** and so on.

You can add a new file or script rule anytime you want, and delete previously set ones.


# Application Debugging

## Application Log Collection

After uploading your application and creating your Stream link, you can enable [Application Log Collection](/streams/configurations/advanced#collect-application-logs) from the Stream Configurations > Advanced page for the log-enabled applications.

When it's enabled system will auto-collect the application logs for debug-enabled Unreal Engine and Unity builds, and the logs will be accessible from the Stats page for each Visitor Session.

This method gives you the ability to monitor the application's health and status while streaming it, and you can debug your application in case of any crash or issue.

Please note that this feature is only supported for debug-enabled Unity and Unreal Engine applications.

<figure><img src="/files/m7lh8goLhEcmcDG6WI2q" alt=""><figcaption></figcaption></figure>

## Requesting Support

As Vagon, our support team will be happy to assist you with your onboarding and application testing process. If you need any assistance, please don't hesitate to contact us via <support@vagon.io>


# Multi Tenant Streaming

Multi Tenancy makes it possible to run multiple sessions on a single machine by partitioning the selected performance. You can now launch up to 4 sessions from a single Stream Machine and reduce your usage costs by up to 75% with Multi Tenancy.

As long as the application runs on the selected performance option, it gives you the ability to create multiple **isolated tenants** within a single Stream Machine and enable **independent streaming** for each user.

<figure><img src="https://ci3.googleusercontent.com/meips/ADKq_NZsDvEoXjO2V3ay7RkwEdnZQCcqxkFwTeQ0crLdfdxCSnoxN0nTKsGsh41fui5MkXgD8z8_icaxr-oRm_jsG8MsYmUtjnLnl2-izk_z-0KQdO3w6gtR1kHnK81jlPCdODHhIZCdFObU0Dup5hAEJjVRyAeIog=s0-d-e1-ft#https://5s5uu.img.ag.d.sendibm3.com/im/sh/3b1Ib73jRYaI.png?u=2BpAyz2gMiWnciGhQW5d8DavEgohjV1elf" alt=""><figcaption></figcaption></figure>

### **Key Benefits**

* Serve **more users** with fewer resources.
* **Cut streaming costs** significantly while boosting your concurrent user capacity.

<figure><img src="/files/ZPeNd721ss292x6vOIyd" alt=""><figcaption></figcaption></figure>

### How to Activate M**ulti Tenancy**

1. Ensure your application has the **Pixel Streaming plugin** enabled.
2. Activate the **Multi-Tenancy toggle** from your **Vagon dashboard.**
3. **Vagon Streams** will automatically create **isolated environments** based on your configuration and selected **performance options** to serve your application seamlessly.

{% hint style="success" %}
Enabling [**Instant Installation**](/streams/guides/connection-optimizations#instant-installation) will significantly shorten the initialization process of multiple tenants.
{% endhint %}

{% hint style="danger" %}
Multi Tenant feature is only available for Pixel Streaming-enabled builds.
{% endhint %}


# Visitor Authentication

Require your visitors to sign in with Microsoft Entra, Auth0, or Google before they can access your Stream.

Visitor Authentication (SSO) lets you limit Stream access to authenticated visitors only. When enabled, visitors are redirected to your identity provider — **Microsoft Entra**, **Auth0**, or **Google** — and can only connect to the Stream after a successful login.

{% hint style="info" %}
Visitor Authentication is an **Enterprise** feature and can be configured on **Streams** only.
{% endhint %}

<figure><img src="/files/WEqkAWaJj0jwIwj43tH1" alt=""><figcaption><p>Visitor Authentication (SSO) section in the Visitors tab</p></figcaption></figure>

## How It Works

1. A visitor opens your Stream URL.
2. Vagon redirects the visitor to your identity provider's login page.
3. After the visitor signs in, the provider redirects back to Vagon's **Redirect URI**.
4. Vagon validates the login and the Stream connects.

## Enabling Visitor Authentication

The setup has two sides: configuring an application on your identity provider, and entering its credentials in Vagon. The steps below are common to every provider; see [#provider-setup](#provider-setup) for the provider-specific details.

1. Open your **Streams Dashboard**, select the Stream, and go to **Configure → Visitors**.
2. Toggle **Visitor Authentication (SSO)** on.
3. Select your **SSO Provider** from the dropdown (Microsoft Entra, Auth0 Authentication, or Google OAuth).
4. **Copy the Redirect URI** shown in the panel and register it in your identity provider (see below). The Redirect URI is generated by Vagon and is specific to your Stream — always copy the exact value shown in the dashboard rather than typing it manually.
5. Fill in the provider credentials (**Client ID**, **Client Secret**, and any provider-specific field).
6. Click **Apply Changes**.

{% hint style="warning" %}
The **Redirect URI** must match *exactly* between Vagon and your identity provider. A mismatch is the most common cause of failed logins.
{% endhint %}

## Provider Setup

### Microsoft Entra

**In the Azure Portal (**[**portal.azure.com**](https://portal.azure.com)**):**

1. Go to **Microsoft Entra ID (Azure Active Directory) → App registrations → New registration** and register the app with any name.
2. From the app's **Overview**, copy the **Application (client) ID** and the **Directory (tenant) ID**.
3. Go to **Certificates & secrets → New client secret** and copy the secret **Value** (not the Secret ID).
4. Go to **Authentication → Add a platform → Web** and paste the **Redirect URI** copied from Vagon.
5. Go to **API permissions** and confirm `email`, `openid`, and `profile` are listed, then click **Grant admin consent for Default Directory**.

**In Vagon (Configure → Visitors → Visitor Authentication):**

1. Select provider **Microsoft Entra**.
2. Enter the **Client ID**, **Client Secret**, and **Tenant ID** from the steps above.
3. Confirm the **Redirect URI** matches the one you added in Azure, then click **Apply Changes**.

{% hint style="info" %}
**Adding visitors:** Users in your Entra directory can sign in automatically. To allow external users, go to **Microsoft Entra ID → Users → New user → Invite external user**, enter their email, and send the invite — they must accept it before they can sign in.
{% endhint %}

### Auth0

**In the Auth0 Dashboard:**

1. Go to **Applications → Create Application** and choose **Regular Web Application**.
2. Open the application's **Settings** tab and copy the **Client ID** and **Client Secret**.
3. Add the **Redirect URI** copied from Vagon to **Allowed Callback URLs**, then save changes.
4. Note your **Auth0 Domain** (e.g. `yourcompany.auth0.com`).

**In Vagon (Configure → Visitors → Visitor Authentication):**

1. Select provider **Auth0 Authentication**.
2. Enter the **Client ID**, **Client Secret**, and **Domain**. Vagon automatically derives the authorization and token endpoints from your domain.
3. Confirm the **Callback URL** matches the one you added in Auth0, then click **Apply Changes**.

### Google

**In the Google Cloud Console:**

1. Go to **APIs & Services → Credentials** and create an **OAuth 2.0 Client ID** of type **Web application**.
2. Add the **Redirect URI** copied from Vagon to **Authorized redirect URIs**.
3. Copy the **Client ID** and **Client Secret**.

**In Vagon (Configure → Visitors → Visitor Authentication):**

1. Select provider **Google OAuth**.
2. Enter the **Client ID** and **Client Secret**. No further fields are required — Google's endpoints are preset.
3. Confirm the **Redirect URI** matches the one you added in the Google Console, then click **Apply Changes**.

## Test the Stream

1. Open your Stream URL: `https://streams.vagon.io/streams/<STREAM_UID>`.
2. You should be redirected to your provider's login page.
3. After authenticating, you are redirected back and the Stream connects.

## Troubleshooting

* **Redirect loop or "redirect URI mismatch" error** — The Redirect URI in your identity provider must match the one shown in Vagon character-for-character. Re-copy it from the dashboard.
* **Client Secret shows as dots** — The secret is write-only. Once saved, Vagon never displays it again and shows `••••••••••••••••` as a placeholder. Type a new value only if you want to replace it.


# Troubleshooting

Vagon Streams provides you with the easiest way to create an application streaming experience from any device. However, while testing the experience, some configuration issues can happen. Here are the common mistakes you can easily solve.

### Prerequisites Setup Window Appeared

When you are trying to connect to your Stream if you see the UE Prequisies (x64) Setup window, it's because you chose the wrong file as your application executable.

* Pause the related Stream from the Streams page in your Vagon Streams Dashboard,
* Go back to your Applications page and Click on the Configure button,
* Change the selected executable file from UE prerequisites to your application's main executable file,
* Then, reactivate your Stream link and try to connect to it.

{% hint style="info" %}
All prerequisites for your application have been already installed inside Streams experiences.
{% endhint %}

<figure><img src="https://downloads.intercomcdn.com/i/o/671267145/a238d52e7d0ee2f20ea071bd/image.png?expires=1681105961&#x26;signature=52ebdd9f4af85e31ef400e6dfef1342d5d463fe940aa114c924746b4032c6e56" alt=""><figcaption><p>Application Streaming Prerequisities Installation</p></figcaption></figure>

### Audio / Microphone is Not Working

After creating your Stream link, if you can't get audio and/or microphone working please check the Streams configurations, first.

You should enable audio and/or microphone according to your needs.

<figure><img src="/files/9GKNPcJDHKtjSNPtGAcz" alt=""><figcaption><p>Pixel Streaming Audio and Microphone Support</p></figcaption></figure>

### Application Installation Failed / Missing Game Files

When you try to connect your Stream, if you are getting a Missing Game Files error message, please check your uploaded application folder and be sure that there are no missing required files with your build. If you are sure about that, please contact us for further assistance.

<figure><img src="/files/hpzONVUAP9KeU6OP7fzA" alt=""><figcaption><p>Missing Game Files Error</p></figcaption></figure>

### Keyboard is Not Working inside an iFrame

When you embed the Vagon Streams link as an iFrame to your own platform if you are using custom UI elements on top of your application streaming experience there might be some focus issues while switching between components because of browser limitations.

However, you can easily solve this issue by using `window.Vagon.focusIframe()` the method inside Vagon JS SDK.

{% hint style="info" %}
`window.Vagon.focusIframe()`

Keeps the browser window focused on the streaming iframe. In case you are facing issues with keyboard inputs, you can use this method. Streams JS SDK integration is required.
{% endhint %}

{% content-ref url="/pages/5hsasPU1YqPDElqLbfxx" %}
[Javascript SDK](/streams/integrations/client-side-communication/javascript-sdk)
{% endcontent-ref %}

### Black Screen while Initializing the Application

While connecting to your Vagon Streams experience, if it takes too long to initialize the experience and you are stuck at the black screen too long, please be sure that you optimized the contents inside your application.

Even though you optimize your experience, if your issue persists, we can highly recommend you add a splash screen to your experience to prevent your visitors to stuck at the black screen window.

### Application Not Visible after the First Session

If you face initialization issues after your first session for your application, please check the possible issues below.

#### Minimized Start

Some applications can be set to start in minimized mode, and this configuration causes visitors to stuck on the black screen while connecting to your experience. This issue can be easily fixed from the application configurations.

[Unity Minimized Start - Run in Background Official Fix](https://answers.unity.com/questions/173325/how-to-keep-unity-rendering-when-focus-is-not-set.html)

#### Predefined Resolution Configuration

You can easily choose a predefined resolution from the Streams Configurations page. When you set a predefined resolution or limit your application resolution from in-experience settings, this can cause streaming issues while trying to stream your application from various devices.

Instead of setting a predefined resolution, we highly recommend you set your application to run in Windowed Full-Screen mode.

If you are stuck in a black screen, you can easily test this fix by setting Launch Flags from the Streams Configurations.

**Unreal Engine Launch Flags**

```
-WINDOWED -ResX=1920 -ResY=1080
```

**Unity Launch Flags**

```
-screen-fullscreen 0 -screen-height 1080 -screen-width 1920
```

### Get in Touch

If you are facing an issue that is not listed here, just contact us. We will be happy to help. :100:


# AWS Marketplace

Vagon Streams is also accessible from [AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-dacqev3cisdym), and Vagon credits can be bought via AWS Marketplace for your Vagon account.

This alternative method allows you to use your annual AWS budgets on Vagon Streams with no need for an additional budget from the Finance teams.

It will allow you to utilize your existing discounts and budgets with Vagon Streams and ease the migration process.

<figure><img src="/files/1oa3SHeTzRyAuGoMTXNu" alt=""><figcaption><p>Vagon and AWS Marketplace</p></figcaption></figure>


# Vagon Streams CLI

Upload applications and versions to Vagon Streams directly from the command line.

**Vagon Streams CLI** is a developer tool to help you upload applications and new application versions to your Vagon Streams account from the command line.

### Installation

```
pip install vagon-cli
```

<figure><img src="/files/GlTSHXlTrgXV4Ye6Bdii" alt=""><figcaption></figcaption></figure>


# Unity Verified Plugin

Being a Verified Unity Solution ensures top-tier quality and seamless integration. With Vagon Streams, you can start streaming your Unity projects in minutes.

First, visit the [Vagon Streams page on Unity Asset Store](https://assetstore.unity.com/packages/add-ons/vagon-streams-application-streaming-248734) page and add the plugin to your My Assets list.

<figure><img src="/files/wVPBTXzo9h5b2GB6Vkqs" alt=""><figcaption></figcaption></figure>

Then, navigate the Plugin UI and authenticate your account inside the plugin.

When your project is ready just click on the Build & Create Application button from the plugin UI and wait until the process is completed. When the process is done, the uploaded application will be visible on your Vagon Streams dashboard.

Just follow [How to Start Streaming](/streams/guides/how-to-start-streaming#how-to-create-streams-link-to-stream-apps) for the next steps to create a Stream link.

<figure><img src="/files/T0Tr45CzkVbanoLFIkwb" alt=""><figcaption></figcaption></figure>


# Vagon Teams

**Vagon Teams** allows team managers, company owners, and administrators to set up high-performance virtual machines (Vagon Computers) with ease, enabling team members to access the computing power they need from any device, without the need for physical hardware by creating isolated and secure virtual work environments.

## How Vagon Teams Works

### **Team Administrators**

With just a few clicks, team administrators can create and configure virtual machines in seconds. The centralized dashboard allows admins to manage permissions, assign access, and control computer ownership seamlessly. Administrators can monitor application usage, manage team budgets, and ensure each team member has the resources they need.

<figure><img src="/files/Gd5l1Pj8ruRrMN2nsDqv" alt=""><figcaption><p>Team Admin Dashboard</p></figcaption></figure>

### **Team Members**

Team members can access their Vagon Computers from any device with a browser, giving them the flexibility to work from anywhere. Each team member has a personal dashboard where they can access their assigned Vagon Computer and use it according to the defined computer plan.

<figure><img src="/files/FidOHw2ajbdR60Vn3lQL" alt=""><figcaption><p>Team Member Dashboard</p></figcaption></figure>

## Key Features of Vagon Teams

* **Effortless Team Management**: Quickly invite team members, create virtual computers, and assign resources with ease. Switch computers among members and oversee all activities from a single, organized dashboard.
* **Secure, Isolated Work Environments**: Each virtual machine is securely isolated, providing a protected environment for team members to work without compromising data privacy.
* **Shared File Management**: Enable seamless collaboration with a personal folder and a shared team folder for each Vagon Computer, making it easy to transfer files and keep data synchronized.
* **Customizable Computer Plans**: Define monthly usage, set available performance options, and configure computer specifications to match your team’s needs. Add extra usage if required and manage the team budget effectively.
* **Application Usage Monitoring**: Track application usage and active durations within Vagon Computers in real time to optimize productivity and monitor resources. Admins can analyze application usage details directly from the dashboard.
* **Flexible Computer Templates**: Create reusable machine templates from our application library or your previous sessions. Assign templates to team computers to ensure every member has the right tools at their disposal.
* **Advanced Permission Control**: Customize permissions to maintain team and project privacy. Limit public internet access, restrict file and clipboard permissions, capture instant screenshots, and execute remote scripts within virtual machines.

## Why Choose Vagon Teams?

1. **Efficient Remote Work**: Empower team members to work from anywhere with high-performance virtual desktops accessible from any device.
2. **Centralized Control**: Admins have complete control over resources, permissions, and usage tracking, simplifying team management and enhancing security.
3. **Enhanced Collaboration**: Shared file management, usage monitoring, and secure, isolated environments make collaboration easy and safe.
4. **Scalable and Adaptable**: Vagon Teams grows with your organization, adapting to new members and project demands without the need for physical hardware upgrades.


# How to Use Vagon Teams

Vagon Teams allows you to invite Team Members, create & configure Team Computers with a few clicks, and manage permissions for further security.

You can manage your Team both from the Team Console and via Vagon Teams APIs.

### #1 Invite Team Members

After creating a Vagon Teams account, the first step is inviting team members. Team Administrators can invite an unlimited number of Team Members to their team for FREE, and they can assign computers to them while the invitation is pending.

Team Members are required to accept the invitation to use the assigned Team Computers, otherwise, they won't be able to access the Team Computers. Team admins can remove the team members from their team at any time.

<figure><img src="/files/89nEYgd3HfQBQFxsKVFr" alt=""><figcaption><p>Invite Team Members</p></figcaption></figure>

### #2 Create Computers with Computer Plans

Team Administrators can create Computers for their Team Members. While creating Team Computers, custom Computer Plans can be created and used to limit the total usage hours of team members, disk and personal file storage sizes, and performance selections.

<figure><img src="/files/a0kZfQyf8ssLnQTPhBtJ" alt=""><figcaption><p>Create Computers</p></figcaption></figure>

### #3 Assign Computers to Members

After creating Computers and inviting Team Members, Team Administrators can assign Computers to Team Members, and switch the ownership of the Computers anytime they want.

They have the option of keeping the files inside Computers while switching ownership or resetting the existing computer data.

The assigned Computer will be accessible to the Team Member on their personal dashboard.

<figure><img src="/files/MDOuxTBp2QikoJ6ZU2ie" alt=""><figcaption></figcaption></figure>

### #4 Set Computer Templates with Preinstalled Apps

Computer Templates allow Team Administrators to set ready-to-use Computers with preinstalled apps. Team Administrators can create Templates by using the previous Team Sessions, or selecting applications from the application library.

<figure><img src="/files/hjCI5Po9hdPYTZIHRIca" alt=""><figcaption></figcaption></figure>

### #5 - Manage Computer Permissions

In the last step, manage the Team Computer permissions, limit the functionalities inside Team Computers for further security measures with a few clicks from your dashboard, and access Team Computers remotely. Team admins can limit public internet access, restrict file and clipboard permissions, capture instant screenshots, and execute remote scripts within the Team Computers.

<figure><img src="/files/XuRIf5rjWkvtp1k8LAaY" alt=""><figcaption></figcaption></figure>


# Team Members

Team Administrators can invite unlimited numbers of Team Members to their teams, and they can cancel their access to the Team or remove them from the Team anytime they want.

<figure><img src="/files/yXqqtfhwEfdRlY9F48Lp" alt=""><figcaption></figcaption></figure>

When the Team Administrator sends invitations to new Team Members, the invited Members must accept the invitations to join the Team and access their assigned Team Computers.

After inviting Team Members, the next step is to create [Team Computers](/teams/basics/team-computers) for them.


# Team Computers

Team Computers are isolated & secure virtual machines that can be used in Teams.

Team Administrators can create as many Computers as they want, and Team Members can use their Team Computers according to the assigned Computer Plan limits and configurations.

Each Vagon Computer is bundled with a Computer Plan, which contains disk & personal file storage sizes, monthly usage by minutes, and available performance options for the Computer.

In case all the usage included inside Computer Plans is consumed, Team Administrators can assign additional usage credits to Computers anytime.

Computers are interchangeable among Team Members, and Team Administrators can change the Computer ownership.

Administrators can create and assign Team Computers to themselves to become a member of their Team, or use Personal Computers independently while managing their team as Team Administrators.

<figure><img src="/files/EEI95prpSYNZrnkhrOw0" alt=""><figcaption></figcaption></figure>


# Access to Team Computers

## Team Member Access to Computers

When a Team Computer is assigned to a Team Member, they can access their Computer from their dashboard by logging into their own Vagon account.

Team Members can use the available performance options and the assigned usages in the Computer Plan in minutes which are defined by the Team Administrator.

If there are multiple performance options available for the selected Computer Plan, usage consumptions will be calculated according to the minute pricing of the used performance option in the selected computer region as listed [here](https://vagon.io/region-prices), and deducted from the total usage according to the selected performance.

<figure><img src="/files/FidOHw2ajbdR60Vn3lQL" alt=""><figcaption></figcaption></figure>

## Administrator Access to Computers

Team Administrators can access all Team Computers and related functionalities from the Team Console. The usage of the Computers will be deducted according to the selected performance option for the Computer.

<figure><img src="/files/EEI95prpSYNZrnkhrOw0" alt=""><figcaption></figcaption></figure>


# Team Subscription & Payments

Team Subscription starts when the first Team Computer is created. This date is set for the subscription renewal date for the future months, and the total amount is calculated according to the total Usage Plan prices of created Team Computers.

Team Administrators can leverage different Usage Plans for different Team Computers, and the total subscription payment amount is calculated as the sum of all used Usage Plans for active Team Computers.

Team Computers can be set for deletion by the Team Administrator for the end of each subscription period, and the system automatically deletes the selected Team Computers on the subscription renewal date and calculates the new subscription payment amount according to the Usage Plan selection of the remaining Team Computers.

Team Administrators can turn off the Teams Subscription renewal from the Settings page in Team Console, and the system deletes all Team Computers with all data & files in the computers & files directory in case of subscription termination.

If the Team Administrator creates multiple Computers on different dates, the system charges the full Usage Plan price for the first month and makes the selected usage amount available for the Team Member. For the next subscription period, the system recalculates the discounted plan prices for the computers created after the subscription start date according to the difference in days.


# Teams Features

Vagon Teams provides various features to make cloud remote desktop management process easier and secure for Team Administrators. With Vagon Teams, companies can leverage cloud technologies to provide secure and easy to use high performance remote workstations for their company tasks.

**Monthly Computer Plans** - predefined computer budgets including usage and computer configurations.

**Individual Vagon Files Folders -** independent & individual file storages for members, attached to each Team Computer separately.

**Teams Shared Files Folder** - independent & collaborative file storage, accessible by all Team Members for shared files.

**Computer Templates** - Ready to use computer images with preinstalled apps, and configurations.

**Computer Permissions** - Limitations and administrative tools for Team Administrators for full management capabilities on Team Computers.

**Session Stats & Application Usage Monitoring -** Enhanced usage details for Team Computers, and real-time application usage logs from Team Computers.

**Teams API -** Full functional API endpoints for custom requirements of teams and companies.


# Monthly Computer Plans

**Monthly Computer Plans** are designed for Team Administrators and Finance departments to make it easier to estimate usages and forecast monthly budgets while utilizing cloud remote desktops with Vagon Teams.

Unfortunately, because of the nature of the cloud and the current cost structure of public cloud providers, it's not possible to estimate the budget for the resources running on cloud.

Vagon Teams allows you to set custom Monthly Computer Plans for Team Computers, and know what you will pay at the end of each subscription period.

Team Administrators can either create custom plans according to their requirements or use predefined plans while creating Team Computers.

Computer Plans are usage-included monthly subscription plans for Team Computers. Usages are interchangeable among the available performance options according to the [region-based pricing](https://vagon.io/region-prices) of each performance option, and all usages reset at the beginning of each subscription period.

Monthly Computer Plans consist of four elements,

* **Disk Storage**,
* **Files Storage**,
* **Available Performances**,
* and **Total Usage Hours**.

{% hint style="info" %}
In case a Team Member needs additional usage, Administrators can always add **Extra Usage** from the Team Console anytime.
{% endhint %}

## How to Create Custom Computer Plans?

### #1 Disk Storage Selection

Disk Storage is the C: drive of the Team Computers. The base Disk Storage starts from 75GB, and Team Administrators can increase the Disk Storage size up to 525GB.

<figure><img src="/files/1waxqb6ucMLKz1MxLvu0" alt=""><figcaption></figcaption></figure>

### #2 Vagon Files Storage Selection

Vagon Files Storage is independent storage that is attached to each Team Computer to optimize the file transfer process between the Team Computers and the local computers. Files Storage is 25GB by default, and it can be increased up to 1TB for Team Computers.

Files Storage is assigned to each Team Computer separately, and, besides the Team Administrator, only the Team Member who has access to the related computer can access those files.

{% hint style="info" %}
Team subscription comes with an integrated Shared Team Folder which is accessible for all computer-assigned Team Members from their dashboard and inside their Team Computers in addition to individual Vagon Files Storages for each computer.
{% endhint %}

<figure><img src="/files/kqolPznLmVxOWvHbPT0U" alt=""><figcaption></figcaption></figure>

### #3 Available Performance Selection

Team Members can only use the available performance types selected in the Computer Plan, and switch between the available performance options according to their needs while the data & files inside the computer are preserved.

<figure><img src="/files/vIQln3VeweRIN04N6JmW" alt=""><figcaption></figcaption></figure>

### #4 Monthly Usage Amount Selection

Administrators can set usage amounts for Plans in hours to define usage amounts for Team Members. Performance (usage) cost of the Computer Plan is calculated by multiplying the price of the lowest tier performance option in the Plan, and the selected usage amount.

This usage can be used with available performance options selected in the plan, and the remaining usage is calculated according to the selected performance pricing.

Administrators can also add extra usages on top of the remaining usage for each Team Computer, or they can prefer managing only with extra usage without defining predefined usage in the Computer Plan.

<figure><img src="/files/pm1srOPhWrI6eti0E6TU" alt=""><figcaption></figcaption></figure>

### #5 Saving Plans for Future Use

After completing the Computer Plan configurations, Team Administrators can name & save the Plan for future use.

<figure><img src="/files/9akF8hbpvFOeLqLxEkHw" alt=""><figcaption></figcaption></figure>

## Computer Plan Details

All default and custom plans will be listed in the Plans tab, and all details can be accessible from the same page.

<figure><img src="/files/6TCsrcfdJBHskF0fwkvY" alt=""><figcaption></figcaption></figure>


# Teams File Systems

Every Vagon Team Computer comes with an **Individual Files Folder** to make it easier to transfer and sync files between local devices and Vagon computers.

In addition to the **Individual Files Folders**, each Team has a collaborative **Teams Shared Folder** in which all the files are accessible to all Team Members.

<figure><img src="/files/r6qtLj0fULz0UQ6xzuWp" alt=""><figcaption></figcaption></figure>

Team Administrator can access, edit, and manage both Individual Files Folders and the Shared Team Folder.

All transferred files and folders in the **Individual Files Folder** and the **Shared Team Folder** will be accessible from the Vagon desktop and Member dashboards simultaneously.


# Computer Templates

## Preinstall Apps from Application Library

Team Administrators can create Templates from an up-to-date Application Library in seconds, and use those templates as the starting base of Team Computers to eliminate the manual installation processes, and to start working right away.

<figure><img src="/files/G2IXCrIR9fRxHnw9FZEJ" alt=""><figcaption></figcaption></figure>

## Using an Existing Team Computer as Template

In addition to the Application Library, Team Administrators can use an existing computer session as the base machine template as well. After completing all the configurations & installations in a Team Computer, a Template can be generated from its session, and be used as a starting point for other Team Computers.

<figure><img src="/files/hjCI5Po9hdPYTZIHRIca" alt=""><figcaption></figcaption></figure>


# Computer Permissions

Team Administrators can easily manage Team Computer permissions to maintain security while working with various Members at the same time.

<figure><img src="/files/7A7BJDgA21yoX4riWhui" alt=""><figcaption></figcaption></figure>

## Enable / Disable Public Internet Access Inside Computer

Team Administrators can disable internet access inside Team Computers. When disabled, Team Members cannot access the public internet or browse the web. When enabled, they can browse without restrictions. This setting is enabled by default.

## Manage Application Usage Monitoring

Application usage inside the Vagon computer can be logged and monitored when this setting is enabled. Team Members are notified on the connection screen when this permission is active. This setting is disabled by default.

## Manage Upload & Download Files Permission

Disabling this permission prevents users from uploading and downloading files directly to and from their Vagon desktops. This setting is enabled by default.

This permission does not affect file operations through the Vagon Files system.

## Manage Clipboard Access

Disabling this permission restricts clipboard copy actions inside Vagon computers. When disabled, users cannot copy text from Vagon to their local machine. This setting is enabled by default.

## Input Recording

Administrators can enable mouse and keyboard input recording. When Input Recording is enabled, the system logs mouse events (click, movement, and scroll) and keyboard key press events in a log file.

## Session Recording

Administrators can enable Session Recording. When enabled, the selected computer desktop is recorded, and recording files are saved in parts.

## Folder Auto Snapshots

When enabled, the system automatically creates an `/Outputs` folder on the desktop and periodically creates timestamped snapshot folders in the Vagon Files folder for its contents. In each timestamped snapshot folder, a `Files.txt` file lists unchanged file names, while files that differ from the previous snapshot are saved individually.

## Get Instant Screenshots from Computer

Team Administrators can capture instant screenshots from an active session. This action is available only for running computers.

<figure><img src="/files/ZEQX4uGa38wzx3jdZc6s" alt=""><figcaption></figcaption></figure>

## Run Remote Powershell Scripts Inside the Computer

Team Administrators can run remote PowerShell scripts on the selected computer and receive the output. This action is available only for running computers.

<figure><img src="/files/Dyyg6GxznizrK9bFLcNA" alt=""><figcaption></figcaption></figure>


# Session Stats

Team Administrators can get real-time insights on their Team sessions from the **Monitoring** > **Session Stats** tab. They can filter the data by member, performance, region, and date.

<figure><img src="/files/Hy4kVnRNyfbIH4wJu8PP" alt=""><figcaption></figcaption></figure>


# Application Usage Monitoring

Application Usage insight is collected from a Team Computer if the Application Usage Monitoring permission for the Team Computer is enabled from the **Permissions** tab, and the whole data will be accessible in the **Monitoring** > **Application Usage** tab for Team Administrators.

Application Usage data is also accessible at the Computer and Session detail levels for further analysis.

<figure><img src="/files/BHjj5eu60pHdAoXVdJkk" alt=""><figcaption></figcaption></figure>

## Application Usage Stats

The system logs the application usage inside Team Computers for the **Application Usage Monitoring** enabled sessions and lists the monitored data in real-time for Team Administrators.

## Away-From-Keyboard (AFK) Duration

The duration of session(s) when the user activity is not detected. The system will log Team Member activity inside Team Computers and log the duration when the Team Member is not active during the session.

## Browser Tab Title Logging

The system logs the browser tab titles inside Team Computers and logs the usages for each opened browser tab.


# Folder Auto Snapshot

File & Folder Snapshots feature allows Team Computers to automatically create periodic, timestamped snapshots of the `/Outputs` folder on the desktop. Snapshots are taken every **30 minutes**, preserving a recoverable history of your work while keeping storage usage efficient.

### How It Works

When this feature is enabled, the system creates an `/Outputs` folder on the desktop of the team computer. For files in this folder, the system creates a timestamped folder inside `Vagon Files/Outputs/` for each snapshot cycle and records the folder state.

* **Full files** are saved when a file is new or has been modified since the last snapshot (detected via modified date).
* **File references** are recorded in `Files.txt` for files that have not changed, avoiding redundant copies of unchanged data.

A `Files.txt` file is included in **every** snapshot folder, listing all file names present in `Desktop/Outputs` at the time of the snapshot — regardless of whether each file was modified or not. This gives you a complete inventory of your working directory at every point in time.

If `Desktop/Outputs` is empty, `Files.txt` will contain the following line:

`[INFO] No files to backup - source folder is empty`

> Snapshots are created separately for each session. The system checks the initial folder state when the computer starts, then creates snapshot folders by comparing against the previous snapshot state of the `/Outputs` folder. Because of this, if a file already exists in `/Outputs` from a previous session, it is treated as a new file in the next session's snapshots.

#### Snapshot Cycle

```
Desktop/Outputs/          →   Vagon Files/Outputs/
                                ├── t/           (session start)
                                ├── t+30/        (30 min later)
                                ├── t+60/        (60 min later)
                                └── ...
```

### Example

Assume your `Desktop/Outputs` folder contains the following files at the start of a session:

| File                    | Description             | Modified Since Previous Snapshot |
| ----------------------- | ----------------------- | -------------------------------- |
| `quarterly_report.docx` | Word Document           | `true`                           |
| `financials.pptx`       | Financials Presentation | `false`                          |
| `sales_data.csv`        | Data Export             | `false`                          |

#### **Snapshot at `t` (session start)**

All files are new to this session, so all are copied in full:

```
Vagon Files/Outputs/t/
├── quarterly_report.docx
├── financials.pptx
├── sales_data.csv
└── Files.txt         ← lists quarterly_report.docx, financials.pptx, sales_data.csv
```

#### **Snapshot at `t+30` (user saved changes to `quarterly_report.docx`)**

Only the modified file is copied. The unchanged files are referenced in `Files.txt`:

```
Vagon Files/Outputs/t+30/
├── quarterly_report.docx  ← updated version
└── Files.txt              ← lists quarterly_report.docx, financials.pptx, sales_data.csv
```

#### **Snapshot at `t+60` (no files saved between snapshots)**

No modified files, so only the inventory file is created:

```
Vagon Files/Outputs/t+60/
└── Files.txt              ← lists quarterly_report.docx, financials.pptx, sales_data.csv
```

### Storage Efficiency

This incremental approach is intentional. Copying every file in full at every cycle would rapidly consume available disk space — especially with large project files. By storing only changed files and referencing unchanged ones in `Files.txt`, the system keeps your snapshot history complete without unnecessary duplication.

This feature is available upon request. Please contact the Vagon team to enable it.


# Input Recording

The Input Recording feature allows Team Administrators to collect mouse and keyboard events inside Vagon computers. When enabled, the system logs all actions taken inside Vagon computers and writes them to an input file in real time with timestamps.

This allows actions performed inside Vagon computers to be replayed after a session and used for future evaluation.

Recorded inputs are written to a file. If the Session Recordings & Logs folder is not enabled for the account, this file is created under the session's Vagon Files folder.

If the Session Recordings & Logs folder is enabled for the team, the system automatically transfers recording files to this folder to free up the computer's Vagon Files folder.

## Session Recordings & Logs Folder

This folder is enabled upon request and is designed to store input and session recording files. All logs are stored under the related computer and session folder within this location.


# Session Recording

The Session Recording feature allows Team Administrators to record Vagon computer sessions. When enabled, the selected computer desktop is recorded, and recording files are saved in parts.

These recordings can be reviewed after a session for auditing, quality checks, and operational tracking.

Recording files are created separately for each session in `.mp4` format and stored under the computer's Vagon Files folder.

In the Input Recording file, the system automatically adds `SYNC ON` and `SYNC OFF` events to support input and recording synchronization.

If the Session Recordings & Logs folder is enabled for the team, the system automatically transfers recording files to this folder to free up the computer's Vagon Files folder.

## Session Recordings & Logs Folder

This folder is enabled upon request and is designed to store both input and session recording files. All files are organized under the related computer and session folder within this location.


# Microsoft Entra (Azure AD) Login

Microsoft Entra (Azure AD) Single Sign-On lets your team members sign in to Vagon with your organization's Microsoft identity. Only Team **Owners** and **Admins** can configure it.

Because Vagon is not listed in the Microsoft Entra app gallery, you register it in your tenant as a **custom (non-gallery)** application, then connect it to Vagon from your Team Settings.

**Prerequisites**

* A Vagon Teams organization, with **Owner** or **Admin** access.
* Access to the [Microsoft Entra admin center](https://portal.azure.com/) for your organization, with permission to register applications.

### Step 1 — Set the SSO login path in Vagon and copy the Callback URL

Start in Vagon to generate the values you'll need in Microsoft Entra.

1. Go to **Settings → Teams → Authentication** and click **Setup** under **Microsoft Azure AD Single Sign-On**.

<figure><img src="/files/120xggzSodOkfPTkzPtW" alt="Authentication settings with the Microsoft Azure AD Single Sign-On Setup button"><figcaption></figcaption></figure>

2. On the **Information** tab, enter an **SSO login path** (for example, `company-name`). This generates your **SSO login URL** — the address your team members use to sign in (e.g. `https://app.vagon.io/login/sso/company-name`).
3. Copy the **Callback URL** shown on this tab. You will add it to your Microsoft Entra application in the next step.

<figure><img src="/files/3WinecAeVZrK1DrMjVHm" alt="Information tab showing SSO login path, SSO login URL, and Callback URL"><figcaption></figcaption></figure>

{% hint style="info" %}
The **SSO login path** must be 3–64 characters using only lowercase letters, numbers, and hyphens (for example, `my-company`). It must be unique, and the word `callback` is reserved and cannot be used.
{% endhint %}

{% hint style="info" %}
Always copy the **Callback URL** from your own Vagon dashboard rather than typing it by hand — it must match exactly when you add it to Microsoft Entra.
{% endhint %}

### Step 2 — Register Vagon as a custom application in Microsoft Entra

Keep the Vagon overlay open (you'll return to it in Step 3) and open the Microsoft Entra admin center in another tab.

1. Go to <https://portal.azure.com/> and open **Manage Microsoft Entra ID**.
2. Open **Enterprise applications**, click **New application**, then **Create your own application**. Choose **Integrate any other application you don't find in the gallery (Non-gallery)**, give it a name (for example, `Vagon`), and click **Create**.

<figure><img src="/files/N6JNexQwh3c2lBBA7mrf" alt="Microsoft Entra Enterprise applications list with the New application button"><figcaption></figcaption></figure>

<figure><img src="/files/bAdLugwyoTT7BCOTmVYf" alt="Create your own application panel with the Non-gallery option selected"><figcaption></figcaption></figure>

3. Go back to **Home**, open **App registrations** from the sidebar, and select the application you just created.

<figure><img src="/files/RIH2bwBIWrBqmTi0TLTZ" alt="App registrations list"><figcaption></figcaption></figure>

4. On the application's **Overview**, copy the **Application (client) ID** and the **Directory (tenant) ID**. You'll paste these into Vagon in Step 3.

<figure><img src="/files/sFCJa8sQ6u7gtQRBn9DH" alt="App registration Essentials showing Application (client) ID and Directory (tenant) ID"><figcaption></figcaption></figure>

5. Open **Client credentials** (Certificates & secrets) and create a new **client secret**. Copy its **Value** right away.

{% hint style="info" %}
A client secret's value is shown **only once**, right after you create it. Copy it immediately — if you lose it, you'll need to create a new one.
{% endhint %}

6. Open **Redirect URIs**, click **Add Redirect URI**, choose platform type **Web**, and paste the **Callback URL** you copied from Vagon in Step 1.

<figure><img src="/files/5qcJubqXyIIktBYj6J7e" alt="Redirect URI configuration with a Web platform entry for the Vagon callback URL"><figcaption></figcaption></figure>

### Step 3 — Enter the configuration in Vagon

Return to the **Azure AD SSO Configuration** overlay in Vagon and open the **Configuration** tab.

1. Fill in the following fields using the values from your Microsoft Entra application:

| Vagon field            | Where to find it in Microsoft Entra                       |
| ---------------------- | --------------------------------------------------------- |
| **Azure AD Tenant ID** | App registration → Overview → **Directory (tenant) ID**   |
| **Client ID**          | App registration → Overview → **Application (client) ID** |
| **Client secret**      | Certificates & secrets → client secret **Value**          |

2. Keep **SSO enabled** checked.
3. Set **Add new users to organization automatically** based on your preference (see [Managing SSO](#managing-sso) below).
4. Click **Save SSO settings**.

<figure><img src="/files/YHpS2aNJHYPM7VvR1NaU" alt="Configuration tab with Azure AD Tenant ID, Client ID, Client secret, and the Save SSO settings button"><figcaption></figcaption></figure>

{% hint style="info" %}
The **Client secret** field shows *Leave blank to keep existing secret*. When you later rotate the secret in Microsoft Entra, paste the new value here; leaving it blank keeps the secret you already saved.
{% endhint %}

#### How your team signs in

Once SSO is saved and enabled, share your **SSO login URL** (`https://app.vagon.io/login/sso/<your-path>`) with your team. Members open that URL and click **Sign in with Microsoft**.

* **New users** (no existing Vagon account) are created automatically and must verify their email before they can access the team.
* **Existing Vagon users** who haven't linked SSO yet receive an email to confirm and link their account.
* **Already linked users** are signed in directly.

#### Managing SSO

* **Automatic enrollment** — when **Add new users to organization automatically** is checked, users allowed in your Microsoft Entra tenant can join your team automatically by signing in with the SSO login URL. Users who already have a personal Vagon subscription are not added automatically and must be invited explicitly.
* **Invite flow** — when Microsoft Entra is enabled, the user invite flow is automated. Team Admins can still invite users from outside your organization at any time.
* **Disabling SSO** — you can entirely disable Microsoft Entra login with the **Disable** button, or temporarily disable it by unchecking the **SSO enabled** checkbox.

#### Troubleshooting

{% hint style="info" %}

* **Sign-in fails with a redirect error** — make sure the **Redirect URI** in Microsoft Entra exactly matches the **Callback URL** shown in your Vagon dashboard. The Callback URL is environment-specific, so always copy it from your own dashboard.
* **SSO login path is rejected** — the path must be unique and follow the format rules (3–64 lowercase letters, numbers, and hyphens), and cannot be `callback`.
* **A user can't be linked** — a user who already belongs to a different organization cannot be auto-linked to your team via SSO.
  {% endhint %}


# SCIM User Provisioning

SCIM (System for Cross-domain Identity Management) lets your identity provider create and remove Vagon team members automatically. When someone joins the directory group you sync, Vagon invites them to your organization; when they leave it, their membership is removed and their computer is released — without an admin doing anything by hand.

Vagon supports **SCIM 2.0** so any compliant identity provider can connect to it. This guide walks through **Microsoft Entra ID (Azure AD)**, which is the most common setup.

Only Team **Owners** and **Admins** can configure SCIM.

* **Provisioning creates a pending invitation, not a membership.** The person becomes a member when they accept — normally the first time they sign in through SSO, or via the invitation email. Invitations are valid for three months.
* **No computer is ever assigned automatically.** Assigning a computer stays an explicit action by a team admin.
* **Deprovisioning is immediate.** The membership is removed, the computer is released, and the person's access tokens are revoked.

{% hint style="info" %}
**SCIM and SSO are independent.** SCIM authenticates with its own token and works with or without [Microsoft Entra (Azure AD) Login](/teams/features/microsoft-entra-sso) configured. They're commonly used together — with SSO enabled, invited people are enrolled automatically on first sign-in instead of having to click a link in an email.
{% endhint %}

**Prerequisites**

* A Vagon Teams organization, with **Owner** or **Admin** access.
* Access to the [Microsoft Entra admin center](https://portal.azure.com/) with permission to register applications.

***

## Step 1 — Set up SCIM in Vagon

1. Go to **Settings → Authentication** in your Vagon Team Console and find **Automatic User Provisioning – SCIM Integration**.
2. Click **Setup**.

<figure><img src="/files/N9L5vy9e3cLwspJM8tsQ" alt="Vagon Authentication settings with the Automatic User Provisioning - SCIM Integration section and its Setup button"><figcaption></figcaption></figure>

3. Give the token a name so you can tell it apart later — name it after the identity provider you're connecting, for example `Microsoft Entra ID`. Click **Generate**.

<figure><img src="/files/4TX6GL3TdAelx5SffZXJ" alt="Generate SCIM token dialog with the Token name field"><figcaption></figcaption></figure>

4. Vagon shows you two values. Copy **both** now — you'll paste them into Microsoft Entra in Step 3. Then click **Done**.
   * **Tenant URL** — the SCIM endpoint for your organization.
   * **Secret token** — the bearer token your identity provider authenticates with.

<figure><img src="/files/KOOORBqEjxOOuAtGf6Dn" alt="SCIM Integration dialog showing the Tenant URL and Secret token"><figcaption></figcaption></figure>

{% hint style="warning" %}
The **secret token is shown only once.** Vagon stores it hashed and cannot display it again. If you lose it, disable the integration and set it up again with a new token.
{% endhint %}

{% hint style="info" %}
Always copy the **Tenant URL** from your own dashboard rather than typing it by hand. Keep the path exactly as shown — it is case-sensitive, so `/scim/v2/Users` resolves and `/scim/v2/users` does not.
{% endhint %}

Your organization holds **one active SCIM token at a time**, and tokens are not scoped — every token for an organization can see and modify the same resources. This means you connect **one identity provider per organization**.

## Step 2 — Create the application in Microsoft Entra

Vagon is not in the Microsoft Entra app gallery, so you register it as a custom (non-gallery) application.

1. Open the [Microsoft Entra admin center](https://portal.azure.com/) and go to **Identity → Applications → Enterprise applications**.
2. Click **New application → Create your own application**, choose **"Integrate any other application you don't find in the gallery"**, give it a name (for example, `Vagon`), and click **Create**.
3. Open the application you just created from the **All applications** list.

<figure><img src="/files/2cRI9DbfE1rjpBUBidFD" alt="Microsoft Entra Enterprise applications list with the newly created application"><figcaption></figcaption></figure>

{% hint style="info" %}
If you already registered Vagon for [Microsoft Entra SSO](/teams/features/microsoft-entra-sso), you can reuse that same enterprise application here instead of creating a second one — just open it and continue from Step 3.
{% endhint %}

## Step 3 — Connect provisioning to Vagon

1. In the application's sidebar, open **Provisioning**.

<figure><img src="/files/EnQLXPvt3NwxqsY14YaL" alt="Enterprise application Overview page with Provisioning in the sidebar"><figcaption></figcaption></figure>

2. Click **New configuration** (or **Connect your application** on the Get started panel).

<figure><img src="/files/JcRdNBpE7HBrVmvXbtF6" alt="Get started with application provisioning panel"><figcaption></figcaption></figure>

3. Fill in the **Admin credentials**:

| Entra field                      | Value                                            |
| -------------------------------- | ------------------------------------------------ |
| **Select authentication method** | Bearer authentication                            |
| **Tenant URL**                   | The Tenant URL you copied from Vagon in Step 1   |
| **Secret token**                 | The Secret token you copied from Vagon in Step 1 |

4. Click **Test connection**. You should see *Connection test was successful*. Then click **Create**.

<figure><img src="/files/XFpVFf2L9nOgKdAtBEki" alt="New provisioning configuration with Bearer authentication, Tenant URL, Secret token, and the Test connection button"><figcaption></figcaption></figure>

<figure><img src="/files/DKAVfMDeinA8SGZJUZcN" alt="Confirmation that the provisioning configuration was created"><figcaption></figcaption></figure>

{% hint style="info" %}
Microsoft Entra offers a new and a legacy provisioning experience, and the screenshots here use the new one. On the legacy screens the same step is **Provisioning Mode: Automatic → Admin Credentials**; the fields and the values you paste are identical.
{% endhint %}

## Step 4 — Choose who gets provisioned

Vagon only creates the users Entra sends it, so scope the sync deliberately.

1. Under the provisioning configuration, open **Manage → Provisioning settings** and set **Scope** to **Sync only assigned users and groups**.
2. Go back to the application and open **Users and groups**.

<figure><img src="/files/FxQxB8KYAMfIxQufdfUj" alt="Users and groups page with no assignments yet"><figcaption></figcaption></figure>

3. Click **Add user/group**, select the people (or groups) who should have Vagon access, and click **Assign**.

<figure><img src="/files/ehrJevbP5FDDl0dmmK8v" alt="Add Assignment panel with users selected"><figcaption></figcaption></figure>

{% hint style="info" %}
Keep the matching attribute as **`userName`**. Vagon supports filtering on `userName` and `externalId` only, so matching on any other attribute will fail.
{% endhint %}

## Step 5 — Provision admins automatically (optional)

By default everyone provisioned through SCIM joins as a **member**. If you want your directory to decide who is an organization **admin**, map Vagon's `isAdmin` attribute.

1. Open **Manage → Attribute mapping**, select the **Provision Microsoft Entra ID Users** mapping, and click **Edit attribute list** (shown as *customappsso*).
2. At the bottom of the list, click **+ Add new attribute** and add:
   * **Name** — `urn:vagon:params:scim:schemas:extension:2.0:User:isAdmin`
   * **Type** — `Boolean`
3. Click **Save**.
4. Back in **Attribute mapping**, add a mapping that assigns a value to `isAdmin` — for example from an app role or a directory attribute.

{% hint style="info" %}
Vagon accepts the attribute under its full URN or as a plain `isAdmin`, which is what Entra sends if you leave the URN off the attribute name. Either works.
{% endhint %}

**How Vagon interprets `isAdmin`:**

* **Not sent at all means unchanged.** A directory that doesn't map `isAdmin` will never demote your existing admins. Only an explicit `false` demotes someone to member.
* **The organization owner is never affected.** `isAdmin` cannot grant or remove ownership — admin is the highest role SCIM can assign.
* **A demotion revokes that person's access tokens**, so admin privileges stop immediately rather than lasting until their session expires. Promotions don't revoke anything.
* If the person hasn't accepted their invitation yet, the role is recorded and applied the moment they do.

{% hint style="warning" %}
**Set the source attribute before the user enters scope.** Entra omits empty source attributes from the payload entirely, so a user created in Vagon before `isAdmin` has a value arrives as a member — the role then follows on the next sync cycle once the value changes. The same applies if you add the mapping after users are already syncing. Use **Restart provisioning** to force a full re-sync, or **Provision on demand** to push one user immediately.
{% endhint %}

## Step 6 — Test, then turn provisioning on

Before switching the sync on for everyone, push a single user through it.

1. Open **Provision on demand**, pick one assigned user, and run it.
2. All four steps — *Import user*, *Determine if user is in scope*, *Match user between source and target system*, *Perform action* — should report **Success**. Open **View details** on **Perform action** to see exactly which attributes were sent.
3. Check that the person received a Vagon invitation, then set **Provisioning Status** to **On** and save.

Microsoft Entra runs an initial full sync immediately, then an incremental cycle roughly **every 40 minutes**. Changes you make in your directory won't appear in Vagon instantly — use **Provision on demand** when you need one user pushed through straight away.

***

## Managing the integration

Once SCIM is set up, the **Automatic User Provisioning – SCIM Integration** row in your Authentication settings offers **Configure** and **Disable** instead of **Setup**. Configure shows the active token, its name, and when it was last used.

* **Rotating a token** — disable the integration, set it up again to generate a new token, and paste the new value into Microsoft Entra. Provisioning pauses in between, which in practice is one sync cycle.
* **Disabling the integration** — your identity provider can no longer provision or remove users until you set it up again with a new token. **Existing members are not affected** — nobody loses access, and nobody is deprovisioned, because you turned SCIM off.

<figure><img src="/files/SeYjLVA3glRj4CsJNahr" alt="Disable SCIM Integration confirmation dialog in Vagon settings"><figcaption></figcaption></figure>

{% hint style="info" %}
Disabling SCIM stops the sync but leaves your team exactly as it is. If you need to remove someone's access, do it in Vagon or in your directory — turning the integration off won't do it for you.
{% endhint %}

If you need help, reach out to us at <support@vagon.io>.


# Audio/Microphone Issues

All Vagon computers are preconfigured to support audio and microphone devices for both input and output.

However, configurations can become outdated over time, and usage-related changes may also lead to misconfigurations that affect audio and microphone support.

If you are experiencing audio or microphone issues inside your Vagon computer, follow the steps below in order.

## 1. Enable Audio and Microphone

Open the Vagon dock menu — the Vagon icon at the top of your Vagon desktop — and make sure the audio and microphone toggles are enabled.

<figure><img src="/files/vzYu5HGzIvvlUfN5pXVU" alt=""><figcaption></figcaption></figure>

## 2. Check the Selected Audio and Microphone Devices

In the dock menu, check the selected Audio and Microphone devices, and make sure the options starting with "Default" are selected.

> Some external microphone & audio devices may be listed in different formats. If you are using additional external devices, try different combinations of the microphone and audio input options.

<figure><img src="/files/TwISF7SL9y8jZDVhU7fF" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/PqBnT545qsq8S0AyVfYs" alt=""><figcaption></figcaption></figure>

If you can see the correct options here, move on to the next step; otherwise, continue with the steps below.

## 3. Check Browser Permissions

When connecting to your Vagon computer from a browser, you must grant audio and microphone permissions to use these devices.

When connecting through the Vagon Desktop Application, you must also grant microphone and audio permissions in your local device settings so that Vagon can access them.

If these permissions are not granted, the system cannot enable audio and microphone support.

## 4. Ensure that Voicemeeter Is Running

If audio and microphone are enabled and permissions are granted, but you still cannot use your microphone or hear sound, make sure Voicemeeter is running inside your Vagon computer with the correct configuration.

<figure><img src="/files/a5dS0dfxFwF53XDczWbe" alt=""><figcaption></figcaption></figure>

## 5. Verify Input and Output Device Selection

If all the steps above are correct but the issue persists, go to the **System > Sound** settings page to check the Windows device selections.

* **Output (Playback) device:** Speakers (Scream (WDM))
* **Input (Recording) device:** Voicemeeter Out B1

To set a device as default, select it from the list and click **Set Default**.

<figure><img src="/files/WlTbZ9tc9V9iARDRVMMw" alt=""><figcaption></figcaption></figure>

## 6. Check Application Level Configurations

By default, applications use the System Default audio and microphone configuration. However, some applications (e.g. Zoom, Slack) can override this and select different devices on their own.

When this happens, you will still hear system sounds and audio from websites, but you cannot hear the application's audio, or your voice is not delivered through it.

To configure application-specific Audio & Microphone selections, go to the application's settings, open its Audio and/or Microphone preferences, and make sure that **Scream (WDM) is selected as the Audio device** and **Voicemeeter Out B1 is selected as the Microphone device.**

<figure><img src="/files/dyhWFqKVxaXESqZLZzk3" alt=""><figcaption></figcaption></figure>

## 7. Advanced Configurations

Your issue should have been resolved by applying the configurations above. However, if you are still facing problems, the final thing to check is the audio and microphone configuration inside your Vagon computer.

### 7.1. Open the Sound Settings Window

Open the Control Panel and go to **Sound**. A window with the **Playback**, **Recording**, **Sounds**, and **Communications** tabs will appear.

The **Playback** tab must contain the **Speakers** — Scream (WDM) *(Default Device)* item, and this must be the selected device, regardless of any others in the list.

<figure><img src="/files/fxui8EAxt4xtCDfkApIb" alt=""><figcaption></figcaption></figure>

### 7.2. Check the Format of Playback Device

| Device                      | Default Format                    | Exclusive Mode         |
| --------------------------- | --------------------------------- | ---------------------- |
| **Speakers** (Scream (WDM)) | 32 bit, 48000 Hz (Studio Quality) | Both boxes **checked** |

<figure><img src="/files/1yA2FVHk4UALc3Poe2V3" alt=""><figcaption></figcaption></figure>

### 7.3. Check the Format of Recording Device

After checking the Playback devices, switch to the **Recording** tab. **Voicemeeter Out B1** — VB-Audio Voicemeeter VAIO *(Default Device)* must be listed there, and this must be the selected device, regardless of any others in the list.

Apply the same process (Properties → Advanced) to this device and match the values below:

| Device                                             | Default Format                               | Exclusive Mode         |
| -------------------------------------------------- | -------------------------------------------- | ---------------------- |
| **Voicemeeter Out B1** (VB-Audio Voicemeeter VAIO) | 2 channel, 24 bit, 48000 Hz (Studio Quality) | Both boxes **checked** |

<figure><img src="/files/ec4akbBEbuI5ovzFVtpT" alt=""><figcaption></figcaption></figure>

### 7.4. Verify Voicemeeter Settings

After checking the Windows audio device formats, open **Voicemeeter** and verify that its settings are correct. (Voicemeeter must be running; see **Step 4**.)

In the Voicemeeter interface, look at the **HARDWARE OUT** section in the top-right corner. Make sure the **A1** output is routed to the correct device:

* **A1** → **CABLE Input (VB-Audio Virtual Cable)**

Also check that the **Voicemeeter Input** device is active in the **VIRTUAL INPUT** section.

<figure><img src="/files/rTRbupE81vESVdssetSD" alt=""><figcaption></figcaption></figure>

### 7.5. Select the Correct Output Device in Voicemeeter

If the settings in Voicemeeter do not match the ones shown above, you need to select the correct device manually:

1. Click the **A1** button in the top-right corner.
2. In the **Select A1 Output Device** window that opens, make sure **WDM (WASAPI)** mode is selected on the left.
3. Select **CABLE Input — VB-Audio Virtual Cable** from the list (it should appear as **44100 Hz, 2 Ch**).

Once the device is selected, Voicemeeter will route the audio correctly, and your microphone/speaker issue should be resolved.

<figure><img src="/files/bLKozzau3V7jOY0N9A2i" alt=""><figcaption></figcaption></figure>


# Connection Performance

Vagon Streaming Protocol is designed to adapt dynamically and support connections from anywhere in the world, including up to 4K at 60 FPS.

However, due to network and infrastructure limitations, connection quality can still be affected. If you are experiencing streaming or responsiveness issues, check the points below.

## 1. Unstable Network Connection

An unstable internet connection is the most common reason for lag, stutter, frame drops, or temporary disconnections.

What to check:

* Use a stable Wi-Fi signal or a wired Ethernet connection when possible.
* Avoid heavy network usage in parallel (downloads, uploads, cloud sync, video calls, or streaming).

## 2. Out of Date Browser Version

Using an outdated browser can affect WebRTC-based streaming performance and hardware acceleration. We recommend using [Vagon Desktop Application](https://vagon.io/download) to get the best streaming experience.

What to check:

* Update your browser to the latest stable version.
* Use a modern supported browser such as Google Chrome or Microsoft Edge.
* Close unnecessary tabs or extensions that may consume CPU/GPU resources.
* After updating, restart the browser and reconnect to your Vagon computer.

## 3. Distance Between Vagon Computer Region and User Location

Physical distance between your location and the selected Vagon computer region directly affects latency. If you experience lag, check the selected region and make sure you are connected to the nearest available location. If you are connected to a distant region, contact your Team Administrator to update it.

## 4. Network & Firewall Issues

Corporate networks, VPNs, proxies, and strict firewalls can interfere with streaming traffic.

What to check:

* Temporarily disable VPN/proxy and test the connection again.
* If you are on a corporate network, ask your IT team to allow Vagon traffic and required WebRTC connections.
* Check whether network security tools are throttling or blocking real-time media streams.
* If possible, test from a different network to confirm whether the issue is environment-specific.

If the issue continues after these checks, contact the Vagon team and include your location, selected region, network type, and a short description of the problem pattern (for example: periodic lag every few minutes, constant high latency, or random disconnects).


# Microsoft 365 Login Issues

Microsoft 365 applications running inside your Vagon computer sign in through Microsoft's licensing and identity flows. Occasionally these flows can leave your account in a state where the Microsoft apps can no longer complete sign-in, even though the account still appears on your computer.

When this happens, opening a Microsoft app or trying to log in to your Microsoft 365 account can return a **Device TPM problem** error.

<figure><img src="/files/AxnYq6LZ9Vf8meOvNfsG" alt="Device TPM problem error dialog"><figcaption></figcaption></figure>

Depending on the flow, the same underlying issue may also be reported with one of the following messages:

* **An unexpected error occurred.**
* **Keyset does not exist.**
* **The credential is invalid. Unexpected sub status (6008).**

If you run into any of these, follow the steps below to re-register your account and restore access.

## 1. Close All Microsoft Applications

Before making any changes, close **every** open Microsoft application window (Outlook, Word, Excel, Teams, OneDrive, etc.). The account cannot be re-registered correctly while these apps are still running.

## 2. Open the Accounts Settings

Open the **Settings** app from the Start Menu, switch to the **Accounts** tab, and click **Email & accounts** to list the active accounts on the computer.

<figure><img src="/files/30aO3FrwqxDhq9ITultZ" alt="Accounts settings with Email &#x26; accounts highlighted"><figcaption></figcaption></figure>

## 3. Re-Add Your Account via "Add a work or school account"

On the **Email & accounts** page, under **Accounts used by other apps**, click **Add a work or school account** and sign in to your Microsoft 365 account.

<figure><img src="/files/8CBvVNn9fUgUTF5oxHO5" alt="Email &#x26; accounts page with Add a work or school account highlighted"><figcaption></figcaption></figure>

> **Do this even if your account is already listed on the page.** Seeing your account under **Accounts used by other apps** does not mean it is registered correctly. You must re-add it through **Add a work or school account** to resolve the error.

Once you have signed in, you will be able to open your Microsoft 365 applications without any issues.

## Common Mistakes

Two mistakes prevent this fix from working — avoid both:

* **Clicking the wrong button.** The blue **Add account** button at the top of the page is more prominent, so it is easy to click by mistake. It does **not** resolve this issue. You must use the **Add a work or school account** link under *Accounts used by other apps*.
* **Leaving the page too early.** If you see your account already listed and assume nothing needs to be done, the error will persist. Always re-add the account through **Add a work or school account**, even when it already appears in the list.


# How to Use Teams API

## Get Teams API Keys

Before starting API integration for Vagon Teams, you must have at least one Team Computer. API Key and Secret Key will be accessible on the **Settings** tab on your dashboard.

* **API Public Key**
* **Secret Key**

<figure><img src="/files/hkM5M2ejtiWeBVxXrule" alt=""><figcaption></figcaption></figure>

## Authentication <a href="#id-1-client-authentication" id="id-1-client-authentication"></a>

The client must be authenticated by using **API Public** and **Secret** **keys** with HMAC authentication, by using the SHA256 algorithm.

* Every API call requires to be authenticated via the Authorization header.
* **Header format**\
  `Authorization: HMAC {key}:{signature}:{nonce}:{timestamp}`
* Signature payload is calculated as\
  `payload = "{api key}{request method}{request path}{timestamp}{nonce}{request body}"`
* `request path` shouldn't include the base API endpoint. For example; if you send a GET request to `https://api.vagon.io/organization-management/v1/machines` the request path should be `/organization-management/v1/machines`
* Request body should be an empty string for `GET` requests.
* Signature is calculated as the\
  `signature = HMAC(SHA256, payload, api secret)`
* Signature should be in HexaDecimal format
* The nonce is a random string value and the timestamp is the current UTC timestamp (milliseconds).

#### **Machine Status List**

| friendly\_status  | description                                                    |
| ----------------- | -------------------------------------------------------------- |
| off               | Machine is stopped                                             |
| creating          | Machine is started at the first time                           |
| turning\_on       | Machine is turning on                                          |
| ready             | Machine is running, and ready to connect                       |
| turning\_off      | Machine is turning off, to be stopped                          |
| resizing\_disk    | Machine disk size is expanding                                 |
| installing        | Machine image/template assignment post process is in progress. |
| region\_migration | Machine region migration is in progress                        |
| warming\_up       | Machine is getting ready at the first run                      |


# Authentication

HMAC-SHA256 based authentication. Every request must include an `Authorization` header.

#### Header Format

```
Authorization: HMAC {api_key}:{signature}:{nonce}:{timestamp}
```

All four parts are separated by `:` with no spaces.

#### Parameters

| Parameter   | Type   | Description                                                                                            |
| ----------- | ------ | ------------------------------------------------------------------------------------------------------ |
| `api_key`   | String | Your API key (provided by Vagon)                                                                       |
| `signature` | String | HMAC-SHA256 **hex digest** of the signing string (see below)                                           |
| `nonce`     | String | A unique random string for each request (e.g., UUID). Must never be reused.                            |
| `timestamp` | String | Current time as **milliseconds since Unix epoch** (e.g., `1712567890123`). Not seconds — milliseconds. |

#### Signature Computation

**Step 1 — Build the signing string**

Concatenate the following values **with no separator** (no spaces, no newlines, no delimiters):

```
{api_key}{HTTP_METHOD}{path}{timestamp}{nonce}{request_body}
```

| Component      | Description                                                                   | Example                                |
| -------------- | ----------------------------------------------------------------------------- | -------------------------------------- |
| `api_key`      | Same API key used in the header                                               | `ak_live_abc123`                       |
| `HTTP_METHOD`  | Uppercase HTTP method                                                         | `POST`, `GET`, `PATCH`, `DELETE`       |
| `path`         | **Full request path** including the base path, without query string or host   | `/organization-management/v1/machines` |
| `timestamp`    | Same timestamp used in the header (milliseconds)                              | `1712567890123`                        |
| `nonce`        | Same nonce used in the header                                                 | `550e8400-e29b-41d4-a716-446655440000` |
| `request_body` | Raw JSON request body. **Empty string for GET/DELETE requests with no body.** | `{"plan_id":1,"quantity":1}`           |

**Step 2 — Sign with HMAC-SHA256**

Sign the concatenated string using your **API secret** as the key, producing a **hex digest** (lowercase).

```
signature = HMAC-SHA256(api_secret, signing_string).hexdigest
```

#### Important Notes

* **Path must be the full path** (e.g., `/organization-management/v1/machines`), without query string or host.
* **Timestamp is in milliseconds**, not seconds (13 digits, e.g., `1712567890123`).
* **GET/DELETE requests** with no body: use an empty string `""` as the `request_body` component.
* **Nonce must be unique** per request (use UUID or random string).
* **Signature is hex-encoded**: lowercase hex string (64 characters for SHA-256), not Base64.

#### Full Example

**Given:**

* API Key: `ak_live_abc123`
* API Secret: `sk_live_xyz789`
* Method: `POST`
* Path: `/organization-management/v1/machines`
* Timestamp: `1712567890123`
* Nonce: `550e8400-e29b-41d4-a716-446655440000`
* Body: `{"plan_id":1,"quantity":1,"region":"dublin"}`

**Step 1 — Signing string (concatenated, no separator):**

```
ak_live_abc123POST/organization-management/v1/machines1712567890123550e8400-e29b-41d4-a716-446655440000{"plan_id":1,"quantity":1,"region":"dublin"}
```

**Step 2 — Compute signature:**

```python
import hmac, hashlib
signing_string = 'ak_live_abc123POST/organization-management/v1/machines1712567890123550e8400-e29b-41d4-a716-446655440000{"plan_id":1,"quantity":1,"region":"dublin"}'
signature = hmac.new(b'sk_live_xyz789', signing_string.encode(), hashlib.sha256).hexdigest()
```

**Step 3 — Final header:**

```
Authorization: HMAC ak_live_abc123:{computed_signature}:550e8400-e29b-41d4-a716-446655440000:1712567890123
```

**GET request example (no body):**

```
signing_string = "ak_live_abc123GET/organization-management/v1/machines1712567890123550e8400-e29b-41d4-a716-446655440000"
```

#### Replay Protection

Requests with a timestamp older than **60 seconds** from the server's current time are rejected. Ensure your system clock is synchronized (NTP recommended).

#### Error Responses

| HTTP Status        | Cause                                                                         |
| ------------------ | ----------------------------------------------------------------------------- |
| `400 Bad Request`  | Missing `Authorization` header                                                |
| `401 Unauthorized` | Invalid signature, expired timestamp, missing token parts, or unknown API key |


# Machines

## List Machines

> List all machine(s) with their applied configurations.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Query Parameters\*\*\
> \
> \| Parameter | Type | Default | Description |\
> \| --- | --- | --- | --- |\
> \| \`page\` | Integer | 1 | Page number |\
> \| \`per\_page\` | Integer | 20 | Record count per page |\
> \| \`q\` | String | \\- | Search query by user email or machine name |\
> \| \`time\_left\` | Integer | \\- | Filter by remaining usage in minutes. Returns machines with at least this many minutes remaining |\
> \| \`has\_session\_data\` | Boolean | \\- | Filter by whether machine has session data after reset. \`true\` = has session data (sessions after reset), \`false\` = no session data |\
> \| \`assigned\` | Boolean | \\- | Filter by machine assignment. \`true\` = only machines has a user or pending invitation, \`false\` = only machines has no user and no pending invitation |\
> \| \`status\` | String | \\- | Filter by machine status. |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "machines": \[\
> &#x20;       {\
> &#x20;           "id": "100",\
> &#x20;           "type": "machine",\
> &#x20;           "attributes": {\
> &#x20;               "name": "Computer #100",\
> &#x20;               "last\_session\_start\_at": "2026-01-23T11:02:41.902Z",\
> &#x20;               "os": "windows",\
> &#x20;               "auto\_stop\_threshold": 900,\
> &#x20;               "file\_storage\_size": 25,\
> &#x20;               "disk\_size": 75,\
> &#x20;               "network\_credit": 10233505675,\
> &#x20;               "assigned\_image\_id": 990,\
> &#x20;               "assigned\_image\_name": "Template #990",\
> &#x20;               "region": "dublin",\
> &#x20;               "machine\_type": "Planet",\
> &#x20;               "remaining\_usage": 0,\
> &#x20;               "deposited\_usage": 0,\
> &#x20;               "friendly\_status": "off",\
> &#x20;               "user": {\
> &#x20;                   "id": "f1592625-edd0-48df-9bc0-de14910ec936",\
> &#x20;                   "type": "user",\
> &#x20;                   "attributes": {\
> &#x20;                       "email": "<user@vagon.io>",\
> &#x20;                       "name": "Computer User"\
> &#x20;                   }\
> &#x20;               },\
> &#x20;               "permissions": {\
> &#x20;                   "public\_internet\_access": true,\
> &#x20;                   "can\_download\_from\_vagon\_workstation": true,\
> &#x20;                   "can\_upload\_to\_workstation": true,\
> &#x20;                   "analytics\_collection\_enabled": true,\
> &#x20;                   "clipboard\_enabled": true,\
> &#x20;                   "screen\_recording\_enabled": true,\
> &#x20;                   "input\_recording\_enabled": true\
> &#x20;               },\
> &#x20;               "usage\_source": "machine",\
> &#x20;               "task": {\
> &#x20;                   "id": 42,\
> &#x20;                   "uid": "Project-Alpha",\
> &#x20;                   "created\_at": "2026-04-20T09:15:00Z"\
> &#x20;               },\
> &#x20;               "latest\_image\_status": "ready"\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "101",\
> &#x20;           "type": "machine",\
> &#x20;           "attributes": {\
> &#x20;               "name": "Computer #101",\
> &#x20;               "last\_session\_start\_at": "2026-01-23T14:12:18.943Z",\
> &#x20;               "os": "linux",\
> &#x20;               "auto\_stop\_threshold": 900,\
> &#x20;               "file\_storage\_size": 250,\
> &#x20;               "disk\_size": 125,\
> &#x20;               "network\_credit": 10338256517,\
> &#x20;               "assigned\_image\_id": 991,\
> &#x20;               "assigned\_image\_name": "Template #991",\
> &#x20;               "region": "dublin",\
> &#x20;               "machine\_type": "Planet",\
> &#x20;               "remaining\_usage": 2400,\
> &#x20;               "deposited\_usage": 0,\
> &#x20;               "user": null,\
> &#x20;               "permissions": {\
> &#x20;                   "public\_internet\_access": true,\
> &#x20;                   "can\_download\_from\_vagon\_workstation": true,\
> &#x20;                   "can\_upload\_to\_workstation": true,\
> &#x20;                   "analytics\_collection\_enabled": true,\
> &#x20;                   "clipboard\_enabled": true,\
> &#x20;                   "screen\_recording\_enabled": true,\
> &#x20;                   "input\_recording\_enabled": true\
> &#x20;               },\
> &#x20;               "friendly\_status": "off",\
> &#x20;               "usage\_source": "machine",\
> &#x20;               "task": null,\
> &#x20;               "latest\_image\_status": "processing"\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "count": 2,\
> &#x20;   "page": 1,\
> &#x20;   "next\_page": null,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-05T10:08:09Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`machines\` | Array | Array of machine objects |\
> \| \`machines\[].id\` | String | Machine ID |\
> \| \`machines\[].type\` | String | Always "machine" |\
> \| \`machines\[].attributes.name\` | String | Machine Name |\
> \| \`machines\[].attributes.os\` | String | Operating system: \`windows\` or \`linux\` |\
> \| \`machines\[].attributes.last\_session\_start\_at\` | String | Last session start time (ISO 8601). null if no session |\
> \| \`machines\[].attributes.auto\_stop\_threshold\` | Integer | Auto-stop threshold in seconds |\
> \| \`machines\[].attributes.file\_storage\_size\` | Integer | Vagon Files storage size in GB |\
> \| \`machines\[].attributes.disk\_size\` | Integer | Machine disk size in GB |\
> \| \`machines\[].attributes.network\_credit\` | Integer | Available outbound network credits in bytes |\
> \| \`machines\[].attributes.assigned\_image\_id\` | Integer | Assigned image/template ID. null if none |\
> \| \`machines\[].attributes.assigned\_image\_name\` | String | Name of the assigned base image/template. null if none |\
> \| \`machines\[].attributes.region\` | String | Machine region |\
> \| \`machines\[].attributes.machine\_type\` | String | Machine Performance Type |\
> \| \`machines\[].attributes.remaining\_usage\` | Integer | Remaining usage time in minutes |\
> \| \`machines\[].attributes.deposited\_usage\` | Integer | Deposited usage time in minutes |\
> \| \`machines\[].attributes.friendly\_status\` | String | Machine Status |\
> \| \`machines\[].attributes.user\` | Object | Assigned User (null if no user) |\
> \| \`machines\[].attributes.user.id\` | String | User UUID |\
> \| \`machines\[].attributes.user.type\` | String | Always "user" |\
> \| \`machines\[].attributes.user.attributes.email\` | String | User email |\
> \| \`machines\[].attributes.user.attributes.name\` | String | User name |\
> \| \`machines\[].attributes.permissions\` | Object | Machine Permissions |\
> \| \`machines\[].attributes.usage\_source\` | String | Usage source - "machine" (only assigned usages) or "team\_balance" (can use team balance when no additional usage on machine) |\
> \| \`machines\[].attributes.task\` | Object | Active task on the machine (null if no task is active) |\
> \| \`machines\[].attributes.task.id\` | Integer | Active task ID on the machine |\
> \| \`machines\[].attributes.task.uid\` | String | Unique human-readable task name / uid for the machine |\
> \| \`machines\[].attributes.task.created\_at\` | String | Task creation timestamp to the machine (ISO 8601) |\
> \| \`machines\[].attributes.latest\_image\_status\` | String | Snapshot state of the latest machine image. One of \`in\_use\`, \`processing\`, \`ready\`, or \`null\`. \`null\` = machine has no user data yet (never started, or reset since); \`in\_use\` = machine is not off; \`processing\` = a snapshot is being captured; \`ready\` = machine is off and no snapshot is being captured. |\
> \| \`count\` | Integer | Total number of machines |\
> \| \`page\` | Integer | Current page number |\
> \| \`next\_page\` | Integer | Next page number. null if last page |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines":{"get":{"summary":"List Machines","parameters":[{"name":"page","in":"query","description":"(Optional) Page number. Default: 1","schema":{"type":"integer"}},{"name":"per_page","in":"query","description":"(Optional) Records per page. Default: 20","schema":{"type":"integer"}},{"name":"q","in":"query","description":"(Optional) Search by user email or machine name","schema":{"type":"string"}}],"responses":{"200":{"description":"List of machines","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMachinesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"480":{"description":"Insufficient funds","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error480Response"}}}},"4201":{"description":"Machine is not ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4201Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"List all machine(s) with their applied configurations.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Query Parameters**\n\n| Parameter | Type | Default | Description |\n| --- | --- | --- | --- |\n| `page` | Integer | 1 | Page number |\n| `per_page` | Integer | 20 | Record count per page |\n| `q` | String | \\- | Search query by user email or machine name |\n| `time_left` | Integer | \\- | Filter by remaining usage in minutes. Returns machines with at least this many minutes remaining |\n| `has_session_data` | Boolean | \\- | Filter by whether machine has session data after reset. `true` = has session data (sessions after reset), `false` = no session data |\n| `assigned` | Boolean | \\- | Filter by machine assignment. `true` = only machines has a user or pending invitation, `false` = only machines has no user and no pending invitation |\n| `status` | String | \\- | Filter by machine status. |\n\n### **Success Response Example**\n\n``` json\n{\n    \"machines\": [\n        {\n            \"id\": \"100\",\n            \"type\": \"machine\",\n            \"attributes\": {\n                \"name\": \"Computer #100\",\n                \"last_session_start_at\": \"2026-01-23T11:02:41.902Z\",\n                \"os\": \"windows\",\n                \"auto_stop_threshold\": 900,\n                \"file_storage_size\": 25,\n                \"disk_size\": 75,\n                \"network_credit\": 10233505675,\n                \"assigned_image_id\": 990,\n                \"assigned_image_name\": \"Template #990\",\n                \"region\": \"dublin\",\n                \"machine_type\": \"Planet\",\n                \"remaining_usage\": 0,\n                \"deposited_usage\": 0,\n                \"friendly_status\": \"off\",\n                \"user\": {\n                    \"id\": \"f1592625-edd0-48df-9bc0-de14910ec936\",\n                    \"type\": \"user\",\n                    \"attributes\": {\n                        \"email\": \"user@vagon.io\",\n                        \"name\": \"Computer User\"\n                    }\n                },\n                \"permissions\": {\n                    \"public_internet_access\": true,\n                    \"can_download_from_vagon_workstation\": true,\n                    \"can_upload_to_workstation\": true,\n                    \"analytics_collection_enabled\": true,\n                    \"clipboard_enabled\": true,\n                    \"screen_recording_enabled\": true,\n                    \"input_recording_enabled\": true\n                },\n                \"usage_source\": \"machine\",\n                \"task\": {\n                    \"id\": 42,\n                    \"uid\": \"Project-Alpha\",\n                    \"created_at\": \"2026-04-20T09:15:00Z\"\n                },\n                \"latest_image_status\": \"ready\"\n            }\n        },\n        {\n            \"id\": \"101\",\n            \"type\": \"machine\",\n            \"attributes\": {\n                \"name\": \"Computer #101\",\n                \"last_session_start_at\": \"2026-01-23T14:12:18.943Z\",\n                \"os\": \"linux\",\n                \"auto_stop_threshold\": 900,\n                \"file_storage_size\": 250,\n                \"disk_size\": 125,\n                \"network_credit\": 10338256517,\n                \"assigned_image_id\": 991,\n                \"assigned_image_name\": \"Template #991\",\n                \"region\": \"dublin\",\n                \"machine_type\": \"Planet\",\n                \"remaining_usage\": 2400,\n                \"deposited_usage\": 0,\n                \"user\": null,\n                \"permissions\": {\n                    \"public_internet_access\": true,\n                    \"can_download_from_vagon_workstation\": true,\n                    \"can_upload_to_workstation\": true,\n                    \"analytics_collection_enabled\": true,\n                    \"clipboard_enabled\": true,\n                    \"screen_recording_enabled\": true,\n                    \"input_recording_enabled\": true\n                },\n                \"friendly_status\": \"off\",\n                \"usage_source\": \"machine\",\n                \"task\": null,\n                \"latest_image_status\": \"processing\"\n            }\n        }\n    ],\n    \"count\": 2,\n    \"page\": 1,\n    \"next_page\": null,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-05T10:08:09Z\"\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `machines` | Array | Array of machine objects |\n| `machines[].id` | String | Machine ID |\n| `machines[].type` | String | Always \"machine\" |\n| `machines[].attributes.name` | String | Machine Name |\n| `machines[].attributes.os` | String | Operating system: `windows` or `linux` |\n| `machines[].attributes.last_session_start_at` | String | Last session start time (ISO 8601). null if no session |\n| `machines[].attributes.auto_stop_threshold` | Integer | Auto-stop threshold in seconds |\n| `machines[].attributes.file_storage_size` | Integer | Vagon Files storage size in GB |\n| `machines[].attributes.disk_size` | Integer | Machine disk size in GB |\n| `machines[].attributes.network_credit` | Integer | Available outbound network credits in bytes |\n| `machines[].attributes.assigned_image_id` | Integer | Assigned image/template ID. null if none |\n| `machines[].attributes.assigned_image_name` | String | Name of the assigned base image/template. null if none |\n| `machines[].attributes.region` | String | Machine region |\n| `machines[].attributes.machine_type` | String | Machine Performance Type |\n| `machines[].attributes.remaining_usage` | Integer | Remaining usage time in minutes |\n| `machines[].attributes.deposited_usage` | Integer | Deposited usage time in minutes |\n| `machines[].attributes.friendly_status` | String | Machine Status |\n| `machines[].attributes.user` | Object | Assigned User (null if no user) |\n| `machines[].attributes.user.id` | String | User UUID |\n| `machines[].attributes.user.type` | String | Always \"user\" |\n| `machines[].attributes.user.attributes.email` | String | User email |\n| `machines[].attributes.user.attributes.name` | String | User name |\n| `machines[].attributes.permissions` | Object | Machine Permissions |\n| `machines[].attributes.usage_source` | String | Usage source - \"machine\" (only assigned usages) or \"team_balance\" (can use team balance when no additional usage on machine) |\n| `machines[].attributes.task` | Object | Active task on the machine (null if no task is active) |\n| `machines[].attributes.task.id` | Integer | Active task ID on the machine |\n| `machines[].attributes.task.uid` | String | Unique human-readable task name / uid for the machine |\n| `machines[].attributes.task.created_at` | String | Task creation timestamp to the machine (ISO 8601) |\n| `machines[].attributes.latest_image_status` | String | Snapshot state of the latest machine image. One of `in_use`, `processing`, `ready`, or `null`. `null` = machine has no user data yet (never started, or reset since); `in_use` = machine is not off; `processing` = a snapshot is being captured; `ready` = machine is off and no snapshot is being captured. |\n| `count` | Integer | Total number of machines |\n| `page` | Integer | Current page number |\n| `next_page` | Integer | Next page number. null if last page |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |"}}},"components":{"schemas":{"ListMachinesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"machines":{"type":"array","items":{"$ref":"#/components/schemas/Machine"}},"count":{"type":"integer","description":"Total number of machines"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Machine":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/MachineAttributes"}}},"MachineAttributes":{"type":"object","properties":{"name":{"type":"string"},"region":{"type":"string","nullable":true},"last_session_start_at":{"type":"string","format":"date-time","nullable":true},"friendly_status":{"type":"string","enum":["off","creating","turning_on","ready","turning_off","resizing_disk","installing","region_migration","warming_up"]},"auto_stop_threshold":{"type":"integer","description":"Auto-stop threshold in seconds"},"file_storage_size":{"type":"integer","description":"Vagon Files storage size in bytes"},"disk_size":{"type":"integer","description":"Machine disk size in bytes"},"network_credit":{"type":"integer","description":"Available outbound network credits in bytes"},"assigned_image_id":{"type":"integer","nullable":true,"description":"Assigned base image ID. null if using default image"},"assigned_image_name":{"type":"string","nullable":true,"description":"Name of the assigned base image/template. null if none"},"machine_type":{"type":"string"},"remaining_usage":{"type":"integer","description":"Remaining usage time in seconds"},"deposited_usage":{"type":"integer","description":"Deposited usage time in seconds"},"user":{"type":"object","nullable":true,"description":"Assigned user (null if no user). When present contains id, type, attributes (email, name)","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"attributes":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}},"permissions":{"$ref":"#/components/schemas/Permissions"},"usage_source":{"type":"string","enum":["machine","team_balance"],"description":"\"machine\" means the computer will only use assigned usages. \"team_balance\" means the computer can use team balance as a fallback source when there is no additional usage on the machine."},"task":{"type":"object","nullable":true,"description":"Currently active task on the machine. null when no task is active or when the seat's `backup_enabled` flag is off.","properties":{"id":{"type":"integer","description":"Task ID. Use this for task API calls (e.g. DELETE /tasks/:id)."},"uid":{"type":"string","description":"Human-readable task name (e.g. \"Outputs\", \"Project-Alpha\")."},"created_at":{"type":"string","format":"date-time","description":"Timestamp when this task was created and assigned to the seat."}}},"latest_image_status":{"type":"string","nullable":true,"enum":["in_use","processing","ready"],"description":"Combined snapshot state of the machine's latest image.\n  - `null`: machine has no user data yet (never started, or has been reset and not used since).\n  - `in_use`: machine is not off, so no snapshot can be captured right now.\n  - `processing`: a snapshot is currently being captured (pending image, or within the post-stop scheduling window before the pending record exists).\n  - `ready`: machine is off and no snapshot is being captured (latest committed image, if any, reflects the machine's current state).\n"}}},"Permissions":{"type":"object","description":"Machine permission settings","properties":{"public_internet_access":{"type":"boolean","description":"Allow public internet access from the machine"},"can_download_from_vagon_workstation":{"type":"boolean","description":"Allow file downloads from the Vagon workstation"},"can_upload_to_workstation":{"type":"boolean","description":"Allow file uploads to the Vagon workstation"},"analytics_collection_enabled":{"type":"boolean","description":"Enable analytics data collection"},"clipboard_enabled":{"type":"boolean","description":"Enable clipboard sharing between local and remote machine"},"screen_recording_enabled":{"type":"boolean","description":"Enable screen recording capability"},"input_recording_enabled":{"type":"boolean","description":"Enable input (keyboard/mouse) recording"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error480Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4201Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Create Machines

> Create machine(s) with selected configurations. Associated payments will be processed from organization balance.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`plan\_id\`\\\* | Integer | Plan ID. Determines which plan the machine will use. Defines available machine types, disk size, file storage size, etc. Contact Vagon team to learn Plan ID options. |\
> \| \`quantity\` | Integer | Number of machines to create. Must be greater than 0. Default: 1 |\
> \| \`region\` | String | Region where machine will be created (e.g., "dublin", "frankfurt"). Required if default region is not set for the account, globally. |\
> \| \`os\` | String | Operating system for the created machines: \`windows\` or \`linux\`. Optional. Default: \`windows\`. |\
> \| \`software\_ids\` | Array\\\[Integer\\] | Array of software IDs to pre-install. Use \`GET /software\` to see available software |\
> \| \`base\_image\_id\` | Integer | Base image ID, when it's null uses latest base image. Use \`GET /software\` to see available images |\
> \| \`permissions.public\_internet\_access\` | Boolean | Whether machine has internet access. Default: true |\
> \| \`permissions.can\_download\_from\_vagon\_workstation\` | Boolean | Whether files can be downloaded from Vagon machine. Default: true |\
> \| \`permissions.can\_upload\_to\_workstation\` | Boolean | Whether team member is allowed to upload files to the Vagon workstation. Default: true |\
> \| \`permissions.analytics\_collection\_enabled\` | Boolean | Whether analytics collection is enabled. Default: false |\
> \| \`permissions.clipboard\_enabled\` | Boolean | Whether clipboard sharing is enabled. Default: true |\
> \| \`permissions.screen\_recording\_enabled\` | Boolean | Whether screen recording is enabled. Default: false |\
> \| \`permissions.input\_recording\_enabled\` | Boolean | Whether input recording is enabled. Default: false |\
> \
> \### Request Body\
> \
> \`\`\` json\
> {\
> &#x20; "plan\_id": 1,\
> &#x20; "quantity": 1,\
> &#x20; "region": "dublin",\
> &#x20; "os": "windows",\
> &#x20; "software\_ids": \[],\
> &#x20; "base\_image\_id": 100,\
> &#x20; "permissions": {\
> &#x20;   "public\_internet\_access": true,\
> &#x20;   "can\_download\_from\_vagon\_workstation": true,\
> &#x20;   "can\_upload\_to\_workstation": true,\
> &#x20;   "analytics\_collection\_enabled": false,\
> &#x20;   "clipboard\_enabled": true,\
> &#x20;   "screen\_recording\_enabled": false,\
> &#x20;   "input\_recording\_enabled": false\
> &#x20; }\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "machines": \[\
> &#x20;       {\
> &#x20;           "id": "100",\
> &#x20;           "type": "machine",\
> &#x20;           "attributes": {\
> &#x20;               "name": "Computer #100",\
> &#x20;               "last\_session\_start\_at": null,\
> &#x20;               "os": "windows",\
> &#x20;               "auto\_stop\_threshold": 900,\
> &#x20;               "file\_storage\_size": 25,\
> &#x20;               "disk\_size": 75,\
> &#x20;               "network\_credit": 10737418240,\
> &#x20;               "assigned\_image\_id": 100,\
> &#x20;               "assigned\_image\_name": "Template #100",\
> &#x20;               "region": "dublin",\
> &#x20;               "machine\_type": "Planet",\
> &#x20;               "remaining\_usage": 0,\
> &#x20;               "deposited\_usage": 0,\
> &#x20;               "user": null,\
> &#x20;               "friendly\_status": "off",\
> &#x20;               "permissions": {\
> &#x20;                   "public\_internet\_access": true,\
> &#x20;                   "can\_download\_from\_vagon\_workstation": true,\
> &#x20;                   "can\_upload\_to\_workstation": true,\
> &#x20;                   "analytics\_collection\_enabled": false,\
> &#x20;                   "clipboard\_enabled": true,\
> &#x20;                   "screen\_recording\_enabled": false,\
> &#x20;                   "input\_recording\_enabled": false\
> &#x20;               },\
> &#x20;               "task": null,\
> &#x20;               "latest\_image\_status": null\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "count": 1,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-05T10:10:22Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`machines\` | Array | Array of created machine objects |\
> \| \`machines\[].id\` | String | Machine ID |\
> \| \`machines\[].type\` | String | Always "machine" |\
> \| \`machines\[].attributes.name\` | String | Machine Name |\
> \| \`machines\[].attributes.os\` | String | Operating system: \`windows\` or \`linux\` |\
> \| \`machines\[].attributes.last\_session\_start\_at\` | String | Last session start time (ISO 8601). null if no session |\
> \| \`machines\[].attributes.auto\_stop\_threshold\` | Integer | Auto-stop threshold in seconds |\
> \| \`machines\[].attributes.file\_storage\_size\` | Integer | Vagon Files storage size in GB |\
> \| \`machines\[].attributes.disk\_size\` | Integer | Machine disk size in GB |\
> \| \`machines\[].attributes.network\_credit\` | Integer | Available  network credits in bytes |\
> \| \`machines\[].attributes.assigned\_image\_id\` | Integer | Assigned image/template ID. null if none |\
> \| \`machines\[].attributes.assigned\_image\_name\` | String | Name of the assigned base image/template. null if none |\
> \| \`machines\[].attributes.region\` | String | Machine region |\
> \| \`machines\[].attributes.machine\_type\` | String | Machine Performance Type |\
> \| \`machines\[].attributes.remaining\_usage\` | Integer | Remaining usage time in minutes |\
> \| \`machines\[].attributes.deposited\_usage\` | Integer | Deposited usage time in minutes |\
> \| \`machines\[].attributes.user\` | Object | Assigned User (null if no user) |\
> \| \`machines\[].attributes.friendly\_status\` | String | Machine Status - check documentation for detailed machine states. |\
> \| \`machines\[].attributes.permissions\` | Object | Machine Permissions |\
> \| \`machines\[].attributes.task\` | Object | Active task on the machine (null if no task is active) |\
> \| \`machines\[].attributes.task.id\` | Integer | Active task ID on the machine |\
> \| \`machines\[].attributes.task.uid\` | String | Unique human-readable task name / uid for the machine |\
> \| \`machines\[].attributes.task.created\_at\` | String | Task creation timestamp to the machine (ISO 8601) |\
> \| \`machines\[].attributes.latest\_image\_status\` | String | Snapshot state of the latest machine image. One of \`in\_use\`, \`processing\`, \`ready\`, or \`null\`. \`null\` = machine has no user data yet (never started, or reset since); \`in\_use\` = machine is not off; \`processing\` = a snapshot is being captured; \`ready\` = machine is off and no snapshot is being captured. |\
> \| \`count\` | Integer | Number of machines created |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Plan ID not found |\
> \| 480 | Insufficient balance to create computer |\
> \| 4202 | Region is required |\
> \| 4710 | Permission required |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines":{"post":{"summary":"Create Machines","responses":{"200":{"description":"Machines created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMachinesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Plan ID not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"480":{"description":"Insufficient balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error480Response"}}}},"4202":{"description":"Region is required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4202Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Create machine(s) with selected configurations. Associated payments will be processed from organization balance.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `plan_id`\\* | Integer | Plan ID. Determines which plan the machine will use. Defines available machine types, disk size, file storage size, etc. Contact Vagon team to learn Plan ID options. |\n| `quantity` | Integer | Number of machines to create. Must be greater than 0. Default: 1 |\n| `region` | String | Region where machine will be created (e.g., \"dublin\", \"frankfurt\"). Required if default region is not set for the account, globally. |\n| `os` | String | Operating system for the created machines: `windows` or `linux`. Optional. Default: `windows`. |\n| `software_ids` | Array\\[Integer\\] | Array of software IDs to pre-install. Use `GET /software` to see available software |\n| `base_image_id` | Integer | Base image ID, when it's null uses latest base image. Use `GET /software` to see available images |\n| `permissions.public_internet_access` | Boolean | Whether machine has internet access. Default: true |\n| `permissions.can_download_from_vagon_workstation` | Boolean | Whether files can be downloaded from Vagon machine. Default: true |\n| `permissions.can_upload_to_workstation` | Boolean | Whether team member is allowed to upload files to the Vagon workstation. Default: true |\n| `permissions.analytics_collection_enabled` | Boolean | Whether analytics collection is enabled. Default: false |\n| `permissions.clipboard_enabled` | Boolean | Whether clipboard sharing is enabled. Default: true |\n| `permissions.screen_recording_enabled` | Boolean | Whether screen recording is enabled. Default: false |\n| `permissions.input_recording_enabled` | Boolean | Whether input recording is enabled. Default: false |\n\n### Request Body\n\n``` json\n{\n  \"plan_id\": 1,\n  \"quantity\": 1,\n  \"region\": \"dublin\",\n  \"os\": \"windows\",\n  \"software_ids\": [],\n  \"base_image_id\": 100,\n  \"permissions\": {\n    \"public_internet_access\": true,\n    \"can_download_from_vagon_workstation\": true,\n    \"can_upload_to_workstation\": true,\n    \"analytics_collection_enabled\": false,\n    \"clipboard_enabled\": true,\n    \"screen_recording_enabled\": false,\n    \"input_recording_enabled\": false\n  }\n}\n\n ```\n\n### **Success Response Example**\n\n``` json\n{\n    \"machines\": [\n        {\n            \"id\": \"100\",\n            \"type\": \"machine\",\n            \"attributes\": {\n                \"name\": \"Computer #100\",\n                \"last_session_start_at\": null,\n                \"os\": \"windows\",\n                \"auto_stop_threshold\": 900,\n                \"file_storage_size\": 25,\n                \"disk_size\": 75,\n                \"network_credit\": 10737418240,\n                \"assigned_image_id\": 100,\n                \"assigned_image_name\": \"Template #100\",\n                \"region\": \"dublin\",\n                \"machine_type\": \"Planet\",\n                \"remaining_usage\": 0,\n                \"deposited_usage\": 0,\n                \"user\": null,\n                \"friendly_status\": \"off\",\n                \"permissions\": {\n                    \"public_internet_access\": true,\n                    \"can_download_from_vagon_workstation\": true,\n                    \"can_upload_to_workstation\": true,\n                    \"analytics_collection_enabled\": false,\n                    \"clipboard_enabled\": true,\n                    \"screen_recording_enabled\": false,\n                    \"input_recording_enabled\": false\n                },\n                \"task\": null,\n                \"latest_image_status\": null\n            }\n        }\n    ],\n    \"count\": 1,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-05T10:10:22Z\"\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `machines` | Array | Array of created machine objects |\n| `machines[].id` | String | Machine ID |\n| `machines[].type` | String | Always \"machine\" |\n| `machines[].attributes.name` | String | Machine Name |\n| `machines[].attributes.os` | String | Operating system: `windows` or `linux` |\n| `machines[].attributes.last_session_start_at` | String | Last session start time (ISO 8601). null if no session |\n| `machines[].attributes.auto_stop_threshold` | Integer | Auto-stop threshold in seconds |\n| `machines[].attributes.file_storage_size` | Integer | Vagon Files storage size in GB |\n| `machines[].attributes.disk_size` | Integer | Machine disk size in GB |\n| `machines[].attributes.network_credit` | Integer | Available  network credits in bytes |\n| `machines[].attributes.assigned_image_id` | Integer | Assigned image/template ID. null if none |\n| `machines[].attributes.assigned_image_name` | String | Name of the assigned base image/template. null if none |\n| `machines[].attributes.region` | String | Machine region |\n| `machines[].attributes.machine_type` | String | Machine Performance Type |\n| `machines[].attributes.remaining_usage` | Integer | Remaining usage time in minutes |\n| `machines[].attributes.deposited_usage` | Integer | Deposited usage time in minutes |\n| `machines[].attributes.user` | Object | Assigned User (null if no user) |\n| `machines[].attributes.friendly_status` | String | Machine Status - check documentation for detailed machine states. |\n| `machines[].attributes.permissions` | Object | Machine Permissions |\n| `machines[].attributes.task` | Object | Active task on the machine (null if no task is active) |\n| `machines[].attributes.task.id` | Integer | Active task ID on the machine |\n| `machines[].attributes.task.uid` | String | Unique human-readable task name / uid for the machine |\n| `machines[].attributes.task.created_at` | String | Task creation timestamp to the machine (ISO 8601) |\n| `machines[].attributes.latest_image_status` | String | Snapshot state of the latest machine image. One of `in_use`, `processing`, `ready`, or `null`. `null` = machine has no user data yet (never started, or reset since); `in_use` = machine is not off; `processing` = a snapshot is being captured; `ready` = machine is off and no snapshot is being captured. |\n| `count` | Integer | Number of machines created |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Plan ID not found |\n| 480 | Insufficient balance to create computer |\n| 4202 | Region is required |\n| 4710 | Permission required |","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["plan_id","quantity","region"],"properties":{"plan_id":{"type":"integer","description":"Subscription plan ID"},"quantity":{"type":"integer","description":"Number of machines to create"},"region":{"type":"string","description":"Region for the machine (e.g., dublin, frankfurt)"},"os":{"type":"string","enum":["windows","linux"],"default":"windows","description":"Operating system for the created machines. Optional; defaults to windows."},"software_ids":{"type":"array","description":"List of software IDs to pre-install","items":{"type":"integer"}},"base_image_id":{"type":"integer","nullable":true,"description":"Base image ID to use (null for default)"},"permissions":{"type":"object","description":"Machine permission settings","properties":{"public_internet_access":{"type":"boolean","description":"Allow public internet access"},"can_download_from_vagon_workstation":{"type":"boolean","description":"Allow file downloads from workstation"},"can_upload_to_workstation":{"type":"boolean","description":"Allow file uploads to the Vagon workstation"},"analytics_collection_enabled":{"type":"boolean","description":"Enable analytics collection"},"clipboard_enabled":{"type":"boolean","description":"Enable clipboard sharing"},"screen_recording_enabled":{"type":"boolean","description":"Enable screen recording"},"input_recording_enabled":{"type":"boolean","description":"Enable input recording"}}}}}}}}}}},"components":{"schemas":{"CreateMachinesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"machines":{"type":"array","items":{"$ref":"#/components/schemas/Machine"}},"count":{"type":"integer"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Machine":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/MachineAttributes"}}},"MachineAttributes":{"type":"object","properties":{"name":{"type":"string"},"region":{"type":"string","nullable":true},"last_session_start_at":{"type":"string","format":"date-time","nullable":true},"friendly_status":{"type":"string","enum":["off","creating","turning_on","ready","turning_off","resizing_disk","installing","region_migration","warming_up"]},"auto_stop_threshold":{"type":"integer","description":"Auto-stop threshold in seconds"},"file_storage_size":{"type":"integer","description":"Vagon Files storage size in bytes"},"disk_size":{"type":"integer","description":"Machine disk size in bytes"},"network_credit":{"type":"integer","description":"Available outbound network credits in bytes"},"assigned_image_id":{"type":"integer","nullable":true,"description":"Assigned base image ID. null if using default image"},"assigned_image_name":{"type":"string","nullable":true,"description":"Name of the assigned base image/template. null if none"},"machine_type":{"type":"string"},"remaining_usage":{"type":"integer","description":"Remaining usage time in seconds"},"deposited_usage":{"type":"integer","description":"Deposited usage time in seconds"},"user":{"type":"object","nullable":true,"description":"Assigned user (null if no user). When present contains id, type, attributes (email, name)","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"attributes":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}},"permissions":{"$ref":"#/components/schemas/Permissions"},"usage_source":{"type":"string","enum":["machine","team_balance"],"description":"\"machine\" means the computer will only use assigned usages. \"team_balance\" means the computer can use team balance as a fallback source when there is no additional usage on the machine."},"task":{"type":"object","nullable":true,"description":"Currently active task on the machine. null when no task is active or when the seat's `backup_enabled` flag is off.","properties":{"id":{"type":"integer","description":"Task ID. Use this for task API calls (e.g. DELETE /tasks/:id)."},"uid":{"type":"string","description":"Human-readable task name (e.g. \"Outputs\", \"Project-Alpha\")."},"created_at":{"type":"string","format":"date-time","description":"Timestamp when this task was created and assigned to the seat."}}},"latest_image_status":{"type":"string","nullable":true,"enum":["in_use","processing","ready"],"description":"Combined snapshot state of the machine's latest image.\n  - `null`: machine has no user data yet (never started, or has been reset and not used since).\n  - `in_use`: machine is not off, so no snapshot can be captured right now.\n  - `processing`: a snapshot is currently being captured (pending image, or within the post-stop scheduling window before the pending record exists).\n  - `ready`: machine is off and no snapshot is being captured (latest committed image, if any, reflects the machine's current state).\n"}}},"Permissions":{"type":"object","description":"Machine permission settings","properties":{"public_internet_access":{"type":"boolean","description":"Allow public internet access from the machine"},"can_download_from_vagon_workstation":{"type":"boolean","description":"Allow file downloads from the Vagon workstation"},"can_upload_to_workstation":{"type":"boolean","description":"Allow file uploads to the Vagon workstation"},"analytics_collection_enabled":{"type":"boolean","description":"Enable analytics data collection"},"clipboard_enabled":{"type":"boolean","description":"Enable clipboard sharing between local and remote machine"},"screen_recording_enabled":{"type":"boolean","description":"Enable screen recording capability"},"input_recording_enabled":{"type":"boolean","description":"Enable input (keyboard/mouse) recording"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error480Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4202Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Update Machine

> Update machine settings. All parameters are optional; only sent fields are updated.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Machine ID |\
> \
> \### Request Body\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`auto\_stop\_threshold\` | Integer | Auto-stop threshold in seconds. Options": \`"0"\`, \`"900"\`, \`"3600"\`, \`"10800"\`, \`"21600"\`. \`"0"\` to disable. |\
> \| \`usage\_source\` | String | \`"team\_balance"\` or \`"machine"\`. Controls whether usage is drawn from team balance or machine-only balance. |\
> \
> \### Success Response Fields\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | String | Machine ID |\
> \| \`type\` | String | Always "machine" |\
> \| \`attributes.name\` | String | Machine Name |\
> \| \`attributes.os\` | String | Operating system: \`windows\` or \`linux\` |\
> \| \`attributes.last\_session\_start\_at\` | String | Last session start time (ISO 8601). null if no session |\
> \| \`attributes.auto\_stop\_threshold\` | Integer | Auto-stop threshold in seconds |\
> \| \`attributes.file\_storage\_size\` | Integer | Vagon Files storage size in GB |\
> \| \`attributes.disk\_size\` | Integer | Machine disk size in GB |\
> \| \`attributes.network\_credit\` | Integer | Available outbound network credits in bytes |\
> \| \`attributes.assigned\_image\_id\` | Integer | Assigned image/template ID. null if none |\
> \| \`attributes.assigned\_image\_name\` | String | Name of the assigned base image/template. null if none |\
> \| \`attributes.region\` | String | Machine region |\
> \| \`attributes.machine\_type\` | String | Machine Performance Type |\
> \| \`attributes.remaining\_usage\` | Integer | Remaining usage time in minutes |\
> \| \`attributes.deposited\_usage\` | Integer | Deposited usage time in minutes |\
> \| \`attributes.friendly\_status\` | String | Machine Status |\
> \| \`attributes.user\` | Object | Assigned User (null if no user) |\
> \| \`attributes.user.id\` | String | User UUID |\
> \| \`attributes.user.type\` | String | Always "user" |\
> \| \`attributes.user.attributes.email\` | String | User email |\
> \| \`attributes.user.attributes.name\` | String | User name |\
> \| \`attributes.permissions\` | Object | Machine Permissions |\
> \| \`attributes.usage\_source\` | String | Usage source - "machine" (only assigned usages) or "team\_balance" (can use team balance when no additional usage on machine) |\
> \| \`attributes.task\` | Object | Active task on the machine (null if no task is active) |\
> \| \`attributes.task.id\` | Integer | Active task ID on the machine |\
> \| \`attributes.task.uid\` | String | Unique human-readable task name / uid for the machine |\
> \| \`attributes.task.created\_at\` | String | Task creation timestamp to the machine (ISO 8601) |\
> \| \`attributes.latest\_image\_status\` | String | Snapshot state of the latest machine image. One of \`in\_use\`, \`processing\`, \`ready\`, or \`null\`. \`null\` = machine has no user data yet (never started, or reset since); \`in\_use\` = machine is not off; \`processing\` = a snapshot is being captured; \`ready\` = machine is off and no snapshot is being captured. |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |

```json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}":{"patch":{"summary":"Update Machine","responses":{"200":{"description":"Machine updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MachineResponse"}}}},"400":{"description":"Bad request (e.g. invalid usage_source)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Update machine settings. All parameters are optional; only sent fields are updated.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Machine ID |\n\n### Request Body\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `auto_stop_threshold` | Integer | Auto-stop threshold in seconds. Options\": `\"0\"`, `\"900\"`, `\"3600\"`, `\"10800\"`, `\"21600\"`. `\"0\"` to disable. |\n| `usage_source` | String | `\"team_balance\"` or `\"machine\"`. Controls whether usage is drawn from team balance or machine-only balance. |\n\n### Success Response Fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `id` | String | Machine ID |\n| `type` | String | Always \"machine\" |\n| `attributes.name` | String | Machine Name |\n| `attributes.os` | String | Operating system: `windows` or `linux` |\n| `attributes.last_session_start_at` | String | Last session start time (ISO 8601). null if no session |\n| `attributes.auto_stop_threshold` | Integer | Auto-stop threshold in seconds |\n| `attributes.file_storage_size` | Integer | Vagon Files storage size in GB |\n| `attributes.disk_size` | Integer | Machine disk size in GB |\n| `attributes.network_credit` | Integer | Available outbound network credits in bytes |\n| `attributes.assigned_image_id` | Integer | Assigned image/template ID. null if none |\n| `attributes.assigned_image_name` | String | Name of the assigned base image/template. null if none |\n| `attributes.region` | String | Machine region |\n| `attributes.machine_type` | String | Machine Performance Type |\n| `attributes.remaining_usage` | Integer | Remaining usage time in minutes |\n| `attributes.deposited_usage` | Integer | Deposited usage time in minutes |\n| `attributes.friendly_status` | String | Machine Status |\n| `attributes.user` | Object | Assigned User (null if no user) |\n| `attributes.user.id` | String | User UUID |\n| `attributes.user.type` | String | Always \"user\" |\n| `attributes.user.attributes.email` | String | User email |\n| `attributes.user.attributes.name` | String | User name |\n| `attributes.permissions` | Object | Machine Permissions |\n| `attributes.usage_source` | String | Usage source - \"machine\" (only assigned usages) or \"team_balance\" (can use team balance when no additional usage on machine) |\n| `attributes.task` | Object | Active task on the machine (null if no task is active) |\n| `attributes.task.id` | Integer | Active task ID on the machine |\n| `attributes.task.uid` | String | Unique human-readable task name / uid for the machine |\n| `attributes.task.created_at` | String | Task creation timestamp to the machine (ISO 8601) |\n| `attributes.latest_image_status` | String | Snapshot state of the latest machine image. One of `in_use`, `processing`, `ready`, or `null`. `null` = machine has no user data yet (never started, or reset since); `in_use` = machine is not off; `processing` = a snapshot is being captured; `ready` = machine is off and no snapshot is being captured. |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"auto_stop_threshold":{"type":"integer","description":"Auto-stop threshold in seconds. 0 to disable."},"usage_source":{"type":"string","enum":["team_balance","machine"],"description":"Usage source - team_balance or machine"}}}}}}}}},"components":{"schemas":{"MachineResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"$ref":"#/components/schemas/Machine"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Machine":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/MachineAttributes"}}},"MachineAttributes":{"type":"object","properties":{"name":{"type":"string"},"region":{"type":"string","nullable":true},"last_session_start_at":{"type":"string","format":"date-time","nullable":true},"friendly_status":{"type":"string","enum":["off","creating","turning_on","ready","turning_off","resizing_disk","installing","region_migration","warming_up"]},"auto_stop_threshold":{"type":"integer","description":"Auto-stop threshold in seconds"},"file_storage_size":{"type":"integer","description":"Vagon Files storage size in bytes"},"disk_size":{"type":"integer","description":"Machine disk size in bytes"},"network_credit":{"type":"integer","description":"Available outbound network credits in bytes"},"assigned_image_id":{"type":"integer","nullable":true,"description":"Assigned base image ID. null if using default image"},"assigned_image_name":{"type":"string","nullable":true,"description":"Name of the assigned base image/template. null if none"},"machine_type":{"type":"string"},"remaining_usage":{"type":"integer","description":"Remaining usage time in seconds"},"deposited_usage":{"type":"integer","description":"Deposited usage time in seconds"},"user":{"type":"object","nullable":true,"description":"Assigned user (null if no user). When present contains id, type, attributes (email, name)","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"attributes":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}},"permissions":{"$ref":"#/components/schemas/Permissions"},"usage_source":{"type":"string","enum":["machine","team_balance"],"description":"\"machine\" means the computer will only use assigned usages. \"team_balance\" means the computer can use team balance as a fallback source when there is no additional usage on the machine."},"task":{"type":"object","nullable":true,"description":"Currently active task on the machine. null when no task is active or when the seat's `backup_enabled` flag is off.","properties":{"id":{"type":"integer","description":"Task ID. Use this for task API calls (e.g. DELETE /tasks/:id)."},"uid":{"type":"string","description":"Human-readable task name (e.g. \"Outputs\", \"Project-Alpha\")."},"created_at":{"type":"string","format":"date-time","description":"Timestamp when this task was created and assigned to the seat."}}},"latest_image_status":{"type":"string","nullable":true,"enum":["in_use","processing","ready"],"description":"Combined snapshot state of the machine's latest image.\n  - `null`: machine has no user data yet (never started, or has been reset and not used since).\n  - `in_use`: machine is not off, so no snapshot can be captured right now.\n  - `processing`: a snapshot is currently being captured (pending image, or within the post-stop scheduling window before the pending record exists).\n  - `ready`: machine is off and no snapshot is being captured (latest committed image, if any, reflects the machine's current state).\n"}}},"Permissions":{"type":"object","description":"Machine permission settings","properties":{"public_internet_access":{"type":"boolean","description":"Allow public internet access from the machine"},"can_download_from_vagon_workstation":{"type":"boolean","description":"Allow file downloads from the Vagon workstation"},"can_upload_to_workstation":{"type":"boolean","description":"Allow file uploads to the Vagon workstation"},"analytics_collection_enabled":{"type":"boolean","description":"Enable analytics data collection"},"clipboard_enabled":{"type":"boolean","description":"Enable clipboard sharing between local and remote machine"},"screen_recording_enabled":{"type":"boolean","description":"Enable screen recording capability"},"input_recording_enabled":{"type":"boolean","description":"Enable input (keyboard/mouse) recording"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
```

## Start Machine

> Start selected machine.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Machine ID |\
> \
> \### Success Response\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-05T10:11:54Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Machine not found |\
> \| 480 | Insufficient balance |\
> \| 4710 | Permission required |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/start":{"post":{"summary":"Start Machine","responses":{"200":{"description":"Machine started successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"480":{"description":"Insufficient balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error480Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Start selected machine.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Machine ID |\n\n### Success Response\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-05T10:11:54Z\"\n}\n\n ```\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Machine not found |\n| 480 | Insufficient balance |\n| 4710 | Permission required |"}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error480Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Get Available Machine Performances

> Lists all available machine types for a specific machine based on its plan.\
> \
> Machine types define the hardware specifications (CPU, RAM, GPU) that can be used for the machine.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | Integer | Machine ID |\
> \
> \### Response Fields\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`machine\_types\` | Array | Array of available machine type objects |\
> \| \`machine\_types\[].id\` | String | Machine type ID (use this in machine\_type\_id parameter) |\
> \| \`machine\_types\[].type\` | String | Always "machine\_type" |\
> \| \`machine\_types\[].attributes.name\` | String | Internal machine type name (e.g., "g4dn.xlarge") |\
> \| \`machine\_types\[].attributes.friendly\_name\` | String | Human-readable machine type name (e.g., "Planet", "Spark") |\
> \| \`machine\_types\[].attributes.cpu\` | Integer | Number of CPU cores |\
> \| \`machine\_types\[].attributes.memory\` | String | RAM size in GB (e.g., "16.0") |\
> \| \`machine\_types\[].attributes.gpu\` | Integer | Number of GPUs (0 = no GPU) |\
> \| \`machine\_types\[].attributes.gpu\_memory\` | String | GPU memory in GB (e.g., "16.0") |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### Response Example\
> \
> \`\`\` json\
> {\
> &#x20;   "machine\_types": \[\
> &#x20;       {\
> &#x20;           "id": "11",\
> &#x20;           "type": "machine\_type",\
> &#x20;           "attributes": {\
> &#x20;               "name": "g4dn.xlarge",\
> &#x20;               "friendly\_name": "Planet",\
> &#x20;               "cpu": 4,\
> &#x20;               "memory": "16.0",\
> &#x20;               "gpu": 1,\
> &#x20;               "gpu\_memory": "16.0"\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "15",\
> &#x20;           "type": "machine\_type",\
> &#x20;           "attributes": {\
> &#x20;               "name": "g5.xlarge",\
> &#x20;               "friendly\_name": "Spark",\
> &#x20;               "cpu": 4,\
> &#x20;               "memory": "16.0",\
> &#x20;               "gpu": 1,\
> &#x20;               "gpu\_memory": "24.0"\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T11:13:07Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/available-machine-types":{"get":{"summary":"Get Available Machine Performances","responses":{"200":{"description":"List of available machine types","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailableMachineTypesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Lists all available machine types for a specific machine based on its plan.\n\nMachine types define the hardware specifications (CPU, RAM, GPU) that can be used for the machine.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id` | Integer | Machine ID |\n\n### Response Fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `machine_types` | Array | Array of available machine type objects |\n| `machine_types[].id` | String | Machine type ID (use this in machine_type_id parameter) |\n| `machine_types[].type` | String | Always \"machine_type\" |\n| `machine_types[].attributes.name` | String | Internal machine type name (e.g., \"g4dn.xlarge\") |\n| `machine_types[].attributes.friendly_name` | String | Human-readable machine type name (e.g., \"Planet\", \"Spark\") |\n| `machine_types[].attributes.cpu` | Integer | Number of CPU cores |\n| `machine_types[].attributes.memory` | String | RAM size in GB (e.g., \"16.0\") |\n| `machine_types[].attributes.gpu` | Integer | Number of GPUs (0 = no GPU) |\n| `machine_types[].attributes.gpu_memory` | String | GPU memory in GB (e.g., \"16.0\") |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### Response Example\n\n``` json\n{\n    \"machine_types\": [\n        {\n            \"id\": \"11\",\n            \"type\": \"machine_type\",\n            \"attributes\": {\n                \"name\": \"g4dn.xlarge\",\n                \"friendly_name\": \"Planet\",\n                \"cpu\": 4,\n                \"memory\": \"16.0\",\n                \"gpu\": 1,\n                \"gpu_memory\": \"16.0\"\n            }\n        },\n        {\n            \"id\": \"15\",\n            \"type\": \"machine_type\",\n            \"attributes\": {\n                \"name\": \"g5.xlarge\",\n                \"friendly_name\": \"Spark\",\n                \"cpu\": 4,\n                \"memory\": \"16.0\",\n                \"gpu\": 1,\n                \"gpu_memory\": \"24.0\"\n            }\n        }\n    ],\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T11:13:07Z\"\n}\n\n ```"}}},"components":{"schemas":{"AvailableMachineTypesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"machine_types":{"type":"array","items":{"$ref":"#/components/schemas/MachineType"}}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"MachineType":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/MachineTypeAttributes"}}},"MachineTypeAttributes":{"type":"object","properties":{"name":{"type":"string","description":"AWS instance type name"},"friendly_name":{"type":"string","description":"User-friendly machine type name"},"cpu":{"type":"integer","description":"Number of CPU cores"},"memory":{"type":"string","description":"RAM in GB"},"gpu":{"type":"integer","description":"Number of GPUs"},"gpu_memory":{"type":"string","description":"GPU memory in GB"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Set Machine Performance

> Changes the machine performance type. Allows you to change the machine's CPU, RAM, GPU, and GPU memory allocation. The machine must be stopped before changing the type.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | Integer | Machine ID |\
> \
> \### Body Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`machine\_type\_id\` | Integer | Yes | New machine type ID. Must be one of the types available in the machine's plan. Use \`GET /machines/:id/available-machine-types\` to see available types |\
> \
> \*\*Success Response:\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T11:16:28Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/machine-type":{"post":{"summary":"Set Machine Performance","responses":{"200":{"description":"Machine type updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4205":{"description":"Machine type is not available for this seat plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4205Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Changes the machine performance type. Allows you to change the machine's CPU, RAM, GPU, and GPU memory allocation. The machine must be stopped before changing the type.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id` | Integer | Machine ID |\n\n### Body Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `machine_type_id` | Integer | Yes | New machine type ID. Must be one of the types available in the machine's plan. Use `GET /machines/:id/available-machine-types` to see available types |\n\n**Success Response:**\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T11:16:28Z\"\n}\n\n ```","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"machine_type_id":{"type":"integer"}}}}}}}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4205Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Stop Machine

> Stop the selected running machine.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Machine ID |\
> \
> \### Body Parameters\
> \
> \| Parameter | Type | Default | Description |\
> \| --- | --- | --- | --- |\
> \| \`gracefully\` | Boolean | false | \`true\`: Sends graceful shutdown signal, and let system to save logs and recordings. Use to prevent any file interruptions.  \<br>  \<br>\`false\`: Stops machine immediately |\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Machine not found |\
> \| 4204 | Machine is not running |\
> \| 4710 | Permission required |\
> \
> \### Success Response\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T11:18:42Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/stop":{"post":{"summary":"Stop Machine","responses":{"200":{"description":"Machine stopped successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4204":{"description":"Machine is not running","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4204Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Stop the selected running machine.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Machine ID |\n\n### Body Parameters\n\n| Parameter | Type | Default | Description |\n| --- | --- | --- | --- |\n| `gracefully` | Boolean | false | `true`: Sends graceful shutdown signal, and let system to save logs and recordings. Use to prevent any file interruptions.  <br>  <br>`false`: Stops machine immediately |\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Machine not found |\n| 4204 | Machine is not running |\n| 4710 | Permission required |\n\n### Success Response\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T11:18:42Z\"\n}\n\n ```","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"gracefully":{"type":"boolean"}}}}}}}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4204Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Get Access Link for a Machine

> Creates a temporary access token for external access to the machine.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | Integer | Machine ID |\
> \
> \### Body Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`expires\_in\`\\\* | Integer | Token validity duration in minutes. Minimum: 1 minute. Example: 60 = 1 hour, 1440 = 24 hours |\
> \
> \### Success Response\
> \
> \`\`\` json\
> {\
> &#x20;   "id": "77",\
> &#x20;   "type": "machine\_external\_access",\
> &#x20;   "attributes": {\
> &#x20;       "expires\_at": "2026-02-05T11:12:42.677Z",\
> &#x20;       "connection\_link": "<https://app.vagon.io/team/session/62ba2d60-5ee2-11aa-aa64-957da90ef117"\\>
> &#x20;   },\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-05T10:12:42Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### Response Fields\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | String | Unique identifier for the access token |\
> \| \`type\` | String | Always "machine\_external\_access" |\
> \| \`attributes.expires\_at\` | String | ISO 8601 timestamp when the token expires |\
> \| \`attributes.connection\_link\` | String | Full URL that can be shared with users to access the machine |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/access":{"post":{"summary":"Get Access Link for a Machine","responses":{"200":{"description":"Access link created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MachineAccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Creates a temporary access token for external access to the machine.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id` | Integer | Machine ID |\n\n### Body Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `expires_in`\\* | Integer | Token validity duration in minutes. Minimum: 1 minute. Example: 60 = 1 hour, 1440 = 24 hours |\n\n### Success Response\n\n``` json\n{\n    \"id\": \"77\",\n    \"type\": \"machine_external_access\",\n    \"attributes\": {\n        \"expires_at\": \"2026-02-05T11:12:42.677Z\",\n        \"connection_link\": \"https://app.vagon.io/team/session/62ba2d60-5ee2-11aa-aa64-957da90ef117\"\n    },\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-05T10:12:42Z\"\n}\n\n ```\n\n### Response Fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `id` | String | Unique identifier for the access token |\n| `type` | String | Always \"machine_external_access\" |\n| `attributes.expires_at` | String | ISO 8601 timestamp when the token expires |\n| `attributes.connection_link` | String | Full URL that can be shared with users to access the machine |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"expires_in":{"type":"integer"}}}}}}}}},"components":{"schemas":{"MachineAccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/MachineAccessAttributes"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"MachineAccessAttributes":{"type":"object","description":"Machine external access token attributes","properties":{"expires_at":{"type":"string","format":"date-time","description":"Token expiration timestamp"},"connection_link":{"type":"string","format":"uri","description":"URL to access the machine session"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Reset Machine to Initial State

> Resets all files and data inside the computer, and revert it to the initial machine image state. This action is irreversible. All data on the machine will be permanently deleted.\
> \
> \### Task Behavior on Reset\
> \
> All non-default tasks are deleted and their Desktop source folders (\`C:\Users\Administrator\Desktop\\{uid}\`) are removed from the machine on the next boot. The default "Outputs" task is preserved and set as active. Task names that were removed by the reset become reusable.\
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Machine ID |\
> \
> \### Body Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`remove\_files\` | Boolean | No | When \`true\`, the VagonFiles folder (computer files) is also wiped as part of the reset. When \`false\` (default), VagonFiles are preserved. |\
> \
> \### Success Response\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T11:31:12Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Machine not found |\
> \| 4206 | Machine is running |\
> \| 4710 | Permission required |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/reset":{"post":{"summary":"Reset Machine to Initial State","responses":{"200":{"description":"Machine reset successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4206":{"description":"Machine is running","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4206Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Resets all files and data inside the computer, and revert it to the initial machine image state. This action is irreversible. All data on the machine will be permanently deleted.\n\n### Task Behavior on Reset\n\nAll non-default tasks are deleted and their Desktop source folders (`C:\\Users\\Administrator\\Desktop\\{uid}`) are removed from the machine on the next boot. The default \"Outputs\" task is preserved and set as active. Task names that were removed by the reset become reusable.\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Machine ID |\n\n### Body Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `remove_files` | Boolean | No | When `true`, the VagonFiles folder (computer files) is also wiped as part of the reset. When `false` (default), VagonFiles are preserved. |\n\n### Success Response\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T11:31:12Z\"\n}\n\n ```\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Machine not found |\n| 4206 | Machine is running |\n| 4710 | Permission required |","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"remove_files":{"type":"boolean","default":false,"description":"When `true`, the VagonFiles folder (computer files) is also wiped as part of the reset. When `false` (default), VagonFiles are preserved."}}}}}}}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4206Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Manage Permissions

> Updates permissions for a specific machine.\
> \
> This endpoint allows you to modify permission settings for a machine's seat. Only permission fields available in the external API can be updated.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Machine ID |\
> \
> \### Body Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`permissions\`\\\* | Object | Yes | Dictionary of permission field names to boolean values |\
> \| \`permissions.public\_internet\_access\` | Boolean | No | Whether machine has internet access |\
> \| \`permissions.can\_download\_from\_vagon\_workstation\` | Boolean | No | Whether files can be downloaded from the Vagon Computer |\
> \| \`permissions.can\_upload\_to\_workstation\` | Boolean | No | Whether team members are allowed to upload files to the Vagon Computer |\
> \| \`permissions.analytics\_collection\_enabled\` | Boolean | No | Whether analytics collection is enabled |\
> \| \`permissions.clipboard\_enabled\` | Boolean | No | Whether clipboard sharing is enabled |\
> \| \`permissions.screen\_recording\_enabled\` | Boolean | No | Whether screen recording is enabled |\
> \| \`permissions.input\_recording\_enabled\` | Boolean | No | Whether input recording is enabled |\
> \
> \### Request Body\
> \
> \`\`\` json\
> {\
> &#x20; "permissions": {\
> &#x20;   "public\_internet\_access": true,\
> &#x20;   "can\_download\_from\_vagon\_workstation": true,\
> &#x20;   "can\_upload\_to\_workstation": true,\
> &#x20;   "analytics\_collection\_enabled": false,\
> &#x20;   "clipboard\_enabled": true,\
> &#x20;   "screen\_recording\_enabled": false,\
> &#x20;   "input\_recording\_enabled": false\
> &#x20; }\
> }\
> \
> &#x20;\`\`\`\
> \
> \### Success Response\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T11:41:34Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (invalid permissions) |\
> \| 404 | Machine not found |\
> \| 4710 | Permission required |\
> \
> \### Notes\
> \
> \- Only permission fields available in the external API can be updated\
> \- Use \`GET /machines/permission-fields\` to see available permission fields\
> \- Permission changes are logged in user action logs

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/permissions":{"post":{"summary":"Manage Permissions","responses":{"200":{"description":"Permissions updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Updates permissions for a specific machine.\n\nThis endpoint allows you to modify permission settings for a machine's seat. Only permission fields available in the external API can be updated.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Machine ID |\n\n### Body Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `permissions`\\* | Object | Yes | Dictionary of permission field names to boolean values |\n| `permissions.public_internet_access` | Boolean | No | Whether machine has internet access |\n| `permissions.can_download_from_vagon_workstation` | Boolean | No | Whether files can be downloaded from the Vagon Computer |\n| `permissions.can_upload_to_workstation` | Boolean | No | Whether team members are allowed to upload files to the Vagon Computer |\n| `permissions.analytics_collection_enabled` | Boolean | No | Whether analytics collection is enabled |\n| `permissions.clipboard_enabled` | Boolean | No | Whether clipboard sharing is enabled |\n| `permissions.screen_recording_enabled` | Boolean | No | Whether screen recording is enabled |\n| `permissions.input_recording_enabled` | Boolean | No | Whether input recording is enabled |\n\n### Request Body\n\n``` json\n{\n  \"permissions\": {\n    \"public_internet_access\": true,\n    \"can_download_from_vagon_workstation\": true,\n    \"can_upload_to_workstation\": true,\n    \"analytics_collection_enabled\": false,\n    \"clipboard_enabled\": true,\n    \"screen_recording_enabled\": false,\n    \"input_recording_enabled\": false\n  }\n}\n\n ```\n\n### Success Response\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T11:41:34Z\"\n}\n\n ```\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (invalid permissions) |\n| 404 | Machine not found |\n| 4710 | Permission required |\n\n### Notes\n\n- Only permission fields available in the external API can be updated\n- Use `GET /machines/permission-fields` to see available permission fields\n- Permission changes are logged in user action logs","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["permissions"],"properties":{"permissions":{"type":"object","description":"Permission settings to update","properties":{"public_internet_access":{"type":"boolean","description":"Allow public internet access"},"can_download_from_vagon_workstation":{"type":"boolean","description":"Allow file downloads from workstation"},"can_upload_to_workstation":{"type":"boolean","description":"Allow file uploads to the Vagon workstation"},"analytics_collection_enabled":{"type":"boolean","description":"Enable analytics collection"},"clipboard_enabled":{"type":"boolean","description":"Enable clipboard sharing"},"screen_recording_enabled":{"type":"boolean","description":"Enable screen recording"},"input_recording_enabled":{"type":"boolean","description":"Enable input recording"}}}}}}}}}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Run Remote Script

> Runs a script on a machine and returns its output. The interpreter depends on the machine OS: \*\*Windows\*\* machines run the script via \*\*PowerShell\*\*, \*\*Linux\*\* machines run it as a \*\*bash\*\* script.\
> \
> The script in \`script\_body\` is executed on the machine via the workstation agent. The request waits up to \*\*5 seconds\*\* for the agent to respond. If the agent responds in time, its output is returned in \`result\`. If the call times out (or otherwise fails), \`result\` is an empty string \`""\`.\
> \
> The machine must have been launched at least once (it must have a cloud instance id); otherwise the request returns \`400\`.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Path Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | Machine ID |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`script\_body\` | String | Yes | The script to execute on the machine: PowerShell on Windows machines, bash on Linux machines |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (e.g., missing \`script\_body\` or machine has never been launched) |\
> \| 404 | Machine not found or does not belong to organization |\
> \| 4710 | Permission required |\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`result\` | String | The script output, or \`""\` if the call timed out |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Request Body Example (single line)\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "script\_body": "Write-Output \\"PowerShell script is working!\\""\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Request Body Example (multi line)\*\*\
> \
> Multi-line scripts are sent as a single JSON string with each line separated by an escaped newline (\`\n\`):\
> \
> \`\`\` json\
> {\
> &#x20; "script\_body": "Write-Output \\"OS            : $((Get-CimInstance Win32\_OperatingSystem).Caption)\\"\nWrite-Output \\"PS Version    : $($PSVersionTable.PSVersion)\\"\nWrite-Output \\"Timestamp     : $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')\\""\
> }\
> \
> &#x20;\`\`\`\
> \
> \
> The \`script\_body\` above corresponds to the following PowerShell:\
> \
> \`\`\` powershell\
> Write-Output "OS            : $((Get-CimInstance Win32\_OperatingSystem).Caption)" Write-Output "PS Version    : $($PSVersionTable.PSVersion)" Write-Output "Timestamp     : $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"\
> \
> &#x20;\`\`\`\
> \
> \
> \### \*\*Request Body Example (Linux / bash)\*\*\
> \
> On Linux machines \`script\_body\` is a bash script:\
> \
> \`\`\` json\
> {\
> &#x20; "script\_body": "echo \\"OS        : $(uname -a)\\"\necho \\"Timestamp : $(date '+%Y-%m-%d %H:%M:%S')\\""\
> }\
> \
> &#x20;\`\`\`\
> \
> \
> ...which corresponds to the following bash:\
> \
> \`\`\` bash\
> echo "OS        : $(uname -a)" echo "Timestamp : $(date '+%Y-%m-%d %H:%M:%S')"\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "result": "PowerShell script is working!",\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T11:55:10Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/run-script":{"post":{"summary":"Run Remote Script","responses":{"200":{"description":"Script execution result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunScriptResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Runs a script on a machine and returns its output. The interpreter depends on the machine OS: **Windows** machines run the script via **PowerShell**, **Linux** machines run it as a **bash** script.\n\nThe script in `script_body` is executed on the machine via the workstation agent. The request waits up to **5 seconds** for the agent to respond. If the agent responds in time, its output is returned in `result`. If the call times out (or otherwise fails), `result` is an empty string `\"\"`.\n\nThe machine must have been launched at least once (it must have a cloud instance id); otherwise the request returns `400`.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Path Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | Machine ID |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `script_body` | String | Yes | The script to execute on the machine: PowerShell on Windows machines, bash on Linux machines |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (e.g., missing `script_body` or machine has never been launched) |\n| 404 | Machine not found or does not belong to organization |\n| 4710 | Permission required |\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `result` | String | The script output, or `\"\"` if the call timed out |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Request Body Example (single line)**\n\n``` json\n{\n  \"script_body\": \"Write-Output \\\"PowerShell script is working!\\\"\"\n}\n\n ```\n\n### **Request Body Example (multi line)**\n\nMulti-line scripts are sent as a single JSON string with each line separated by an escaped newline (`\\n`):\n\n``` json\n{\n  \"script_body\": \"Write-Output \\\"OS            : $((Get-CimInstance Win32_OperatingSystem).Caption)\\\"\\nWrite-Output \\\"PS Version    : $($PSVersionTable.PSVersion)\\\"\\nWrite-Output \\\"Timestamp     : $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')\\\"\"\n}\n\n ```\n\n\nThe `script_body` above corresponds to the following PowerShell:\n\n``` powershell\nWrite-Output \"OS            : $((Get-CimInstance Win32_OperatingSystem).Caption)\" Write-Output \"PS Version    : $($PSVersionTable.PSVersion)\" Write-Output \"Timestamp     : $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')\"\n\n ```\n\n\n### **Request Body Example (Linux / bash)**\n\nOn Linux machines `script_body` is a bash script:\n\n``` json\n{\n  \"script_body\": \"echo \\\"OS        : $(uname -a)\\\"\\necho \\\"Timestamp : $(date '+%Y-%m-%d %H:%M:%S')\\\"\"\n}\n\n ```\n\n\n...which corresponds to the following bash:\n\n``` bash\necho \"OS        : $(uname -a)\" echo \"Timestamp : $(date '+%Y-%m-%d %H:%M:%S')\"\n\n ```\n\n### **Response Example**\n\n``` json\n{\n    \"result\": \"PowerShell script is working!\",\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T11:55:10Z\"\n}\n\n ```","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["script_body"],"properties":{"script_body":{"type":"string","description":"The script to execute on the machine: PowerShell on Windows machines, bash on Linux machines"}}}}}}}}},"components":{"schemas":{"RunScriptResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"result":{"type":"string","description":"The script output, or an empty string if the call timed out"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Bulk Create & Assign Computers

> Bulk-creates and assigns computers to users for the authenticated organization from a list of rows. Each row maps a region/area, an optional template, optional applications to pre-install, and an optional disk size to a user (by \`email\`). \`email\` is \*\*optional\*\*: a row sent without an email creates the computer \*\*unassigned\*\* — no user and no invitation — so you can pre-provision computers and assign them to people later.\
> \
> \> \*\*Availability\*\* > > This endpoint is available upon request for selected customers. Please > contact Vagon to enable bulk computer creation for your organization.\
> \
> The computer plan is the supplied \`plan\_id\`; when omitted, the organization's configured default computer plan is used. \`4706\` is returned \*\*only\*\* when neither is configured. If a plan id \*is\* resolved but does not exist for the organization, the request returns \`4202\` — resolved plans must belong to the organization (or be a global plan).\
> \
> Set \`dry\_run\` to \`true\` to preview the outcome without making any changes (no computers are assigned, no invitations are created). The response shape is identical for dry runs and real runs.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`rows\` | Array | Yes | List of assignment rows (see Row Fields) |\
> \| \`plan\_id\` | Integer | No | Computer plan to assign. Falls back to the organization's configured default computer plan when omitted |\
> \| \`dry\_run\` | Boolean | No | When \`true\`, preview only — no changes are persisted. Defaults to \`false\` |\
> \
> \### \*\*Row Fields\*\*\
> \
> \| Field | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`email\` | String | No | Email of the user to assign the computer to. Leave blank to create the computer unassigned (no user, no invitation) |\
> \| \`os\` | String | No | Operating system for the row's computer: \`windows\` or \`linux\`. Per-row — set it on each row independently. Blank or invalid values fall back to \`windows\`. |\
> \| \`region\` | String | No | Target area. Supported values: \`europe\`, \`us\_east\`, \`us\_west\`, \`us\_central\`, \`canada\`, \`south\_america\`, \`south\_africa\`, \`australia\`, \`south\_asia\`, \`east\_asia\`, \`south\_east\_asia\`. Unknown values are rejected — see Per-row validation below |\
> \| \`template\_name\` | String | No | Name of the template (silver image) to assign. Available values can be collected from \[Get Images]\(<https://docs.vagon.io/teams/reference/images#get-images>) |\
> \| \`applications\` | Array | No | Application names to pre-install. Send values as an array of software names. Available values can be collected from \[Get Software]\(<https://docs.vagon.io/teams/reference/software#get-software>) |\
> \| \`disk\_size\` | String | No | Optional per-computer disk size override in GB. Supported values: \`125\`, \`175\`, \`225\`, \`275\`, \`325\`, \`375\`, \`425\`, \`475\`, \`525\`. Blank, zero, or non-positive values are ignored — the computer keeps its plan default. |\
> \
> \### \*\*Per-row validation\*\*\
> \
> Rows are validated independently — an invalid row is reported with an \`error\` message in its result entry and is \*\*not\*\* assigned (no invitation or computer is created for it), while valid rows in the same request are still processed. The validation applies in both \`dry\_run\` and execute modes, so a preview surfaces every error before you commit.\
> \
> \| Condition | \`error\` message |\
> \| --- | --- |\
> \| \`region\` is not one of the supported area values | \`Arbitrary region values aren't allowed.\` |\
> \| \`email\` already belongs to a team — member of this or another org, or has a pending invitation here or elsewhere | \`User is already on a team.\` |\
> \| The resolved template is larger than the computer's disk (override or plan default) | \`Template size cannot exceed disk storage.\` |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 4632 | Bulk computer creation is not enabled for this team |\
> \| 4706 | No \`plan\_id\` supplied \*\*and\*\* no default computer plan configured |\
> \| 4202 | Invalid parameters, or the resolved computer plan does not exist for the organization |\
> \| 400 | Bad request (e.g. missing \`rows\`) |\
> \| 4710 | Permission required |\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`results\` | Object | Per-row outcome of the assignment. Keyed by row email — rows without an email use a synthetic \`(no email #N)\` key; each value carries \`invitation\`, \`machine\_id\`, \`disk\_size\`, \`os\`, and \`template\`. A rejected row carries an \`error\` string instead (see Per-row validation) |\
> \| \`summary\` | Object | Aggregate counts: \`total\` (rows processed), \`invalid\` (rows rejected by per-row validation), and \`assigned\` (computers assigned) |\
> \
> \### \*\*Request Body Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "plan\_id": 42,\
> &#x20; "dry\_run": true,\
> &#x20; "rows": \[\
> &#x20;   {\
> &#x20;     "email": "<user@example.com>",\
> &#x20;     "region": "europe",\
> &#x20;     "template\_name": "Design Template",\
> &#x20;     "disk\_size": "275",\
> &#x20;     "applications": \[\
> &#x20;       "Blender",\
> &#x20;       "Maya"\
> &#x20;     ]\
> &#x20;   },\
> &#x20;   {\
> &#x20;     "email": "<taken@example.com>",\
> &#x20;     "region": "europe"\
> &#x20;   },\
> &#x20;   {\
> &#x20;     "region": "europe",\
> &#x20;     "template\_name": "Design Template"\
> &#x20;   }\
> &#x20; ]\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "results": {\
> &#x20;       "<user@example.com>": {\
> &#x20;           "invitation": "created",\
> &#x20;           "machine\_id": 8085,\
> &#x20;           "disk\_size": 275,\
> &#x20;           "template": "assigned: Design Template"\
> &#x20;       },\
> &#x20;       "<taken@example.com>": {\
> &#x20;           "invitation": "skipped (already on a team)",\
> &#x20;           "machine\_id": null,\
> &#x20;           "disk\_size": null,\
> &#x20;           "template": "User is already on a team.",\
> &#x20;           "error": "User is already on a team."\
> &#x20;       },\
> &#x20;       "(no email #3)": {\
> &#x20;           "invitation": "skipped (no email)",\
> &#x20;           "machine\_id": 8086,\
> &#x20;           "disk\_size": 275,\
> &#x20;           "template": "assigned: Design Template"\
> &#x20;       }\
> &#x20;   },\
> &#x20;   "summary": {\
> &#x20;       "total": 3,\
> &#x20;       "invalid": 1,\
> &#x20;       "assigned": 2\
> &#x20;   },\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-06-08T11:58:57Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/bulk-create":{"post":{"summary":"Bulk Create & Assign Computers","responses":{"200":{"description":"Bulk computer assignment result","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"object","description":"Per-row outcome of the assignment. Each key is the row email; rows sent without an email are keyed with a synthetic `(no email #N)` placeholder (N is the 1-based row position). The value describes what happened for that row.","additionalProperties":{"type":"object","properties":{"invitation":{"type":"string","description":"Invitation outcome (e.g. `created`, `skipped (already member)`). Rows sent without an email report `skipped (no email)` — no user or invitation is created and the computer is left unassigned."},"machine_id":{"type":"integer","nullable":true,"description":"ID of the assigned computer; `null` when the row was not assigned"},"disk_size":{"type":"integer","nullable":true,"description":"Disk size (GB) of the assigned computer"},"os":{"type":"string","enum":["windows","linux"],"description":"Operating system applied to the row's computer. Echoes the row's `os` column; defaults to `windows` when the column is blank or invalid."},"template":{"type":"string","description":"Template/application assignment outcome (e.g. `assigned: Design Template`, `partial_assigned: Blender, Maya`)"},"error":{"type":"string","description":"Present only on invalid rows; the reason the row was not assigned"}}}},"summary":{"type":"object","description":"Aggregate counts of the assignment run","properties":{"total":{"type":"integer","description":"Total number of rows processed"},"invalid":{"type":"integer","description":"Number of rows rejected by per-row validation"},"assigned":{"type":"integer","description":"Number of computers assigned"}}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Bulk-creates and assigns computers to users for the authenticated organization from a list of rows. Each row maps a region/area, an optional template, optional applications to pre-install, and an optional disk size to a user (by `email`). `email` is **optional**: a row sent without an email creates the computer **unassigned** — no user and no invitation — so you can pre-provision computers and assign them to people later.\n\n> **Availability** > > This endpoint is available upon request for selected customers. Please > contact Vagon to enable bulk computer creation for your organization.\n\nThe computer plan is the supplied `plan_id`; when omitted, the organization's configured default computer plan is used. `4706` is returned **only** when neither is configured. If a plan id *is* resolved but does not exist for the organization, the request returns `4202` — resolved plans must belong to the organization (or be a global plan).\n\nSet `dry_run` to `true` to preview the outcome without making any changes (no computers are assigned, no invitations are created). The response shape is identical for dry runs and real runs.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `rows` | Array | Yes | List of assignment rows (see Row Fields) |\n| `plan_id` | Integer | No | Computer plan to assign. Falls back to the organization's configured default computer plan when omitted |\n| `dry_run` | Boolean | No | When `true`, preview only — no changes are persisted. Defaults to `false` |\n\n### **Row Fields**\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `email` | String | No | Email of the user to assign the computer to. Leave blank to create the computer unassigned (no user, no invitation) |\n| `os` | String | No | Operating system for the row's computer: `windows` or `linux`. Per-row — set it on each row independently. Blank or invalid values fall back to `windows`. |\n| `region` | String | No | Target area. Supported values: `europe`, `us_east`, `us_west`, `us_central`, `canada`, `south_america`, `south_africa`, `australia`, `south_asia`, `east_asia`, `south_east_asia`. Unknown values are rejected — see Per-row validation below |\n| `template_name` | String | No | Name of the template (silver image) to assign. Available values can be collected from [Get Images](https://docs.vagon.io/teams/reference/images#get-images) |\n| `applications` | Array | No | Application names to pre-install. Send values as an array of software names. Available values can be collected from [Get Software](https://docs.vagon.io/teams/reference/software#get-software) |\n| `disk_size` | String | No | Optional per-computer disk size override in GB. Supported values: `125`, `175`, `225`, `275`, `325`, `375`, `425`, `475`, `525`. Blank, zero, or non-positive values are ignored — the computer keeps its plan default. |\n\n### **Per-row validation**\n\nRows are validated independently — an invalid row is reported with an `error` message in its result entry and is **not** assigned (no invitation or computer is created for it), while valid rows in the same request are still processed. The validation applies in both `dry_run` and execute modes, so a preview surfaces every error before you commit.\n\n| Condition | `error` message |\n| --- | --- |\n| `region` is not one of the supported area values | `Arbitrary region values aren't allowed.` |\n| `email` already belongs to a team — member of this or another org, or has a pending invitation here or elsewhere | `User is already on a team.` |\n| The resolved template is larger than the computer's disk (override or plan default) | `Template size cannot exceed disk storage.` |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 4632 | Bulk computer creation is not enabled for this team |\n| 4706 | No `plan_id` supplied **and** no default computer plan configured |\n| 4202 | Invalid parameters, or the resolved computer plan does not exist for the organization |\n| 400 | Bad request (e.g. missing `rows`) |\n| 4710 | Permission required |\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `results` | Object | Per-row outcome of the assignment. Keyed by row email — rows without an email use a synthetic `(no email #N)` key; each value carries `invitation`, `machine_id`, `disk_size`, `os`, and `template`. A rejected row carries an `error` string instead (see Per-row validation) |\n| `summary` | Object | Aggregate counts: `total` (rows processed), `invalid` (rows rejected by per-row validation), and `assigned` (computers assigned) |\n\n### **Request Body Example**\n\n``` json\n{\n  \"plan_id\": 42,\n  \"dry_run\": true,\n  \"rows\": [\n    {\n      \"email\": \"user@example.com\",\n      \"region\": \"europe\",\n      \"template_name\": \"Design Template\",\n      \"disk_size\": \"275\",\n      \"applications\": [\n        \"Blender\",\n        \"Maya\"\n      ]\n    },\n    {\n      \"email\": \"taken@example.com\",\n      \"region\": \"europe\"\n    },\n    {\n      \"region\": \"europe\",\n      \"template_name\": \"Design Template\"\n    }\n  ]\n}\n\n ```\n\n### **Response Example**\n\n``` json\n{\n    \"results\": {\n        \"user@example.com\": {\n            \"invitation\": \"created\",\n            \"machine_id\": 8085,\n            \"disk_size\": 275,\n            \"template\": \"assigned: Design Template\"\n        },\n        \"taken@example.com\": {\n            \"invitation\": \"skipped (already on a team)\",\n            \"machine_id\": null,\n            \"disk_size\": null,\n            \"template\": \"User is already on a team.\",\n            \"error\": \"User is already on a team.\"\n        },\n        \"(no email #3)\": {\n            \"invitation\": \"skipped (no email)\",\n            \"machine_id\": 8086,\n            \"disk_size\": 275,\n            \"template\": \"assigned: Design Template\"\n        }\n    },\n    \"summary\": {\n        \"total\": 3,\n        \"invalid\": 1,\n        \"assigned\": 2\n    },\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-06-08T11:58:57Z\"\n}\n\n ```","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["rows"],"properties":{"plan_id":{"type":"integer","description":"Computer plan to assign; falls back to the org default when omitted"},"dry_run":{"type":"boolean","description":"When true, preview only — no changes are persisted"},"rows":{"type":"array","description":"List of assignment rows","items":{"type":"object","properties":{"email":{"type":"string","description":"Email of the user to assign the computer to. Optional — omit or leave blank to create the computer unassigned (no user, no invitation)."},"region":{"type":"string","enum":["europe","us_east","us_west","us_central","canada","south_america","south_africa","australia","south_asia","east_asia","south_east_asia"],"description":"Area value. Unknown values are rejected"},"template_name":{"type":"string","description":"Template name. Available values can be collected from https://docs.vagon.io/teams/reference/images#get-images"},"applications":{"type":"array","description":"Application names. Available values can be collected from https://docs.vagon.io/teams/reference/software#get-software","items":{"type":"string"}},"disk_size":{"type":"string","enum":["125","175","225","275","325","375","425","475","525"],"description":"Optional per-computer disk size override in GB. Blank, zero, or non-positive values are ignored."}}}}}}}}}}}},"components":{"schemas":{"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Get Machine Sessions

> Retrieves all sessions for a specific machine. Sessions are ordered by start time in descending order, most recent first.\
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | Integer | Machine ID |\
> \
> \### Response Fields\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`sessions\` | Array | Array of session objects |\
> \| \`sessions\[].id\` | String | Session ID |\
> \| \`sessions\[].type\` | String | Always "machine\_session" |\
> \| \`sessions\[].attributes.start\_at\` | String | Session start time (ISO 8601 format) |\
> \| \`sessions\[].attributes.end\_at\` | String | Session end time (ISO 8601 format). null if still active |\
> \| \`sessions\[].attributes.duration\` | Integer | Session duration in minutes |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### Response Example\
> \
> \`\`\` json\
> {\
> &#x20;   "sessions": \[\
> &#x20;       {\
> &#x20;           "id": "2000",\
> &#x20;           "type": "machine\_session",\
> &#x20;           "attributes": {\
> &#x20;               "start\_at": "2026-01-23T11:02:41.902Z",\
> &#x20;               "end\_at": "2026-01-23T11:07:51.115Z",\
> &#x20;               "duration": 6\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "1999",\
> &#x20;           "type": "machine\_session",\
> &#x20;           "attributes": {\
> &#x20;               "start\_at": "2026-01-21T22:57:57.450Z",\
> &#x20;               "end\_at": "2026-01-21T22:59:58.408Z",\
> &#x20;               "duration": 3\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T11:55:58Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/sessions":{"get":{"summary":"Get Machine Sessions","responses":{"200":{"description":"List of machine sessions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MachineSessionsResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Retrieves all sessions for a specific machine. Sessions are ordered by start time in descending order, most recent first.\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id` | Integer | Machine ID |\n\n### Response Fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `sessions` | Array | Array of session objects |\n| `sessions[].id` | String | Session ID |\n| `sessions[].type` | String | Always \"machine_session\" |\n| `sessions[].attributes.start_at` | String | Session start time (ISO 8601 format) |\n| `sessions[].attributes.end_at` | String | Session end time (ISO 8601 format). null if still active |\n| `sessions[].attributes.duration` | Integer | Session duration in minutes |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### Response Example\n\n``` json\n{\n    \"sessions\": [\n        {\n            \"id\": \"2000\",\n            \"type\": \"machine_session\",\n            \"attributes\": {\n                \"start_at\": \"2026-01-23T11:02:41.902Z\",\n                \"end_at\": \"2026-01-23T11:07:51.115Z\",\n                \"duration\": 6\n            }\n        },\n        {\n            \"id\": \"1999\",\n            \"type\": \"machine_session\",\n            \"attributes\": {\n                \"start_at\": \"2026-01-21T22:57:57.450Z\",\n                \"end_at\": \"2026-01-21T22:59:58.408Z\",\n                \"duration\": 3\n            }\n        }\n    ],\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T11:55:58Z\"\n}\n\n ```"}}},"components":{"schemas":{"MachineSessionsResponse":{"type":"object","properties":{"sessions":{"type":"array","items":{"$ref":"#/components/schemas/MachineSession"}},"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"MachineSession":{"type":"object","description":"Machine session record","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/MachineSessionAttributes"}}},"MachineSessionAttributes":{"type":"object","properties":{"start_at":{"type":"string","format":"date-time","description":"Session start timestamp"},"end_at":{"type":"string","format":"date-time","nullable":true,"description":"Session end timestamp (null if session is ongoing)"},"duration":{"type":"integer","description":"Session duration in minutes (0 if session is ongoing)"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## List Machine Tasks

> Returns all non-deleted tasks for the machine, ordered by \`created\_at\` descending.\
> \
> Each task maps a \`uid\` (folder name) to a specific Desktop source path and snapshot destination on the Windows machine. The currently active task determines which folder is monitored for snapshots when the machine starts.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Machine ID |\
> \
> \### Query Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`page\` | Integer | No | Page number (default: 1) |\
> \| \`per\_page\` | Integer | No | Results per page (default: Kaminari default) |\
> \
> \### Response Fields\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`tasks\` | Array | Array of task objects |\
> \| \`tasks\[].id\` | String | Task ID |\
> \| \`tasks\[].type\` | String | Always \`"task"\` |\
> \| \`tasks\[].attributes.uid\` | String | Task identifier (Desktop folder name) |\
> \| \`tasks\[].attributes.status\` | String | \`"active"\` or \`"inactive"\` |\
> \| \`tasks\[].attributes.source\_path\` | String | Full Windows path monitored for snapshots |\
> \| \`tasks\[].attributes.snapshot\_destination\` | String | Full Windows path where snapshots are stored |\
> \| \`tasks\[].attributes.folder\_size\` | Integer or null | Cumulative size (bytes) of the task's folder, recorded when the machine last stopped. \`null\` until first recorded. |\
> \| \`tasks\[].attributes.created\_at\` | String | Task creation time (ISO 8601) |\
> \| \`count\` | Integer | Total number of tasks returned |\
> \| \`page\` | Integer | Current page number |\
> \| \`next\_page\` | Integer or null | Next page number (null if no more pages) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \
> \### Response Example\
> \
> \`\`\`json\
> {\
> &#x20; "tasks": \[\
> &#x20;   {\
> &#x20;     "id": "18",\
> &#x20;     "type": "task",\
> &#x20;     "attributes": {\
> &#x20;       "uid": "Outputs",\
> &#x20;       "created\_at": "2025-12-02T09:50:37.244Z",\
> &#x20;       "status": "active",\
> &#x20;       "source\_path": "C:\\\Users\\\Administrator\\\Desktop\\\Outputs",\
> &#x20;       "snapshot\_destination": "V:\\\Outputs",\
> &#x20;       "folder\_size": 713\
> &#x20;     }\
> &#x20;   }\
> &#x20; ],\
> &#x20; "count": 1,\
> &#x20; "page": 1,\
> &#x20; "next\_page": null,\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-04-15T11:11:27Z"\
> }\
> \`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/tasks":{"get":{"summary":"List Machine Tasks","responses":{"200":{"description":"List of tasks for the machine","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTasksResponse"}}}},"404":{"description":"Machine not found or does not belong to the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Returns all non-deleted tasks for the machine, ordered by `created_at` descending.\n\nEach task maps a `uid` (folder name) to a specific Desktop source path and snapshot destination on the Windows machine. The currently active task determines which folder is monitored for snapshots when the machine starts.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Machine ID |\n\n### Query Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `page` | Integer | No | Page number (default: 1) |\n| `per_page` | Integer | No | Results per page (default: Kaminari default) |\n\n### Response Fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `tasks` | Array | Array of task objects |\n| `tasks[].id` | String | Task ID |\n| `tasks[].type` | String | Always `\"task\"` |\n| `tasks[].attributes.uid` | String | Task identifier (Desktop folder name) |\n| `tasks[].attributes.status` | String | `\"active\"` or `\"inactive\"` |\n| `tasks[].attributes.source_path` | String | Full Windows path monitored for snapshots |\n| `tasks[].attributes.snapshot_destination` | String | Full Windows path where snapshots are stored |\n| `tasks[].attributes.folder_size` | Integer or null | Cumulative size (bytes) of the task's folder, recorded when the machine last stopped. `null` until first recorded. |\n| `tasks[].attributes.created_at` | String | Task creation time (ISO 8601) |\n| `count` | Integer | Total number of tasks returned |\n| `page` | Integer | Current page number |\n| `next_page` | Integer or null | Next page number (null if no more pages) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n\n### Response Example\n\n```json\n{\n  \"tasks\": [\n    {\n      \"id\": \"18\",\n      \"type\": \"task\",\n      \"attributes\": {\n        \"uid\": \"Outputs\",\n        \"created_at\": \"2025-12-02T09:50:37.244Z\",\n        \"status\": \"active\",\n        \"source_path\": \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\Outputs\",\n        \"snapshot_destination\": \"V:\\\\Outputs\",\n        \"folder_size\": 713\n      }\n    }\n  ],\n  \"count\": 1,\n  \"page\": 1,\n  \"next_page\": null,\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-04-15T11:11:27Z\"\n}\n```"}}},"components":{"schemas":{"ListTasksResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"count":{"type":"integer","description":"Total number of tasks returned"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Task":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/TaskAttributes"}}},"TaskAttributes":{"type":"object","properties":{"uid":{"type":"string","description":"Task identifier used as the Desktop folder name"},"status":{"type":"string","enum":["active","inactive"],"description":"Task status"},"source_path":{"type":"string","description":"Full Windows path monitored for snapshots"},"snapshot_destination":{"type":"string","description":"Full Windows path where snapshots are stored. For the default \"Outputs\" task this is `V:\\Outputs`; for all other tasks it is `V:\\{uid}-snapshots`."},"folder_size":{"type":"integer","nullable":true,"description":"Cumulative size in bytes of the task's corresponding folder, recorded when the machine last stopped gracefully. `null` until the machine stops for the first time with an active task and a matching folder."},"created_at":{"type":"string","format":"date-time","description":"Task creation time (ISO 8601)"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Create or Activate Machine Task

> Creates or selects a task by UID and sets it as the active snapshot source for the seat. Any previously active task is automatically deactivated.\
> \
> The endpoint is idempotent with respect to the \`result\` field — three distinct outcomes are possible:\
> \
> \| Scenario | \`result\` |\
> \| --- | --- |\
> \| New task created | \`"created"\` |\
> \| Existing inactive task re-activated | \`"reactivated"\` |\
> \| Requested task is already active (no-op) | \`"already\_active"\` |\
> \
> \*\*UID rules:\*\* must be non-empty, at most 255 characters, and must not contain any Windows-reserved characters: \`\ / : \* ? " < > |\`\
> \
> \*\*Deleted task names cannot be reused\*\* — if a task with the given UID was previously deleted, the request returns \`4217\`. The only exception is a machine reset: task names deleted as part of a reset become available again after the reset completes.\
> \
> \*\*Backup must be enabled\*\* — the seat's backup setting must be active, otherwise returns \`4218\`.\
> \
> \*\*Machine must be \`off\`\*\* — tasks cannot be changed while the machine is running (returns \`4206\`).\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Machine ID |\
> \
> \### Request Body\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`uid\`\\\* | String | Yes | Task identifier used as the Desktop folder name. Must be non-empty, ≤ 255 characters, and free of Windows-reserved characters (\`\ / : \* ? " < > |\`). |\
> \
> \### Response Fields\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`task\` | Object | The created or activated task object |\
> \| \`task.id\` | String | Task ID |\
> \| \`task.type\` | String | Always \`"task"\` |\
> \| \`task.attributes.uid\` | String | Task identifier |\
> \| \`task.attributes.status\` | String | Always \`"active"\` after this call |\
> \| \`task.attributes.source\_path\` | String | Full Windows path monitored for snapshots |\
> \| \`task.attributes.snapshot\_destination\` | String | Full Windows path where snapshots are stored |\
> \| \`task.attributes.folder\_size\` | Integer or null | Cumulative size (bytes) of the task's folder. \`null\` until first recorded. |\
> \| \`task.attributes.created\_at\` | String | Task creation time (ISO 8601) |\
> \| \`result\` | String | Outcome: \`"created"\`, \`"reactivated"\`, or \`"already\_active"\` |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \
> \### Response Examples\
> \
> \*\*result: "created"\*\*\
> \
> \`\`\`json\
> {\
> &#x20; "task": {\
> &#x20;   "id": "22",\
> &#x20;   "type": "task",\
> &#x20;   "attributes": {\
> &#x20;     "uid": "task-012",\
> &#x20;     "created\_at": "2026-04-15T11:16:44.534Z",\
> &#x20;     "status": "active",\
> &#x20;     "source\_path": "C:\\\Users\\\Administrator\\\Desktop\\\task-012",\
> &#x20;     "snapshot\_destination": "V:\\\task-012-snapshots",\
> &#x20;     "folder\_size": null\
> &#x20;   }\
> &#x20; },\
> &#x20; "result": "created",\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-04-15T11:16:44Z"\
> }\
> \`\`\`\
> \
> \*\*result: "reactivated"\*\*\
> \
> \`\`\`json\
> {\
> &#x20; "task": {\
> &#x20;   "id": "18",\
> &#x20;   "type": "task",\
> &#x20;   "attributes": {\
> &#x20;     "uid": "Outputs",\
> &#x20;     "created\_at": "2025-12-02T09:50:37.244Z",\
> &#x20;     "status": "active",\
> &#x20;     "source\_path": "C:\\\Users\\\Administrator\\\Desktop\\\Outputs",\
> &#x20;     "snapshot\_destination": "V:\\\Outputs",\
> &#x20;     "folder\_size": 713\
> &#x20;   }\
> &#x20; },\
> &#x20; "result": "reactivated",\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-04-15T11:17:20Z"\
> }\
> \`\`\`\
> \
> \*\*result: "already\_active"\*\*\
> \
> \`\`\`json\
> {\
> &#x20; "task": {\
> &#x20;   "id": "22",\
> &#x20;   "type": "task",\
> &#x20;   "attributes": {\
> &#x20;     "uid": "task-012",\
> &#x20;     "created\_at": "2026-04-15T11:16:44.534Z",\
> &#x20;     "status": "active",\
> &#x20;     "source\_path": "C:\\\Users\\\Administrator\\\Desktop\\\task-012",\
> &#x20;     "snapshot\_destination": "V:\\\task-012-snapshots",\
> &#x20;     "folder\_size": null\
> &#x20;   }\
> &#x20; },\
> &#x20; "result": "already\_active",\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-04-15T11:17:03Z"\
> }\
> \`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/tasks":{"post":{"summary":"Create or Activate Machine Task","responses":{"200":{"description":"Task created, reactivated, or already active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskActionResponse"}}}},"404":{"description":"Machine not found or does not belong to the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4206":{"description":"Machine is not off — tasks can only be modified when the machine is stopped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4206Response"}}}},"4216":{"description":"Invalid task UID (empty, exceeds 255 characters, or contains reserved characters)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4216Response"}}}},"4217":{"description":"Task UID was previously deleted and cannot be reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4217Response"}}}},"4218":{"description":"Backup is not enabled for this seat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4218Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Creates or selects a task by UID and sets it as the active snapshot source for the seat. Any previously active task is automatically deactivated.\n\nThe endpoint is idempotent with respect to the `result` field — three distinct outcomes are possible:\n\n| Scenario | `result` |\n| --- | --- |\n| New task created | `\"created\"` |\n| Existing inactive task re-activated | `\"reactivated\"` |\n| Requested task is already active (no-op) | `\"already_active\"` |\n\n**UID rules:** must be non-empty, at most 255 characters, and must not contain any Windows-reserved characters: `\\ / : * ? \" < > |`\n\n**Deleted task names cannot be reused** — if a task with the given UID was previously deleted, the request returns `4217`. The only exception is a machine reset: task names deleted as part of a reset become available again after the reset completes.\n\n**Backup must be enabled** — the seat's backup setting must be active, otherwise returns `4218`.\n\n**Machine must be `off`** — tasks cannot be changed while the machine is running (returns `4206`).\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Machine ID |\n\n### Request Body\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `uid`\\* | String | Yes | Task identifier used as the Desktop folder name. Must be non-empty, ≤ 255 characters, and free of Windows-reserved characters (`\\ / : * ? \" < > |`). |\n\n### Response Fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `task` | Object | The created or activated task object |\n| `task.id` | String | Task ID |\n| `task.type` | String | Always `\"task\"` |\n| `task.attributes.uid` | String | Task identifier |\n| `task.attributes.status` | String | Always `\"active\"` after this call |\n| `task.attributes.source_path` | String | Full Windows path monitored for snapshots |\n| `task.attributes.snapshot_destination` | String | Full Windows path where snapshots are stored |\n| `task.attributes.folder_size` | Integer or null | Cumulative size (bytes) of the task's folder. `null` until first recorded. |\n| `task.attributes.created_at` | String | Task creation time (ISO 8601) |\n| `result` | String | Outcome: `\"created\"`, `\"reactivated\"`, or `\"already_active\"` |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n\n### Response Examples\n\n**result: \"created\"**\n\n```json\n{\n  \"task\": {\n    \"id\": \"22\",\n    \"type\": \"task\",\n    \"attributes\": {\n      \"uid\": \"task-012\",\n      \"created_at\": \"2026-04-15T11:16:44.534Z\",\n      \"status\": \"active\",\n      \"source_path\": \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\task-012\",\n      \"snapshot_destination\": \"V:\\\\task-012-snapshots\",\n      \"folder_size\": null\n    }\n  },\n  \"result\": \"created\",\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-04-15T11:16:44Z\"\n}\n```\n\n**result: \"reactivated\"**\n\n```json\n{\n  \"task\": {\n    \"id\": \"18\",\n    \"type\": \"task\",\n    \"attributes\": {\n      \"uid\": \"Outputs\",\n      \"created_at\": \"2025-12-02T09:50:37.244Z\",\n      \"status\": \"active\",\n      \"source_path\": \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\Outputs\",\n      \"snapshot_destination\": \"V:\\\\Outputs\",\n      \"folder_size\": 713\n    }\n  },\n  \"result\": \"reactivated\",\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-04-15T11:17:20Z\"\n}\n```\n\n**result: \"already_active\"**\n\n```json\n{\n  \"task\": {\n    \"id\": \"22\",\n    \"type\": \"task\",\n    \"attributes\": {\n      \"uid\": \"task-012\",\n      \"created_at\": \"2026-04-15T11:16:44.534Z\",\n      \"status\": \"active\",\n      \"source_path\": \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\task-012\",\n      \"snapshot_destination\": \"V:\\\\task-012-snapshots\",\n      \"folder_size\": null\n    }\n  },\n  \"result\": \"already_active\",\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-04-15T11:17:03Z\"\n}\n```","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["uid"],"properties":{"uid":{"type":"string","description":"Task identifier used as the Desktop folder name. Must not contain Windows-reserved characters.","maxLength":255}}}}}}}}},"components":{"schemas":{"TaskActionResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"result":{"type":"string","enum":["created","reactivated","already_active","deleted"],"description":"Outcome of the operation"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Task":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/TaskAttributes"}}},"TaskAttributes":{"type":"object","properties":{"uid":{"type":"string","description":"Task identifier used as the Desktop folder name"},"status":{"type":"string","enum":["active","inactive"],"description":"Task status"},"source_path":{"type":"string","description":"Full Windows path monitored for snapshots"},"snapshot_destination":{"type":"string","description":"Full Windows path where snapshots are stored. For the default \"Outputs\" task this is `V:\\Outputs`; for all other tasks it is `V:\\{uid}-snapshots`."},"folder_size":{"type":"integer","nullable":true,"description":"Cumulative size in bytes of the task's corresponding folder, recorded when the machine last stopped gracefully. `null` until the machine stops for the first time with an active task and a matching folder."},"created_at":{"type":"string","format":"date-time","description":"Task creation time (ISO 8601)"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error4206Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4216Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4217Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4218Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Delete Machine Task

> Deletes a task along with its Desktop source folder and its snapshot folder in the Vagon Files drive. Deletion permanently removes the task record and its files.\
> \
> \*\*Task UID/name reuse is reset-aware.\*\* A deleted task UID cannot be reused in a future \`POST /machines/{id}/tasks\` call unless the deleted record predates the machine's last reset (\`machine.last\_reset\_at\`). In practice, after a machine reset removes all non-default tasks and their files, those task UIDs become available again.\
> \
> \*\*The default "Outputs" task cannot be deleted\*\* — attempting to delete the task with \`uid: "Outputs"\` returns \`4219\`.\
> \
> If the deleted task was active, the default "Outputs" task is automatically activated (or created) before the response is returned.\
> \
> \*\*Machine must be \`off\`\*\* — tasks cannot be changed while the machine is running (returns \`4206\`).\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Machine ID |\
> \| \`task\_id\`\\\* | Integer | Task ID |\
> \
> \### Response Fields\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`task\` | Object | The deleted task object |\
> \| \`task.attributes.folder\_size\` | Integer or null | Cumulative folder size (bytes) at last stop. \`null\` if never recorded. |\
> \| \`result\` | String | Always \`"deleted"\` |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \
> \### Response Example\
> \
> \`\`\`json\
> {\
> &#x20; "task": {\
> &#x20;   "id": "21",\
> &#x20;   "type": "task",\
> &#x20;   "attributes": {\
> &#x20;     "uid": "task-02",\
> &#x20;     "created\_at": "2026-04-15T11:11:35.142Z",\
> &#x20;     "status": "inactive",\
> &#x20;     "source\_path": "C:\\\Users\\\Administrator\\\Desktop\\\task-02",\
> &#x20;     "snapshot\_destination": "V:\\\task-02-snapshots",\
> &#x20;     "folder\_size": null\
> &#x20;   }\
> &#x20; },\
> &#x20; "result": "deleted",\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-04-15T11:11:57Z"\
> }\
> \`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/tasks/{task_id}":{"delete":{"summary":"Delete Machine Task","responses":{"200":{"description":"Task deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskActionResponse"}}}},"404":{"description":"Task not found, already deleted, or belongs to a different seat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4206":{"description":"Machine is not off — tasks can only be modified when the machine is stopped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4206Response"}}}},"4219":{"description":"Cannot delete the default \"Outputs\" task","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4219Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Machines"],"description":"Deletes a task along with its Desktop source folder and its snapshot folder in the Vagon Files drive. Deletion permanently removes the task record and its files.\n\n**Task UID/name reuse is reset-aware.** A deleted task UID cannot be reused in a future `POST /machines/{id}/tasks` call unless the deleted record predates the machine's last reset (`machine.last_reset_at`). In practice, after a machine reset removes all non-default tasks and their files, those task UIDs become available again.\n\n**The default \"Outputs\" task cannot be deleted** — attempting to delete the task with `uid: \"Outputs\"` returns `4219`.\n\nIf the deleted task was active, the default \"Outputs\" task is automatically activated (or created) before the response is returned.\n\n**Machine must be `off`** — tasks cannot be changed while the machine is running (returns `4206`).\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Machine ID |\n| `task_id`\\* | Integer | Task ID |\n\n### Response Fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `task` | Object | The deleted task object |\n| `task.attributes.folder_size` | Integer or null | Cumulative folder size (bytes) at last stop. `null` if never recorded. |\n| `result` | String | Always `\"deleted\"` |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n\n### Response Example\n\n```json\n{\n  \"task\": {\n    \"id\": \"21\",\n    \"type\": \"task\",\n    \"attributes\": {\n      \"uid\": \"task-02\",\n      \"created_at\": \"2026-04-15T11:11:35.142Z\",\n      \"status\": \"inactive\",\n      \"source_path\": \"C:\\\\Users\\\\Administrator\\\\Desktop\\\\task-02\",\n      \"snapshot_destination\": \"V:\\\\task-02-snapshots\",\n      \"folder_size\": null\n    }\n  },\n  \"result\": \"deleted\",\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-04-15T11:11:57Z\"\n}\n```"}}},"components":{"schemas":{"TaskActionResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"result":{"type":"string","enum":["created","reactivated","already_active","deleted"],"description":"Outcome of the operation"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Task":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/TaskAttributes"}}},"TaskAttributes":{"type":"object","properties":{"uid":{"type":"string","description":"Task identifier used as the Desktop folder name"},"status":{"type":"string","enum":["active","inactive"],"description":"Task status"},"source_path":{"type":"string","description":"Full Windows path monitored for snapshots"},"snapshot_destination":{"type":"string","description":"Full Windows path where snapshots are stored. For the default \"Outputs\" task this is `V:\\Outputs`; for all other tasks it is `V:\\{uid}-snapshots`."},"folder_size":{"type":"integer","nullable":true,"description":"Cumulative size in bytes of the task's corresponding folder, recorded when the machine last stopped gracefully. `null` until the machine stops for the first time with an active task and a matching folder."},"created_at":{"type":"string","format":"date-time","description":"Task creation time (ISO 8601)"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error4206Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4219Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````


# Files

## List Files & Folders in Computer

> Lists the file system content of a running machine.\
> \
> This endpoint allows you to browse the machine's file system remotely. It returns files and folders in the specified path.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Path Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | Machine ID |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`path\` | String | Yes | Folder path to list. Must be Windows format with escaped backslashes (e.g., "C:\\\Users", "C:\\\Users\\\Documents") |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (machine is not running) |\
> \| 404 | Machine not found or does not belong to organization |\
> \| 4710 | Permission required |\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`content\` | Array | Array of file system content objects |\
> \| \`content\[].path\` | String | Full path of the file or folder |\
> \| \`content\[].name\` | String | File or folder name |\
> \| \`content\[].is\_directory\` | Boolean | true if directory, false if file |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Request Body Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "path": "C:\\\Users"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "content": \[\
> &#x20;       {\
> &#x20;           "path": "C:\\\Users\\\Administrator",\
> &#x20;           "name": "Administrator",\
> &#x20;           "is\_directory": true\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "path": "C:\\\Users\\\Public",\
> &#x20;           "name": "Public",\
> &#x20;           "is\_directory": true\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T11:55:10Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/list-content":{"post":{"summary":"List Files & Folders in Computer","responses":{"200":{"description":"File system content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContentResponse"}}}},"400":{"description":"Bad request (machine is not running)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Lists the file system content of a running machine.\n\nThis endpoint allows you to browse the machine's file system remotely. It returns files and folders in the specified path.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Path Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | Machine ID |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `path` | String | Yes | Folder path to list. Must be Windows format with escaped backslashes (e.g., \"C:\\\\Users\", \"C:\\\\Users\\\\Documents\") |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (machine is not running) |\n| 404 | Machine not found or does not belong to organization |\n| 4710 | Permission required |\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `content` | Array | Array of file system content objects |\n| `content[].path` | String | Full path of the file or folder |\n| `content[].name` | String | File or folder name |\n| `content[].is_directory` | Boolean | true if directory, false if file |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Request Body Example**\n\n``` json\n{\n  \"path\": \"C:\\\\Users\"\n}\n\n ```\n\n### **Response Example**\n\n``` json\n{\n    \"content\": [\n        {\n            \"path\": \"C:\\\\Users\\\\Administrator\",\n            \"name\": \"Administrator\",\n            \"is_directory\": true\n        },\n        {\n            \"path\": \"C:\\\\Users\\\\Public\",\n            \"name\": \"Public\",\n            \"is_directory\": true\n        }\n    ],\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T11:55:10Z\"\n}\n\n ```","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string"}}}}}}}}},"components":{"schemas":{"ListContentResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"content":{"type":"array","description":"List of files and directories at the specified path","items":{"$ref":"#/components/schemas/FileSystemItem"}}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"FileSystemItem":{"type":"object","description":"File or directory item from machine file system","properties":{"path":{"type":"string","description":"Full path to the file or directory"},"name":{"type":"string","description":"Name of the file or directory"},"is_directory":{"type":"boolean","description":"True if this item is a directory, false if it's a file"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## List Shared Files & Folders in Vagon Files

> Lists the files and folders in Organization Shared Folder.\
> \
> This endpoint lists files stored in the organization's shared storage. These files are accessible to all organization members.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Query Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`parent\_id\` | Integer | Parent folder ID. 0 = root folder (organization's shared root folder) |\
> \| \`page\` | Integer | Page number. Default: 1 |\
> \| \`per\_page\` | Integer | Records per page. Default: 20 |\
> \| \`q\` | String | Search query. Searches by file/directory name |\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Parent folder not found |\
> \| 4710 | Permission required |\
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`files\` | Array | Array of file/folder objects |\
> \| \`files\[].id\` | String | File/folder ID |\
> \| \`files\[].type\` | String | Always "file" |\
> \| \`files\[].attributes.name\` | String | File or folder name |\
> \| \`files\[].attributes.size\` | Integer | File size in bytes. 0 for directories |\
> \| \`files\[].attributes.content\_type\` | String | MIME type (e.g., "image/png") or "directory" |\
> \| \`files\[].attributes.region\` | String | AWS region where file is stored |\
> \| \`files\[].attributes.status\` | String | File status (e.g., "upload\_completed") |\
> \| \`files\[].attributes.object\_type\` | String | Type: "file", "directory", or "root" |\
> \| \`files\[].attributes.path\` | String | Full path of the file/folder. null for some files |\
> \| \`files\[].attributes.parent\_id\` | Integer | Parent folder ID |\
> \| \`files\[].attributes.last\_modified\_date\` | String | ISO 8601 timestamp of last modification |\
> \| \`files\[].attributes.file\_storage\_size\` | Integer | Total file storage size (in bytes). null for non-root |\
> \| \`files\[].attributes.file\_storage\_usage\` | Integer | Used file storage (in bytes). null for non-root |\
> \| \`files\[].attributes.user\` | Object | User who owns the file (null if none) |\
> \| \`files\[].attributes.user.id\` | String | User UUID |\
> \| \`files\[].attributes.user.type\` | String | Always "user" |\
> \| \`files\[].attributes.user.attributes.email\` | String | User email |\
> \| \`files\[].attributes.user.attributes.name\` | String | User name |\
> \| \`files\[].attributes.machine\_id\` | Integer | Machine ID the file belongs to (null for organization shared storage) |\
> \| \`current\` | Object | Current directory object (same structure as file objects). null if at root |\
> \| \`count\` | Integer | Total number of files/folders in current directory |\
> \| \`page\` | Integer | Current page number |\
> \| \`next\_page\` | Integer | Next page number. null if last page |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### Response Example\
> \
> \`\`\` json\
> {\
> &#x20;   "files": \[\
> &#x20;       {\
> &#x20;           "id": "18093",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "example.zip",\
> &#x20;               "size": 0,\
> &#x20;               "content\_type": "directory",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "directory",\
> &#x20;               "path": "/example.zip",\
> &#x20;               "parent\_id": 5122,\
> &#x20;               "last\_modified\_date": null,\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": null,\
> &#x20;               "machine\_id": null\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "18088",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "Project Folder",\
> &#x20;               "size": 0,\
> &#x20;               "content\_type": "directory",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "directory",\
> &#x20;               "path": "/Project Folder",\
> &#x20;               "parent\_id": 5122,\
> &#x20;               "last\_modified\_date": null,\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": null,\
> &#x20;               "machine\_id": null\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "current": {\
> &#x20;       "id": "5122",\
> &#x20;       "type": "file",\
> &#x20;       "attributes": {\
> &#x20;           "name": "Teams Shared Folder",\
> &#x20;           "size": 0,\
> &#x20;           "content\_type": "directory",\
> &#x20;           "region": "dublin",\
> &#x20;           "status": "upload\_completed",\
> &#x20;           "object\_type": "root",\
> &#x20;           "path": null,\
> &#x20;           "parent\_id": null,\
> &#x20;           "last\_modified\_date": "2026-02-04T12:07:59.204Z",\
> &#x20;           "file\_storage\_size": 26843545600,\
> &#x20;           "file\_storage\_usage": 0,\
> &#x20;           "user": null,\
> &#x20;           "machine\_id": null\
> &#x20;       }\
> &#x20;   },\
> &#x20;   "count": 2,\
> &#x20;   "page": 1,\
> &#x20;   "next\_page": null,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-05T10:17:46Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files":{"get":{"summary":"List Shared Files & Folders in Vagon Files","parameters":[{"name":"parent_id","in":"query","description":"(Optional) Parent folder ID. 0 = root folder","schema":{"type":"string"}},{"name":"page","in":"query","description":"(Optional) Page number. Default: 1","schema":{"type":"integer"}},{"name":"per_page","in":"query","description":"(Optional) Records per page. Default: 20","schema":{"type":"integer"}},{"name":"q","in":"query","description":"(Optional) Search by file name","schema":{"type":"string"}}],"responses":{"200":{"description":"List of files and folders","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListFilesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Parent folder not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Lists the files and folders in Organization Shared Folder.\n\nThis endpoint lists files stored in the organization's shared storage. These files are accessible to all organization members.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Query Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `parent_id` | Integer | Parent folder ID. 0 = root folder (organization's shared root folder) |\n| `page` | Integer | Page number. Default: 1 |\n| `per_page` | Integer | Records per page. Default: 20 |\n| `q` | String | Search query. Searches by file/directory name |\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Parent folder not found |\n| 4710 | Permission required |\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `files` | Array | Array of file/folder objects |\n| `files[].id` | String | File/folder ID |\n| `files[].type` | String | Always \"file\" |\n| `files[].attributes.name` | String | File or folder name |\n| `files[].attributes.size` | Integer | File size in bytes. 0 for directories |\n| `files[].attributes.content_type` | String | MIME type (e.g., \"image/png\") or \"directory\" |\n| `files[].attributes.region` | String | AWS region where file is stored |\n| `files[].attributes.status` | String | File status (e.g., \"upload_completed\") |\n| `files[].attributes.object_type` | String | Type: \"file\", \"directory\", or \"root\" |\n| `files[].attributes.path` | String | Full path of the file/folder. null for some files |\n| `files[].attributes.parent_id` | Integer | Parent folder ID |\n| `files[].attributes.last_modified_date` | String | ISO 8601 timestamp of last modification |\n| `files[].attributes.file_storage_size` | Integer | Total file storage size (in bytes). null for non-root |\n| `files[].attributes.file_storage_usage` | Integer | Used file storage (in bytes). null for non-root |\n| `files[].attributes.user` | Object | User who owns the file (null if none) |\n| `files[].attributes.user.id` | String | User UUID |\n| `files[].attributes.user.type` | String | Always \"user\" |\n| `files[].attributes.user.attributes.email` | String | User email |\n| `files[].attributes.user.attributes.name` | String | User name |\n| `files[].attributes.machine_id` | Integer | Machine ID the file belongs to (null for organization shared storage) |\n| `current` | Object | Current directory object (same structure as file objects). null if at root |\n| `count` | Integer | Total number of files/folders in current directory |\n| `page` | Integer | Current page number |\n| `next_page` | Integer | Next page number. null if last page |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### Response Example\n\n``` json\n{\n    \"files\": [\n        {\n            \"id\": \"18093\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"example.zip\",\n                \"size\": 0,\n                \"content_type\": \"directory\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"directory\",\n                \"path\": \"/example.zip\",\n                \"parent_id\": 5122,\n                \"last_modified_date\": null,\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": null,\n                \"machine_id\": null\n            }\n        },\n        {\n            \"id\": \"18088\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"Project Folder\",\n                \"size\": 0,\n                \"content_type\": \"directory\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"directory\",\n                \"path\": \"/Project Folder\",\n                \"parent_id\": 5122,\n                \"last_modified_date\": null,\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": null,\n                \"machine_id\": null\n            }\n        }\n    ],\n    \"current\": {\n        \"id\": \"5122\",\n        \"type\": \"file\",\n        \"attributes\": {\n            \"name\": \"Teams Shared Folder\",\n            \"size\": 0,\n            \"content_type\": \"directory\",\n            \"region\": \"dublin\",\n            \"status\": \"upload_completed\",\n            \"object_type\": \"root\",\n            \"path\": null,\n            \"parent_id\": null,\n            \"last_modified_date\": \"2026-02-04T12:07:59.204Z\",\n            \"file_storage_size\": 26843545600,\n            \"file_storage_usage\": 0,\n            \"user\": null,\n            \"machine_id\": null\n        }\n    },\n    \"count\": 2,\n    \"page\": 1,\n    \"next_page\": null,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-05T10:17:46Z\"\n}\n\n ```"}}},"components":{"schemas":{"ListFilesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"files":{"type":"array","description":"List of files and folders","items":{"$ref":"#/components/schemas/FileObject"}},"current":{"$ref":"#/components/schemas/CurrentDirectory","description":"Current directory information"},"count":{"type":"integer","description":"Total number of items"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"FileObject":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"FileObjectAttributes":{"type":"object","properties":{"name":{"type":"string","description":"File or folder name"},"size":{"type":"integer","description":"File size in bytes (0 for directories)"},"content_type":{"type":"string","description":"MIME type of the file or \"directory\" for folders"},"region":{"type":"string","description":"Storage region"},"status":{"type":"string","enum":["pending_upload","upload_completed","upload_failed"],"description":"Upload status"},"object_type":{"type":"string","enum":["file","directory","root"],"description":"Type of object"},"path":{"type":"string","nullable":true,"description":"Path within the storage"},"parent_id":{"type":"integer","nullable":true,"description":"Parent folder ID"},"last_modified_date":{"type":"string","format":"date-time","nullable":true,"description":"Last modification timestamp"},"file_storage_size":{"type":"integer","nullable":true,"description":"Total storage size in bytes (only for root directories)"},"file_storage_usage":{"type":"integer","nullable":true,"description":"Used storage in bytes (only for root directories)"},"user":{"type":"object","nullable":true,"description":"User who owns this file/folder","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"attributes":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}},"machine_id":{"type":"integer","nullable":true,"description":"Associated machine ID (for machine-scoped files)"}}},"CurrentDirectory":{"type":"object","description":"Current directory information with the same structure as FileObject","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Upload File & Create Directory

> Creates a new file or directory and initiates multipart upload for files.\
> \
> This endpoint creates a file or directory entry. For files, it also generates presigned S3 URLs for multipart upload.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Body Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`machine\_id\` | Integer | No | Machine ID. If provided, file/folder is created in machine's storage. null = organization shared storage |\
> \| \`file\_name\` | String | Yes | File or directory name. Must be unique within the parent folder (unless overwrite=true) |\
> \| \`object\_type\` | String | Yes | Type: \`"file"\` or \`"directory"\` |\
> \| \`content\_type\` | String | Yes (files only) | MIME type for files (e.g., "application/pdf", "image/png", "text/plain"). Required when \`object\_type\` is \`"file"\` |\
> \| \`size\` | Integer | Yes (files only) | File size in bytes. Required when \`object\_type\` is \`"file"\` |\
> \| \`chunk\_size\` | Integer | No | Chunk size in MB for multipart upload. Default: 250 MB. Only used for files |\
> \| \`overwrite\` | Boolean | No | If true, overwrites existing file with same name. Default: false |\
> \| \`parent\_id\` | Integer | Yes | Parent folder ID. Use \`0\` for root folder (machine root if machine\_id provided, organization root if machine\_id is null) |\
> \
> \#### \*\*Chunk Size Explanation\*\*\
> \
> \- Files larger than chunk\_size are uploaded in multiple parts\
> &#x20;   \
> \- Default chunk size is 250 MB\
> &#x20;   \
> \- Smaller chunks: More reliable on slow/unstable networks, easier to retry failed parts\
> &#x20;   \
> \- Larger chunks: Fewer requests, faster upload for stable networks\
> &#x20;   \
> \- Each part is uploaded separately to S3, then combined\
> &#x20;   \
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (e.g., invalid object\_type, missing required fields, parent folder not found or deleted) |\
> \| 404 | Machine not found |\
> \| 450 | Storage full |\
> \| 451 | File already exists (when overwrite=false) |\
> \| 4710 | Permission required |\
> \
> \### \*\*Success Response Fields (File)\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | Integer | File ID (use this in complete endpoint) |\
> \| \`uid\` | String | Unique identifier for the file |\
> \| \`upload\_urls\` | Array | Array of presigned S3 URLs for multipart upload. Each URL is for one chunk |\
> \| \`upload\_urls\[].part\_number\` | Integer | Part number (starts from 1) |\
> \| \`upload\_urls\[].url\` | String | Presigned S3 URL for uploading this part |\
> \| \`chunk\_size\` | Integer | Chunk size in MB used for upload |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Success Response Fields (Directory)\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | Integer | Directory ID |\
> \| \`uid\` | String | Unique identifier for the directory |\
> \| \`upload\_urls\` | null | Always null for directories |\
> \| \`chunk\_size\` | Integer | Chunk size (not used for directories) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Request Body Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "file\_name": "example.zip",\
> &#x20; "object\_type": "file",\
> &#x20; "content\_type": "application/zip",\
> &#x20; "size": 104857600,\
> &#x20; "chunk\_size": 250,\
> &#x20; "overwrite": false,\
> &#x20; "parent\_id": 1\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example (File)\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "id": 6731,\
> &#x20; "uid": "string",\
> &#x20; "upload\_urls": \[\
> &#x20;   {\
> &#x20;     "part\_number": 1,\
> &#x20;     "url": "<https://s3.amazonaws.com/bucket/file?uploadId=xyz\\&partNumber=1\\&X-Amz-Signature=..."\\>
> &#x20;   },\
> &#x20;   {\
> &#x20;     "part\_number": 2,\
> &#x20;     "url": "<https://s3.amazonaws.com/bucket/file?uploadId=xyz\\&partNumber=2\\&X-Amz-Signature=..."\\>
> &#x20;   }\
> &#x20; ],\
> &#x20; "chunk\_size": 250,\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example (Directory)\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "id": 124,\
> &#x20; "uid": "def456-ghi789-jkl012",\
> &#x20; "upload\_urls": null,\
> &#x20; "chunk\_size": 250,\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Upload Flow for Files\*\*\
> \
> 1\. Call this endpoint to create file entry and get upload URLs\
> &#x20;   \
> 2\. For each part in \`upload\_urls\`:\
> &#x20;   \
> &#x20;   \- Make PUT request to the URL with the file chunk data\
> &#x20;       \
> &#x20;   \- Save the \`ETag\` header from the PUT response\
> &#x20;       \
> 3\. Call \`POST /files/:id/complete\` with all part numbers and ETags to finalize upload\
> &#x20;   \
> 4\. Directory creation is immediate (no upload needed)

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files":{"post":{"summary":"Upload File & Create Directory","responses":{"200":{"description":"File or directory created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFileResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"450":{"description":"Storage full","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error450Response"}}}},"451":{"description":"File already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error451Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Creates a new file or directory and initiates multipart upload for files.\n\nThis endpoint creates a file or directory entry. For files, it also generates presigned S3 URLs for multipart upload.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Body Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `machine_id` | Integer | No | Machine ID. If provided, file/folder is created in machine's storage. null = organization shared storage |\n| `file_name` | String | Yes | File or directory name. Must be unique within the parent folder (unless overwrite=true) |\n| `object_type` | String | Yes | Type: `\"file\"` or `\"directory\"` |\n| `content_type` | String | Yes (files only) | MIME type for files (e.g., \"application/pdf\", \"image/png\", \"text/plain\"). Required when `object_type` is `\"file\"` |\n| `size` | Integer | Yes (files only) | File size in bytes. Required when `object_type` is `\"file\"` |\n| `chunk_size` | Integer | No | Chunk size in MB for multipart upload. Default: 250 MB. Only used for files |\n| `overwrite` | Boolean | No | If true, overwrites existing file with same name. Default: false |\n| `parent_id` | Integer | Yes | Parent folder ID. Use `0` for root folder (machine root if machine_id provided, organization root if machine_id is null) |\n\n#### **Chunk Size Explanation**\n\n- Files larger than chunk_size are uploaded in multiple parts\n    \n- Default chunk size is 250 MB\n    \n- Smaller chunks: More reliable on slow/unstable networks, easier to retry failed parts\n    \n- Larger chunks: Fewer requests, faster upload for stable networks\n    \n- Each part is uploaded separately to S3, then combined\n    \n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (e.g., invalid object_type, missing required fields, parent folder not found or deleted) |\n| 404 | Machine not found |\n| 450 | Storage full |\n| 451 | File already exists (when overwrite=false) |\n| 4710 | Permission required |\n\n### **Success Response Fields (File)**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `id` | Integer | File ID (use this in complete endpoint) |\n| `uid` | String | Unique identifier for the file |\n| `upload_urls` | Array | Array of presigned S3 URLs for multipart upload. Each URL is for one chunk |\n| `upload_urls[].part_number` | Integer | Part number (starts from 1) |\n| `upload_urls[].url` | String | Presigned S3 URL for uploading this part |\n| `chunk_size` | Integer | Chunk size in MB used for upload |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Success Response Fields (Directory)**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `id` | Integer | Directory ID |\n| `uid` | String | Unique identifier for the directory |\n| `upload_urls` | null | Always null for directories |\n| `chunk_size` | Integer | Chunk size (not used for directories) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Request Body Example**\n\n``` json\n{\n  \"file_name\": \"example.zip\",\n  \"object_type\": \"file\",\n  \"content_type\": \"application/zip\",\n  \"size\": 104857600,\n  \"chunk_size\": 250,\n  \"overwrite\": false,\n  \"parent_id\": 1\n}\n\n ```\n\n### **Success Response Example (File)**\n\n``` json\n{\n  \"id\": 6731,\n  \"uid\": \"string\",\n  \"upload_urls\": [\n    {\n      \"part_number\": 1,\n      \"url\": \"https://s3.amazonaws.com/bucket/file?uploadId=xyz&partNumber=1&X-Amz-Signature=...\"\n    },\n    {\n      \"part_number\": 2,\n      \"url\": \"https://s3.amazonaws.com/bucket/file?uploadId=xyz&partNumber=2&X-Amz-Signature=...\"\n    }\n  ],\n  \"chunk_size\": 250,\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n### **Success Response Example (Directory)**\n\n``` json\n{\n  \"id\": 124,\n  \"uid\": \"def456-ghi789-jkl012\",\n  \"upload_urls\": null,\n  \"chunk_size\": 250,\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n### **Upload Flow for Files**\n\n1. Call this endpoint to create file entry and get upload URLs\n    \n2. For each part in `upload_urls`:\n    \n    - Make PUT request to the URL with the file chunk data\n        \n    - Save the `ETag` header from the PUT response\n        \n3. Call `POST /files/:id/complete` with all part numbers and ETags to finalize upload\n    \n4. Directory creation is immediate (no upload needed)","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["file_name","object_type"],"properties":{"file_name":{"type":"string","description":"Name of the file or directory"},"object_type":{"type":"string","enum":["file","directory"],"description":"Type of object to create"},"content_type":{"type":"string","description":"MIME type of the file (required for files)"},"size":{"type":"integer","description":"File size in bytes (required for files)"},"chunk_size":{"type":"integer","description":"Chunk size for multipart upload in MB"},"overwrite":{"type":"boolean","description":"Whether to overwrite existing file with same name"},"parent_id":{"type":"integer","description":"Parent folder ID (root folder if omitted)"}}}}}}}}},"components":{"schemas":{"CreateFileResponse":{"type":"object","description":"Response after initiating a file upload","properties":{"id":{"type":"integer","description":"File ID"},"uid":{"type":"string","description":"Unique identifier for the upload"},"upload_urls":{"type":"array","nullable":true,"description":"Pre-signed URLs for uploading file chunks (null for directories)","items":{"$ref":"#/components/schemas/UploadUrl"}},"chunk_size":{"type":"integer","description":"Size of each chunk in MB"}}},"UploadUrl":{"type":"object","description":"Pre-signed URL for uploading a file chunk","properties":{"part_number":{"type":"integer","description":"Part number for multipart upload"},"url":{"type":"string","format":"uri","description":"Pre-signed URL for uploading this part"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error450Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error451Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## List Session Recordings Folder

> Lists session recording files and folders. Same structure as GET /files but scoped to session recordings. Optionally filter by machine\_id.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Query Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`parent\_id\` | Integer | Parent folder ID. 0 = root folder |\
> \| \`page\` | Integer | Page number. Default: 1 |\
> \| \`per\_page\` | Integer | Records per page. Default: 20 |\
> \| \`q\` | String | Search query. Searches by file/directory name |\
> \| \`machine\_id\` | Integer | (Optional) Filter recordings by machine ID |\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Not found |\
> \| 403 | Forbidden |\
> \| 4710 | Permission required |\
> \
> \### Response Fields\
> \
> Same structure as GET /files. The response includes \`files\`, \`current\`, \`count\`, \`page\`, \`next\_page\`, \`client\_code\`, \`message\`, and \`timestamp\` fields.\
> \
> \### Response Example\
> \
> \`\`\` json\
> {\
> &#x20;   "files": \[\
> &#x20;       {\
> &#x20;           "id": "5911",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "rec-20260121-214832.log",\
> &#x20;               "size": 14463,\
> &#x20;               "content\_type": "application/octet-stream",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "file",\
> &#x20;               "path": "/Session\_1950/rec-20260121-214832.log",\
> &#x20;               "parent\_id": 22086,\
> &#x20;               "last\_modified\_date": "2026-01-21T21:49:09.491Z",\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": null,\
> &#x20;               "machine\_id": null\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "5910",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "rec-20260121-214832.mp4",\
> &#x20;               "size": 2095700,\
> &#x20;               "content\_type": "video/mp4",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "file",\
> &#x20;               "path": "/Session\_1950/rec-20260121-214832.mp4",\
> &#x20;               "parent\_id": 22086,\
> &#x20;               "last\_modified\_date": "2026-01-21T21:49:09.203Z",\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": null,\
> &#x20;               "machine\_id": null\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "current": {\
> &#x20;       "id": "22086",\
> &#x20;       "type": "file",\
> &#x20;       "attributes": {\
> &#x20;           "name": "Session\_1950",\
> &#x20;           "size": 0,\
> &#x20;           "content\_type": "directory",\
> &#x20;           "region": "dublin",\
> &#x20;           "status": "upload\_completed",\
> &#x20;           "object\_type": "directory",\
> &#x20;           "path": "/Session\_1950",\
> &#x20;           "parent\_id": 22049,\
> &#x20;           "last\_modified\_date": "2026-01-21T21:49:09.491Z",\
> &#x20;           "file\_storage\_size": null,\
> &#x20;           "file\_storage\_usage": null,\
> &#x20;           "user": null,\
> &#x20;           "machine\_id": null\
> &#x20;       }\
> &#x20;   },\
> &#x20;   "count": 2,\
> &#x20;   "page": 1,\
> &#x20;   "next\_page": null,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-16T10:21:33Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/recordings":{"get":{"summary":"List Session Recordings Folder","parameters":[{"name":"machine_id","in":"query","description":"(Optional) Filter session recordings by machine ID","schema":{"type":"integer"}},{"name":"parent_id","in":"query","description":"(Optional) Parent folder ID. 0 = root folder","schema":{"type":"string"}},{"name":"page","in":"query","description":"(Optional) Page number. Default: 1","schema":{"type":"integer"}},{"name":"per_page","in":"query","description":"(Optional) Records per page. Default: 20","schema":{"type":"integer"}},{"name":"q","in":"query","description":"(Optional) Search by file name","schema":{"type":"string"}}],"responses":{"200":{"description":"List of session recording files and folders","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListFilesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error403Response"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Lists session recording files and folders. Same structure as GET /files but scoped to session recordings. Optionally filter by machine_id.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Query Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `parent_id` | Integer | Parent folder ID. 0 = root folder |\n| `page` | Integer | Page number. Default: 1 |\n| `per_page` | Integer | Records per page. Default: 20 |\n| `q` | String | Search query. Searches by file/directory name |\n| `machine_id` | Integer | (Optional) Filter recordings by machine ID |\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Not found |\n| 403 | Forbidden |\n| 4710 | Permission required |\n\n### Response Fields\n\nSame structure as GET /files. The response includes `files`, `current`, `count`, `page`, `next_page`, `client_code`, `message`, and `timestamp` fields.\n\n### Response Example\n\n``` json\n{\n    \"files\": [\n        {\n            \"id\": \"5911\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"rec-20260121-214832.log\",\n                \"size\": 14463,\n                \"content_type\": \"application/octet-stream\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"file\",\n                \"path\": \"/Session_1950/rec-20260121-214832.log\",\n                \"parent_id\": 22086,\n                \"last_modified_date\": \"2026-01-21T21:49:09.491Z\",\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": null,\n                \"machine_id\": null\n            }\n        },\n        {\n            \"id\": \"5910\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"rec-20260121-214832.mp4\",\n                \"size\": 2095700,\n                \"content_type\": \"video/mp4\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"file\",\n                \"path\": \"/Session_1950/rec-20260121-214832.mp4\",\n                \"parent_id\": 22086,\n                \"last_modified_date\": \"2026-01-21T21:49:09.203Z\",\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": null,\n                \"machine_id\": null\n            }\n        }\n    ],\n    \"current\": {\n        \"id\": \"22086\",\n        \"type\": \"file\",\n        \"attributes\": {\n            \"name\": \"Session_1950\",\n            \"size\": 0,\n            \"content_type\": \"directory\",\n            \"region\": \"dublin\",\n            \"status\": \"upload_completed\",\n            \"object_type\": \"directory\",\n            \"path\": \"/Session_1950\",\n            \"parent_id\": 22049,\n            \"last_modified_date\": \"2026-01-21T21:49:09.491Z\",\n            \"file_storage_size\": null,\n            \"file_storage_usage\": null,\n            \"user\": null,\n            \"machine_id\": null\n        }\n    },\n    \"count\": 2,\n    \"page\": 1,\n    \"next_page\": null,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-16T10:21:33Z\"\n}\n\n ```"}}},"components":{"schemas":{"ListFilesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"files":{"type":"array","description":"List of files and folders","items":{"$ref":"#/components/schemas/FileObject"}},"current":{"$ref":"#/components/schemas/CurrentDirectory","description":"Current directory information"},"count":{"type":"integer","description":"Total number of items"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"FileObject":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"FileObjectAttributes":{"type":"object","properties":{"name":{"type":"string","description":"File or folder name"},"size":{"type":"integer","description":"File size in bytes (0 for directories)"},"content_type":{"type":"string","description":"MIME type of the file or \"directory\" for folders"},"region":{"type":"string","description":"Storage region"},"status":{"type":"string","enum":["pending_upload","upload_completed","upload_failed"],"description":"Upload status"},"object_type":{"type":"string","enum":["file","directory","root"],"description":"Type of object"},"path":{"type":"string","nullable":true,"description":"Path within the storage"},"parent_id":{"type":"integer","nullable":true,"description":"Parent folder ID"},"last_modified_date":{"type":"string","format":"date-time","nullable":true,"description":"Last modification timestamp"},"file_storage_size":{"type":"integer","nullable":true,"description":"Total storage size in bytes (only for root directories)"},"file_storage_usage":{"type":"integer","nullable":true,"description":"Used storage in bytes (only for root directories)"},"user":{"type":"object","nullable":true,"description":"User who owns this file/folder","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"attributes":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}},"machine_id":{"type":"integer","nullable":true,"description":"Associated machine ID (for machine-scoped files)"}}},"CurrentDirectory":{"type":"object","description":"Current directory information with the same structure as FileObject","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error403Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## List Individual Files & Folders in Vagon Files

> Lists files and folders belonging to a specific machine.\
> \
> This endpoint allows you to browse the machine's file storage. You can navigate through folders using the \`parent\_id\` parameter.\
> \
> Pass \`task\_id\` to filter the response to folders associated with a specific task — the task's output/snapshot folder plus all session recording folders that were active under that task. Only directories are returned at  this level; clients descend via \`parent\_id\` to enumerate folder contents.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Path Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | Machine ID |\
> \
> \### \*\*Query Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`parent\_id\` | Integer | No | Parent folder ID. 0 = root folder (machine's root folder) |\
> \| \`page\` | Integer | No | Page number. Default: 1 |\
> \| \`per\_page\` | Integer | No | Records per page. Default: 20 |\
> \| \`q\` | String | No | Search query. Searches by file/directory name |\
> \| \`task\_id\` | Integer | No | Filter to folders associated with the given task on the machine. Returns the task's output/snapshot folder plus linked session recording folders. Directories only. |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Machine not found, does not belong to organization, or \`task\_id\` does not belong to the machine |\
> \| 4710 | Permission required |\
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`files\` | Array | Array of file/folder objects |\
> \| \`files\[].id\` | String | File/folder ID |\
> \| \`files\[].type\` | String | Always "file" |\
> \| \`files\[].attributes.name\` | String | File or folder name |\
> \| \`files\[].attributes.size\` | Integer | File size in bytes. 0 for directories |\
> \| \`files\[].attributes.content\_type\` | String | MIME type (e.g., "image/png") or "directory" |\
> \| \`files\[].attributes.region\` | String | AWS region where file is stored |\
> \| \`files\[].attributes.status\` | String | File status (e.g., "upload\_completed") |\
> \| \`files\[].attributes.object\_type\` | String | Type: "file", "directory", or "root" |\
> \| \`files\[].attributes.path\` | String | Full path of the file/folder. null for some files |\
> \| \`files\[].attributes.parent\_id\` | Integer | Parent folder ID |\
> \| \`files\[].attributes.last\_modified\_date\` | String | ISO 8601 timestamp of last modification |\
> \| \`files\[].attributes.file\_storage\_size\` | Integer | Total file storage size for the machine (in bytes). null for non-root |\
> \| \`files\[].attributes.file\_storage\_usage\` | Integer | Used file storage for the machine (in bytes). null for non-root |\
> \| \`files\[].attributes.user\` | Object | User who owns the file |\
> \| \`files\[].attributes.user.id\` | String | User UUID |\
> \| \`files\[].attributes.user.type\` | String | Always "user" |\
> \| \`files\[].attributes.user.attributes.email\` | String | User email |\
> \| \`files\[].attributes.user.attributes.name\` | String | User name |\
> \| \`files\[].attributes.machine\_id\` | Integer | Machine ID the file belongs to |\
> \| \`current\` | Object | Current directory object (same structure as file objects). null if at root |\
> \| \`count\` | Integer | Total number of files/folders in current directory |\
> \| \`page\` | Integer | Current page number |\
> \| \`next\_page\` | Integer | Next page number. null if last page |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "files": \[\
> &#x20;       {\
> &#x20;           "id": "18468",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "Machine Project Folder",\
> &#x20;               "size": 0,\
> &#x20;               "content\_type": "directory",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "directory",\
> &#x20;               "path": "/Machine Project Folder",\
> &#x20;               "parent\_id": 18465,\
> &#x20;               "last\_modified\_date": "2026-02-05T10:20:53.650Z",\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": {\
> &#x20;                   "id": "f1592625-edd0-48df-9bc0-de14910ec936",\
> &#x20;                   "type": "user",\
> &#x20;                   "attributes": {\
> &#x20;                       "email": "<user@vagon.io>",\
> &#x20;                       "name": "Computer User"\
> &#x20;                   }\
> &#x20;               },\
> &#x20;               "machine\_id": 100\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "18473",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "image.png",\
> &#x20;               "size": 303043,\
> &#x20;               "content\_type": "image/png",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "file",\
> &#x20;               "path": null,\
> &#x20;               "parent\_id": 18465,\
> &#x20;               "last\_modified\_date": "2026-02-05T10:20:33.331Z",\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": {\
> &#x20;                   "id": "f1592625-edd0-48df-9bc0-de14910ec936",\
> &#x20;                   "type": "user",\
> &#x20;                   "attributes": {\
> &#x20;                       "email": "<user@vagon.io>",\
> &#x20;                       "name": "Computer User"\
> &#x20;                   }\
> &#x20;               },\
> &#x20;               "machine\_id": 100\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "current": {\
> &#x20;       "id": "18465",\
> &#x20;       "type": "file",\
> &#x20;       "attributes": {\
> &#x20;           "name": "Computer #100",\
> &#x20;           "size": 0,\
> &#x20;           "content\_type": "directory",\
> &#x20;           "region": "dublin",\
> &#x20;           "status": "upload\_completed",\
> &#x20;           "object\_type": "root",\
> &#x20;           "path": null,\
> &#x20;           "parent\_id": null,\
> &#x20;           "last\_modified\_date": "2026-02-05T10:20:53.650Z",\
> &#x20;           "file\_storage\_size": 26843545600,\
> &#x20;           "file\_storage\_usage": 2688255,\
> &#x20;           "user": {\
> &#x20;               "id": "f1592625-edd0-48df-9bc0-de14910ec936",\
> &#x20;               "type": "user",\
> &#x20;               "attributes": {\
> &#x20;                   "email": "<user@vagon.io>",\
> &#x20;                   "name": "Computer User"\
> &#x20;               }\
> &#x20;           },\
> &#x20;           "machine\_id": 100\
> &#x20;       }\
> &#x20;   },\
> &#x20;   "count": 3,\
> &#x20;   "page": 1,\
> &#x20;   "next\_page": null,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-05T10:22:33Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/files":{"get":{"summary":"List Individual Files & Folders in Vagon Files","responses":{"200":{"description":"List of files and folders","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListFilesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"parameters":[{"name":"parent_id","in":"query","description":"(Optional) Parent folder ID. 0 = root folder","schema":{"type":"string"}},{"name":"page","in":"query","description":"(Optional) Page number. Default: 1","schema":{"type":"integer"}},{"name":"per_page","in":"query","description":"(Optional) Records per page. Default: 20","schema":{"type":"integer"}},{"name":"q","in":"query","description":"(Optional) Search by file name","schema":{"type":"string"}},{"name":"task_id","in":"query","description":"(Optional) Filter to folders associated with a specific task on the machine. Returns the task's output/snapshot folder, all session recording folders linked to this task. Only directories are returned; descend via `parent_id` to fetch contents.","schema":{"type":"integer"}}],"tags":["Files"],"description":"Lists files and folders belonging to a specific machine.\n\nThis endpoint allows you to browse the machine's file storage. You can navigate through folders using the `parent_id` parameter.\n\nPass `task_id` to filter the response to folders associated with a specific task — the task's output/snapshot folder plus all session recording folders that were active under that task. Only directories are returned at  this level; clients descend via `parent_id` to enumerate folder contents.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Path Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | Machine ID |\n\n### **Query Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `parent_id` | Integer | No | Parent folder ID. 0 = root folder (machine's root folder) |\n| `page` | Integer | No | Page number. Default: 1 |\n| `per_page` | Integer | No | Records per page. Default: 20 |\n| `q` | String | No | Search query. Searches by file/directory name |\n| `task_id` | Integer | No | Filter to folders associated with the given task on the machine. Returns the task's output/snapshot folder plus linked session recording folders. Directories only. |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Machine not found, does not belong to organization, or `task_id` does not belong to the machine |\n| 4710 | Permission required |\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `files` | Array | Array of file/folder objects |\n| `files[].id` | String | File/folder ID |\n| `files[].type` | String | Always \"file\" |\n| `files[].attributes.name` | String | File or folder name |\n| `files[].attributes.size` | Integer | File size in bytes. 0 for directories |\n| `files[].attributes.content_type` | String | MIME type (e.g., \"image/png\") or \"directory\" |\n| `files[].attributes.region` | String | AWS region where file is stored |\n| `files[].attributes.status` | String | File status (e.g., \"upload_completed\") |\n| `files[].attributes.object_type` | String | Type: \"file\", \"directory\", or \"root\" |\n| `files[].attributes.path` | String | Full path of the file/folder. null for some files |\n| `files[].attributes.parent_id` | Integer | Parent folder ID |\n| `files[].attributes.last_modified_date` | String | ISO 8601 timestamp of last modification |\n| `files[].attributes.file_storage_size` | Integer | Total file storage size for the machine (in bytes). null for non-root |\n| `files[].attributes.file_storage_usage` | Integer | Used file storage for the machine (in bytes). null for non-root |\n| `files[].attributes.user` | Object | User who owns the file |\n| `files[].attributes.user.id` | String | User UUID |\n| `files[].attributes.user.type` | String | Always \"user\" |\n| `files[].attributes.user.attributes.email` | String | User email |\n| `files[].attributes.user.attributes.name` | String | User name |\n| `files[].attributes.machine_id` | Integer | Machine ID the file belongs to |\n| `current` | Object | Current directory object (same structure as file objects). null if at root |\n| `count` | Integer | Total number of files/folders in current directory |\n| `page` | Integer | Current page number |\n| `next_page` | Integer | Next page number. null if last page |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Response Example**\n\n``` json\n{\n    \"files\": [\n        {\n            \"id\": \"18468\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"Machine Project Folder\",\n                \"size\": 0,\n                \"content_type\": \"directory\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"directory\",\n                \"path\": \"/Machine Project Folder\",\n                \"parent_id\": 18465,\n                \"last_modified_date\": \"2026-02-05T10:20:53.650Z\",\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": {\n                    \"id\": \"f1592625-edd0-48df-9bc0-de14910ec936\",\n                    \"type\": \"user\",\n                    \"attributes\": {\n                        \"email\": \"user@vagon.io\",\n                        \"name\": \"Computer User\"\n                    }\n                },\n                \"machine_id\": 100\n            }\n        },\n        {\n            \"id\": \"18473\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"image.png\",\n                \"size\": 303043,\n                \"content_type\": \"image/png\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"file\",\n                \"path\": null,\n                \"parent_id\": 18465,\n                \"last_modified_date\": \"2026-02-05T10:20:33.331Z\",\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": {\n                    \"id\": \"f1592625-edd0-48df-9bc0-de14910ec936\",\n                    \"type\": \"user\",\n                    \"attributes\": {\n                        \"email\": \"user@vagon.io\",\n                        \"name\": \"Computer User\"\n                    }\n                },\n                \"machine_id\": 100\n            }\n        }\n    ],\n    \"current\": {\n        \"id\": \"18465\",\n        \"type\": \"file\",\n        \"attributes\": {\n            \"name\": \"Computer #100\",\n            \"size\": 0,\n            \"content_type\": \"directory\",\n            \"region\": \"dublin\",\n            \"status\": \"upload_completed\",\n            \"object_type\": \"root\",\n            \"path\": null,\n            \"parent_id\": null,\n            \"last_modified_date\": \"2026-02-05T10:20:53.650Z\",\n            \"file_storage_size\": 26843545600,\n            \"file_storage_usage\": 2688255,\n            \"user\": {\n                \"id\": \"f1592625-edd0-48df-9bc0-de14910ec936\",\n                \"type\": \"user\",\n                \"attributes\": {\n                    \"email\": \"user@vagon.io\",\n                    \"name\": \"Computer User\"\n                }\n            },\n            \"machine_id\": 100\n        }\n    },\n    \"count\": 3,\n    \"page\": 1,\n    \"next_page\": null,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-05T10:22:33Z\"\n}\n\n ```"}}},"components":{"schemas":{"ListFilesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"files":{"type":"array","description":"List of files and folders","items":{"$ref":"#/components/schemas/FileObject"}},"current":{"$ref":"#/components/schemas/CurrentDirectory","description":"Current directory information"},"count":{"type":"integer","description":"Total number of items"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"FileObject":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"FileObjectAttributes":{"type":"object","properties":{"name":{"type":"string","description":"File or folder name"},"size":{"type":"integer","description":"File size in bytes (0 for directories)"},"content_type":{"type":"string","description":"MIME type of the file or \"directory\" for folders"},"region":{"type":"string","description":"Storage region"},"status":{"type":"string","enum":["pending_upload","upload_completed","upload_failed"],"description":"Upload status"},"object_type":{"type":"string","enum":["file","directory","root"],"description":"Type of object"},"path":{"type":"string","nullable":true,"description":"Path within the storage"},"parent_id":{"type":"integer","nullable":true,"description":"Parent folder ID"},"last_modified_date":{"type":"string","format":"date-time","nullable":true,"description":"Last modification timestamp"},"file_storage_size":{"type":"integer","nullable":true,"description":"Total storage size in bytes (only for root directories)"},"file_storage_usage":{"type":"integer","nullable":true,"description":"Used storage in bytes (only for root directories)"},"user":{"type":"object","nullable":true,"description":"User who owns this file/folder","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"attributes":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}},"machine_id":{"type":"integer","nullable":true,"description":"Associated machine ID (for machine-scoped files)"}}},"CurrentDirectory":{"type":"object","description":"Current directory information with the same structure as FileObject","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Complete Upload

> Completes the multipart upload process for a file.\
> \
> After uploading all file chunks to the presigned S3 URLs, call this endpoint to finalize the upload and make the file available.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Path Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | File ID (returned from create endpoint) |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`parts\` | Array | Yes | Array of uploaded parts with their ETags |\
> \| \`parts\[].part\_number\` | Integer | Yes | Part number (must match the part\_number from upload\_urls, starts from 1) |\
> \| \`parts\[].etag\` | String | Yes | ETag value returned from S3 PUT response header. Must include quotes. Example: \`"d8e8fca2dc0f896fd7cb4cb0031ba249"\` |\
> \
> \### \*\*About ETags\*\*\
> \
> \- When you PUT a chunk to S3, the response includes an \`ETag\` header\
> &#x20;   \
> \- Save this ETag exactly as returned (including the quotes)\
> &#x20;   \
> \- ETag format: \`"hexadecimal-string"\` (quotes are part of the value)\
> &#x20;   \
> \- Each part\_number must have a corresponding ETag\
> &#x20;   \
> \- Parts must be in order (part\_number 1, 2, 3, etc.)\
> &#x20;   \
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (e.g., invalid parts format, file not found) |\
> \| 404 | File not found or does not belong to organization |\
> \| 450 | Storage limit exceeded after upload completion (file is deleted) |\
> \| 452 | File size mismatch - actual uploaded size doesn't match expected size (file is deleted) |\
> \| 4710 | Permission required |\
> \
> \### \*\*Request Body Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "parts": \[\
> &#x20;   {\
> &#x20;     "part\_number": 1,\
> &#x20;     "etag": "\\"d8e8fca2dc0f896fd7cb4cb0031ba249\\""\
> &#x20;   },\
> &#x20;   {\
> &#x20;     "part\_number": 2,\
> &#x20;     "etag": "\\"7cb4cb0031ba249d8e8fca2dc0f896fd\\""\
> &#x20;   }\
> &#x20; ]\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`uid\` | String | Unique identifier for the file |\
> \| \`download\_url\` | String | Presigned S3 URL for downloading the file. Valid for limited time (typically 1 hour) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "uid": "string",\
> &#x20; "download\_url": "<https://s3.amazonaws.com/bucket/file?X-Amz-Signature=...\\&X-Amz-Expires=3600",\\>
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/{id}/complete":{"post":{"summary":"Complete Upload","responses":{"200":{"description":"Upload completed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteUploadResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"File not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"450":{"description":"Storage limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error450Response"}}}},"452":{"description":"File size mismatch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error452Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Completes the multipart upload process for a file.\n\nAfter uploading all file chunks to the presigned S3 URLs, call this endpoint to finalize the upload and make the file available.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Path Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | File ID (returned from create endpoint) |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `parts` | Array | Yes | Array of uploaded parts with their ETags |\n| `parts[].part_number` | Integer | Yes | Part number (must match the part_number from upload_urls, starts from 1) |\n| `parts[].etag` | String | Yes | ETag value returned from S3 PUT response header. Must include quotes. Example: `\"d8e8fca2dc0f896fd7cb4cb0031ba249\"` |\n\n### **About ETags**\n\n- When you PUT a chunk to S3, the response includes an `ETag` header\n    \n- Save this ETag exactly as returned (including the quotes)\n    \n- ETag format: `\"hexadecimal-string\"` (quotes are part of the value)\n    \n- Each part_number must have a corresponding ETag\n    \n- Parts must be in order (part_number 1, 2, 3, etc.)\n    \n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (e.g., invalid parts format, file not found) |\n| 404 | File not found or does not belong to organization |\n| 450 | Storage limit exceeded after upload completion (file is deleted) |\n| 452 | File size mismatch - actual uploaded size doesn't match expected size (file is deleted) |\n| 4710 | Permission required |\n\n### **Request Body Example**\n\n``` json\n{\n  \"parts\": [\n    {\n      \"part_number\": 1,\n      \"etag\": \"\\\"d8e8fca2dc0f896fd7cb4cb0031ba249\\\"\"\n    },\n    {\n      \"part_number\": 2,\n      \"etag\": \"\\\"7cb4cb0031ba249d8e8fca2dc0f896fd\\\"\"\n    }\n  ]\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `uid` | String | Unique identifier for the file |\n| `download_url` | String | Presigned S3 URL for downloading the file. Valid for limited time (typically 1 hour) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Success Response Example**\n\n``` json\n{\n  \"uid\": \"string\",\n  \"download_url\": \"https://s3.amazonaws.com/bucket/file?X-Amz-Signature=...&X-Amz-Expires=3600\",\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["parts"],"properties":{"parts":{"type":"array","description":"List of uploaded parts with their ETags","items":{"type":"object","required":["part_number","etag"],"properties":{"part_number":{"type":"integer","description":"Part number (1-indexed)"},"etag":{"type":"string","description":"ETag returned from S3 upload"}}}}}}}}}}}},"components":{"schemas":{"CompleteUploadResponse":{"type":"object","description":"Response after completing a multipart upload","properties":{"uid":{"type":"string","description":"Unique identifier of the uploaded file"},"download_url":{"type":"string","format":"uri","description":"URL to download the uploaded file"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error450Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error452Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Delete File from Vagon Files

> Deletes a file or directory. When a directory is deleted, all files and subdirectories inside it are also deleted recursively. This action is irreversible.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Path Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | File or Directory ID |\
> \
> \### \*\*Deletion Process\*\*\
> \
> \- Files: Immediately marked as deleted and removed from S3\
> &#x20;   \
> \- Directories: Recursively deletes all child files and subdirectories\
> &#x20;   \
> &#x20;   \- Deletion happens asynchronously via background job\
> &#x20;       \
> &#x20;   \- All nested content is soft-deleted\
> &#x20;       \
> &#x20;   \- S3 objects are removed\
> &#x20;       \
> \
> \#### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | File/directory not found or does not belong to organization |\
> \| 450 | Attempted to delete root folder |\
> \| 4710 | Permission required |\
> \
> \#### \*\*Success Response\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T12:16:26Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/{id}":{"delete":{"summary":"Delete File from Vagon Files","responses":{"200":{"description":"File deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"File not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Deletes a file or directory. When a directory is deleted, all files and subdirectories inside it are also deleted recursively. This action is irreversible.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Path Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | File or Directory ID |\n\n### **Deletion Process**\n\n- Files: Immediately marked as deleted and removed from S3\n    \n- Directories: Recursively deletes all child files and subdirectories\n    \n    - Deletion happens asynchronously via background job\n        \n    - All nested content is soft-deleted\n        \n    - S3 objects are removed\n        \n\n#### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | File/directory not found or does not belong to organization |\n| 450 | Attempted to delete root folder |\n| 4710 | Permission required |\n\n#### **Success Response**\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T12:16:26Z\"\n}\n\n ```"}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Generate Download Link for File

> Creates download link for files or directory contents to let users create download links.\
> \
> This endpoint allows you to download single/multiple file(s)s or an entire directory.\
> \
> \- For single file downloads, it returns a direct download URL.\
> &#x20;   \
> \- For multiple files or directories, it returns a download ID that can be used to check the status.\
> &#x20;   \
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Body Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`directory\_id\` | Integer | No | Directory ID to download recursively. Zips the entire directory and all subdirectories |\
> \| \`file\_ids\` | Array\\\[Integer\\] | No | Array of file IDs to be downloaded. |\
> \| \`task\_id\` | Integer | No | Task ID. Bundles the task's output folder and every session recording folder linked to that task (across seat and admin storage) into a single ZIP. Each input directory becomes a top-level subfolder in the archive named after the directory. |\
> \
> \### Notes\
> \
> \- Exactly one of \`directory\_id\`, \`file\_ids\`, or \`task\_id\` must be provided. Sending more than one (or none) returns \`4722\`.\
> \- For single file downloads (one file\_id), returns a direct download URL immediately\
> \- For multiple files, directories, or \`task\_id\`, returns a \`download\_id\` that must be used with \`GET /files/downloads/:id\` to check status and get download URL\
> \- Multiple file downloads, directory downloads, and \`task\_id\` downloads require the organization to have \`multiple\_file\_download\` feature enabled\
> &#x20;   \
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (e.g., invalid IDs) |\
> \| 404 | Directory or files not found or do not belong to organization |\
> \| 4710 | Permission required (multiple file download not enabled) |\
> \| 4717 | Directory or file not found |\
> \| 4718 | File count mismatch during download (requested files not found) |\
> \| 4719 | Directory is empty or has no completed files |\
> \| 4720 | Download URL generation failed |\
> \| 4722 | None of \`directory\_id\`, \`file\_ids\`, \`task\_id\` provided — or more than one provided (mutually exclusive) |\
> \
> \### \*\*Request Body Example\*\*\
> \
> Provide exactly one of \`directory\_id\`, \`file\_ids\`, or \`task\_id\`. Remove the unused fields before sending — they are shown together below for reference only and are mutually exclusive.\
> \
> \`\`\` json\
> {\
> &#x20; "directory\_id": 1,\
> &#x20; "file\_ids": \[2, 3],\
> &#x20; "task\_id": 42\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`url\` | String | Presigned S3 download URL (for single file download) |\
> \| \`size\` | Integer | File size in bytes (single file). For multiple files or directory, total size in bytes of all files to be zipped |\
> \| \`name\` | String | File name |\
> \| \`content\_type\` | String | MIME type of the file |\
> \| \`download\_id\` | Integer | Download ID (for multiple files/directory - use with GET /files/downloads/:id) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### Success Response Example\
> \
> When downloading a single file, returns direct download URL. When downloading multiple files or a directory, returns download ID.\
> \
> \`\`\` json\
> {\
> &#x20; "url": "<https://s3.amazonaws.com/bucket/file?X-Amz-Signature=...\\&X-Amz-Expires=3600",\\>
> &#x20; "size": 1601,\
> &#x20; "name": "string",\
> &#x20; "content\_type": "string",\
> &#x20; "download\_id": 5085,\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### Usage Flow\
> \
> 1\. Call this endpoint with \`directory\_id\` or \`file\_ids\`\
> &#x20;   \
> 2\. If single file: Use the returned \`url\` directly to download\
> &#x20;   \
> 3\. If multiple files/directory: Use the returned \`download\_id\` with \`GET /files/downloads/:id\` to:\
> &#x20;   \- Check processing status (pending, processing, uploaded, failed, cancelled)\
> &#x20;       \
> &#x20;   \- Get download URL when status is \`uploaded\`\
> &#x20;       \
> 4\. Download URLs expire after 24 hours

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/download":{"post":{"summary":"Generate Download Link for File","responses":{"200":{"description":"Download link generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadLinkResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"File or directory not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}},"4717":{"description":"Directory or file not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4717Response"}}}},"4718":{"description":"File count mismatch during download","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4718Response"}}}},"4719":{"description":"Directory is empty or has no completed files","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4719Response"}}}},"4720":{"description":"Download URL generation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4720Response"}}}},"4722":{"description":"No files or directory provided for download","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4722Response"}}}}},"tags":["Files"],"description":"Creates download link for files or directory contents to let users create download links.\n\nThis endpoint allows you to download single/multiple file(s)s or an entire directory.\n\n- For single file downloads, it returns a direct download URL.\n    \n- For multiple files or directories, it returns a download ID that can be used to check the status.\n    \n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Body Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `directory_id` | Integer | No | Directory ID to download recursively. Zips the entire directory and all subdirectories |\n| `file_ids` | Array\\[Integer\\] | No | Array of file IDs to be downloaded. |\n| `task_id` | Integer | No | Task ID. Bundles the task's output folder and every session recording folder linked to that task (across seat and admin storage) into a single ZIP. Each input directory becomes a top-level subfolder in the archive named after the directory. |\n\n### Notes\n\n- Exactly one of `directory_id`, `file_ids`, or `task_id` must be provided. Sending more than one (or none) returns `4722`.\n- For single file downloads (one file_id), returns a direct download URL immediately\n- For multiple files, directories, or `task_id`, returns a `download_id` that must be used with `GET /files/downloads/:id` to check status and get download URL\n- Multiple file downloads, directory downloads, and `task_id` downloads require the organization to have `multiple_file_download` feature enabled\n    \n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (e.g., invalid IDs) |\n| 404 | Directory or files not found or do not belong to organization |\n| 4710 | Permission required (multiple file download not enabled) |\n| 4717 | Directory or file not found |\n| 4718 | File count mismatch during download (requested files not found) |\n| 4719 | Directory is empty or has no completed files |\n| 4720 | Download URL generation failed |\n| 4722 | None of `directory_id`, `file_ids`, `task_id` provided — or more than one provided (mutually exclusive) |\n\n### **Request Body Example**\n\nProvide exactly one of `directory_id`, `file_ids`, or `task_id`. Remove the unused fields before sending — they are shown together below for reference only and are mutually exclusive.\n\n``` json\n{\n  \"directory_id\": 1,\n  \"file_ids\": [2, 3],\n  \"task_id\": 42\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `url` | String | Presigned S3 download URL (for single file download) |\n| `size` | Integer | File size in bytes (single file). For multiple files or directory, total size in bytes of all files to be zipped |\n| `name` | String | File name |\n| `content_type` | String | MIME type of the file |\n| `download_id` | Integer | Download ID (for multiple files/directory - use with GET /files/downloads/:id) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### Success Response Example\n\nWhen downloading a single file, returns direct download URL. When downloading multiple files or a directory, returns download ID.\n\n``` json\n{\n  \"url\": \"https://s3.amazonaws.com/bucket/file?X-Amz-Signature=...&X-Amz-Expires=3600\",\n  \"size\": 1601,\n  \"name\": \"string\",\n  \"content_type\": \"string\",\n  \"download_id\": 5085,\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n### Usage Flow\n\n1. Call this endpoint with `directory_id` or `file_ids`\n    \n2. If single file: Use the returned `url` directly to download\n    \n3. If multiple files/directory: Use the returned `download_id` with `GET /files/downloads/:id` to:\n    - Check processing status (pending, processing, uploaded, failed, cancelled)\n        \n    - Get download URL when status is `uploaded`\n        \n4. Download URLs expire after 24 hours","requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["directory_id"],"properties":{"directory_id":{"type":"integer","description":"Directory ID to download recursively. Zips the entire directory and all subdirectories."}},"additionalProperties":false},{"type":"object","required":["file_ids"],"properties":{"file_ids":{"type":"array","description":"List of file IDs to download.","items":{"type":"integer"}}},"additionalProperties":false},{"type":"object","required":["task_id"],"properties":{"task_id":{"type":"integer","description":"Task ID. Bundles the task's output folder and all linked session recording folders into a single ZIP."}},"additionalProperties":false}]}}}}}}},"components":{"schemas":{"DownloadLinkResponse":{"type":"object","description":"Response containing download link information","properties":{"url":{"type":"string","format":"uri","nullable":true,"description":"Download URL (null if still processing)"},"size":{"type":"integer","nullable":true,"description":"File size in bytes"},"name":{"type":"string","nullable":true,"description":"File name"},"content_type":{"type":"string","nullable":true,"description":"MIME type of the file"},"download_id":{"type":"integer","nullable":true,"description":"Download job ID for status tracking"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4717Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4718Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4719Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4720Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4722Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Get Download Status

> Retrieves the status and download URL for a file download.\
> \
> This endpoint is used to check the processing status of a file created via \`POST /files/download\`. The file is created asynchronously, so you need to poll this endpoint until the status is \`uploaded\`.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | Temporary file ID (download\_id returned from POST /files/download) |\
> \
> \### Status Values\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| \`pending\` | File creation is queued but not started |\
> \| \`processing\` | File is being created |\
> \| \`uploaded\` | File is ready for download |\
> \| \`failed\` | File creation failed |\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Temporary file not found, expired, or does not belong to organization |\
> \| 4710 | Permission required |\
> \### Response Fields\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | String | Temporary file ID |\
> \| \`type\` | String | Always \`"download"\` |\
> \| \`attributes.status\` | String | Current status: \`pending\`, \`processing\`, \`uploaded\`, \`failed\` |\
> \| \`attributes.download\_url\` | String | Presigned S3 download URL. Only present when status is \`uploaded\` and \`generate\_download\_url\` is true. Valid for limited time (typically 1 hour) |\
> \| \`attributes.expires\_at\` | String | ISO 8601 timestamp when the temporary file will be deleted (typically 24 hours after creation) |\
> \| \`attributes.size\` | Integer | Total size in bytes of the files or directory being zipped (nullable for older records) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### Success Response\
> \
> \`\`\` json\
> {\
> &#x20; "id": "string",\
> &#x20; "type": "download",\
> &#x20; "attributes": {\
> &#x20;   "status": "uploaded",\
> &#x20;   "download\_url": "<https://s3.amazonaws.com/bucket/temp\\_files/uuid/archive.zip?X-Amz-Signature=...\\&X-Amz-Expires=3600",\\>
> &#x20;   "expires\_at": "2021-01-21T16:09:09.461Z",\
> &#x20;   "size": 1048576\
> &#x20; },\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### Usage Flow\
> \
> 1\. Call \`POST /files/download\` with \`directory\_id\` or \`file\_ids\` to get a \`download\_id\`\
> &#x20;   \
> 2\. Poll this endpoint with the \`download\_id\` to check status\
> &#x20;   \
> 3\. When status is \`uploaded\`, use the \`download\_url\` to download the zip file\
> &#x20;   \
> 4\. Temporary files expire after 24 hours\
> 5\. To cancel a pending download, use \`DELETE /files/downloads/:id\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/downloads/{id}":{"get":{"summary":"Get Download Status","responses":{"200":{"description":"Download status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadStatusResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Download not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Retrieves the status and download URL for a file download.\n\nThis endpoint is used to check the processing status of a file created via `POST /files/download`. The file is created asynchronously, so you need to poll this endpoint until the status is `uploaded`.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | Temporary file ID (download_id returned from POST /files/download) |\n\n### Status Values\n\n| Status | Description |\n| --- | --- |\n| `pending` | File creation is queued but not started |\n| `processing` | File is being created |\n| `uploaded` | File is ready for download |\n| `failed` | File creation failed |\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Temporary file not found, expired, or does not belong to organization |\n| 4710 | Permission required |\n### Response Fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `id` | String | Temporary file ID |\n| `type` | String | Always `\"download\"` |\n| `attributes.status` | String | Current status: `pending`, `processing`, `uploaded`, `failed` |\n| `attributes.download_url` | String | Presigned S3 download URL. Only present when status is `uploaded` and `generate_download_url` is true. Valid for limited time (typically 1 hour) |\n| `attributes.expires_at` | String | ISO 8601 timestamp when the temporary file will be deleted (typically 24 hours after creation) |\n| `attributes.size` | Integer | Total size in bytes of the files or directory being zipped (nullable for older records) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### Success Response\n\n``` json\n{\n  \"id\": \"string\",\n  \"type\": \"download\",\n  \"attributes\": {\n    \"status\": \"uploaded\",\n    \"download_url\": \"https://s3.amazonaws.com/bucket/temp_files/uuid/archive.zip?X-Amz-Signature=...&X-Amz-Expires=3600\",\n    \"expires_at\": \"2021-01-21T16:09:09.461Z\",\n    \"size\": 1048576\n  },\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n### Usage Flow\n\n1. Call `POST /files/download` with `directory_id` or `file_ids` to get a `download_id`\n    \n2. Poll this endpoint with the `download_id` to check status\n    \n3. When status is `uploaded`, use the `download_url` to download the zip file\n    \n4. Temporary files expire after 24 hours\n5. To cancel a pending download, use `DELETE /files/downloads/:id`"}}},"components":{"schemas":{"DownloadStatusResponse":{"type":"object","description":"Download job status response","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/DownloadStatusAttributes"}}},"DownloadStatusAttributes":{"type":"object","description":"Download job status attributes","properties":{"status":{"type":"string","enum":["pending","processing","uploaded","failed","cancelled"],"description":"Current status of the download job"},"download_url":{"type":"string","format":"uri","nullable":true,"description":"Download URL (available when status is uploaded)"},"expires_at":{"type":"string","format":"date-time","description":"Expiration timestamp for the download URL"},"size":{"type":"integer","nullable":true,"description":"Total size in bytes of the files or directory being zipped"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Abort Pending Download

> Aborts a pending or processing zip download. Use the same \`id\` (download\_id) as returned from POST /files/download and used with GET /files/downloads/:id. When status is \`processing\`, the running job will stop and abort the S3 multipart upload.\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | Temporary file ID (download\_id from POST /files/download) |\
> \
> \### Notes\
> \
> \- Both \`pending\` and \`processing\` downloads can be aborted. If the download is already \`uploaded\`, \`failed\`, or \`cancelled\`, the API returns 4716.\
> \- After abort, the temporary file is marked as \`cancelled\` and will not be processed.

```json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/downloads/{id}":{"delete":{"summary":"Abort Pending Download","operationId":"abortDownload","responses":{"200":{"description":"Download aborted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptySuccessResponse"}}}},"400":{"description":"Bad request (e.g. download cannot be aborted)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Download not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}},"4716":{"description":"Download cannot be aborted (already uploaded or failed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4716Response"}}}}},"tags":["Files"],"description":"Aborts a pending or processing zip download. Use the same `id` (download_id) as returned from POST /files/download and used with GET /files/downloads/:id. When status is `processing`, the running job will stop and abort the S3 multipart upload.\n\n### Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | Temporary file ID (download_id from POST /files/download) |\n\n### Notes\n\n- Both `pending` and `processing` downloads can be aborted. If the download is already `uploaded`, `failed`, or `cancelled`, the API returns 4716.\n- After abort, the temporary file is marked as `cancelled` and will not be processed.","parameters":[{"name":"id","in":"path","required":true,"description":"(Required) Temporary file ID (download_id from POST /files/download)","schema":{"type":"integer"}}]}}},"components":{"schemas":{"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4716Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
```


# Software

## List Softwares and Base Images

> Lists all available softwares and base images.\
> \
> This endpoint shows which softwares can be pre-installed when creating machines and which base images can be used as the operating system foundation.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`software\` | Array | Array of available software objects |\
> \| \`software\[].id\` | Integer | Software ID (use in \`software\_ids\` array when creating machine) |\
> \| \`software\[].name\` | String | Software name |\
> \| \`software\[].size\` | Integer | Software size in bytes |\
> \| \`base\_images\` | Array | Array of available base image objects |\
> \| \`base\_images\[].id\` | Integer | Base image ID (use in \`base\_image\_id\` when creating machine) |\
> \| \`base\_images\[].name\` | String | Base image name (e.g., "Windows 11 Pro - Clean") |\
> \| \`base\_images\[].size\` | Integer | Base image size in bytes |\
> \| \`base\_images\[].type\` | String | Always "base\_image" |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "software": \[\
> &#x20;   {\
> &#x20;     "id": 1,\
> &#x20;     "name": "Adobe Photoshop",\
> &#x20;     "size": 5583457484\
> &#x20;   },\
> &#x20;   {\
> &#x20;     "id": 2,\
> &#x20;     "name": "Blender",\
> &#x20;     "size": 1932735283\
> &#x20;   }\
> &#x20; ],\
> &#x20; "base\_images": \[\
> &#x20;   {\
> &#x20;     "id": 1,\
> &#x20;     "name": "Windows 11 Pro - Clean",\
> &#x20;     "size": 48318382080,\
> &#x20;     "type": "base\_image"\
> &#x20;   },\
> &#x20;   {\
> &#x20;     "id": 2,\
> &#x20;     "name": "Windows 11 - Design Suite",\
> &#x20;     "size": 91268055040,\
> &#x20;     "type": "base\_image"\
> &#x20;   }\
> &#x20; ],\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Usage\*\*\
> \
> \- \*\*Software IDs\*\*: Use \`software\[].id\` values in the \`software\_ids\` array parameter when calling \`POST /machines\`\
> &#x20;   \
> \- \*\*Base Image ID\*\*: Use \`base\_images\[].id\` in the \`base\_image\_id\` parameter when calling \`POST /machines\`\
> &#x20;   \
> \- \*\*Default Base Image\*\*: If \`base\_image\_id\` is not specified (null), the latest base image is automatically used\
> &#x20;   \
> \- \*\*Size Considerations\*\*: When selecting software and base images, ensure the total size (with 5% buffer) fits within the plan's disk size

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/software":{"get":{"summary":"List Softwares and Base Images","responses":{"200":{"description":"List of software and base images","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SoftwareListResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Software"],"description":"Lists all available softwares and base images.\n\nThis endpoint shows which softwares can be pre-installed when creating machines and which base images can be used as the operating system foundation.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `software` | Array | Array of available software objects |\n| `software[].id` | Integer | Software ID (use in `software_ids` array when creating machine) |\n| `software[].name` | String | Software name |\n| `software[].size` | Integer | Software size in bytes |\n| `base_images` | Array | Array of available base image objects |\n| `base_images[].id` | Integer | Base image ID (use in `base_image_id` when creating machine) |\n| `base_images[].name` | String | Base image name (e.g., \"Windows 11 Pro - Clean\") |\n| `base_images[].size` | Integer | Base image size in bytes |\n| `base_images[].type` | String | Always \"base_image\" |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Response Example**\n\n``` json\n{\n  \"software\": [\n    {\n      \"id\": 1,\n      \"name\": \"Adobe Photoshop\",\n      \"size\": 5583457484\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Blender\",\n      \"size\": 1932735283\n    }\n  ],\n  \"base_images\": [\n    {\n      \"id\": 1,\n      \"name\": \"Windows 11 Pro - Clean\",\n      \"size\": 48318382080,\n      \"type\": \"base_image\"\n    },\n    {\n      \"id\": 2,\n      \"name\": \"Windows 11 - Design Suite\",\n      \"size\": 91268055040,\n      \"type\": \"base_image\"\n    }\n  ],\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n### **Usage**\n\n- **Software IDs**: Use `software[].id` values in the `software_ids` array parameter when calling `POST /machines`\n    \n- **Base Image ID**: Use `base_images[].id` in the `base_image_id` parameter when calling `POST /machines`\n    \n- **Default Base Image**: If `base_image_id` is not specified (null), the latest base image is automatically used\n    \n- **Size Considerations**: When selecting software and base images, ensure the total size (with 5% buffer) fits within the plan's disk size"}}},"components":{"schemas":{"SoftwareListResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"software":{"type":"array","description":"List of available software packages","items":{"$ref":"#/components/schemas/Software"}},"base_images":{"type":"array","description":"List of available base images","items":{"$ref":"#/components/schemas/BaseImage"}}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Software":{"type":"object","description":"Software package that can be pre-installed on images","properties":{"id":{"type":"integer","description":"Software ID"},"name":{"type":"string","description":"Software name"},"size":{"type":"number","format":"float","description":"Software size in GB"}}},"BaseImage":{"type":"object","description":"Base image that can be used to create new images","properties":{"id":{"type":"integer","description":"Base image ID"},"name":{"type":"string","description":"Base image name"},"size":{"type":"integer","description":"Base image size in GB"},"type":{"type":"string","description":"Type identifier"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````


# Users

## List Users

> List organization members and pending invitations with optional pagination and search.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Query Parameters\*\*\
> \
> \| Parameter | Type | Default | Description |\
> \| --- | --- | --- | --- |\
> \| \`page\` | Integer | 1 | Page number |\
> \| \`per\_page\` | Integer | 20 | Record count per page |\
> \| \`q\` | String | \\- | Search by user email or name |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "users": \[\
> &#x20;       {\
> &#x20;           "name": "Computer User",\
> &#x20;           "email": "<computeruser@vagon.io>",\
> &#x20;           "status": "active",\
> &#x20;           "machine\_id": 100,\
> &#x20;           "uid": "f1592625-edd0-48df-9bc0-de14910ec936"\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "name": null,\
> &#x20;           "email": "<inviteduser@vagon.io>",\
> &#x20;           "status": "invitation-pending",\
> &#x20;           "machine\_id": null,\
> &#x20;           "uid": null\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "count": 2,\
> &#x20;   "page": 1,\
> &#x20;   "next\_page": null,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-09T12:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`users\` | Array | Array of user or invitation objects |\
> \| \`users\[].name\` | String or null | User display name (null for invitation) |\
> \| \`users\[].email\` | String | User or invitee email |\
> \| \`users\[].status\` | String | "active" or "invitation-pending" |\
> \| \`users\[].machine\_id\` | Integer or null | Assigned machine ID (null if none) |\
> \| \`users\[].uid\` | String or null | User UUID (null for pending invitation) |\
> \| \`count\` | Integer | Total count for current page |\
> \| \`page\` | Integer | Current page number |\
> \| \`next\_page\` | Integer or null | Next page number (null if no more pages) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 4710 | Permission required |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/users":{"get":{"summary":"List Users","parameters":[{"name":"page","in":"query","description":"(Optional) Page number. Default: 1","schema":{"type":"integer"}},{"name":"per_page","in":"query","description":"(Optional) Records per page. Default: 20","schema":{"type":"integer"}},{"name":"q","in":"query","description":"(Optional) Search by user email or name","schema":{"type":"string"}}],"responses":{"200":{"description":"List of users and pending invitations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListUsersResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Users"],"description":"List organization members and pending invitations with optional pagination and search.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Query Parameters**\n\n| Parameter | Type | Default | Description |\n| --- | --- | --- | --- |\n| `page` | Integer | 1 | Page number |\n| `per_page` | Integer | 20 | Record count per page |\n| `q` | String | \\- | Search by user email or name |\n\n### **Success Response Example**\n\n``` json\n{\n    \"users\": [\n        {\n            \"name\": \"Computer User\",\n            \"email\": \"computeruser@vagon.io\",\n            \"status\": \"active\",\n            \"machine_id\": 100,\n            \"uid\": \"f1592625-edd0-48df-9bc0-de14910ec936\"\n        },\n        {\n            \"name\": null,\n            \"email\": \"inviteduser@vagon.io\",\n            \"status\": \"invitation-pending\",\n            \"machine_id\": null,\n            \"uid\": null\n        }\n    ],\n    \"count\": 2,\n    \"page\": 1,\n    \"next_page\": null,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-09T12:00:00Z\"\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `users` | Array | Array of user or invitation objects |\n| `users[].name` | String or null | User display name (null for invitation) |\n| `users[].email` | String | User or invitee email |\n| `users[].status` | String | \"active\" or \"invitation-pending\" |\n| `users[].machine_id` | Integer or null | Assigned machine ID (null if none) |\n| `users[].uid` | String or null | User UUID (null for pending invitation) |\n| `count` | Integer | Total count for current page |\n| `page` | Integer | Current page number |\n| `next_page` | Integer or null | Next page number (null if no more pages) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 4710 | Permission required |"}}},"components":{"schemas":{"ListUsersResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"users":{"type":"array","items":{"$ref":"#/components/schemas/UserListItem"}},"count":{"type":"integer","description":"Total count for current page"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"UserListItem":{"type":"object","description":"User or pending invitation in list","properties":{"name":{"type":"string","nullable":true,"description":"User display name (null for invitation without accepted user)"},"email":{"type":"string","description":"User or invitee email"},"status":{"type":"string","description":"\"active\" for member, \"invitation-pending\" for pending invitation","enum":["active","invitation-pending"]},"machine_id":{"type":"integer","nullable":true,"description":"Assigned machine ID (null if not assigned)"},"uid":{"type":"string","nullable":true,"description":"User UUID (null for pending invitation)"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Remove User or Cancel Invitation

> Remove a member from the organization or cancel a pending invitation.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`email\`\\\* | String | Yes | User or invitee email to remove |\
> \| \`keep\_files\` | Boolean | No | Whether to keep user files. Default: true |\
> \
> \### Request Body Example\
> \
> \`\`\` json\
> {\
> &#x20; "email": "<user@vagon.io>",\
> &#x20; "keep\_files": true\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-10T15:56:54Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Email not found in organization or pending invitations |\
> \| 4318 | Not a valid email |\
> \| 4319 | Email not found |\
> \| 4710 | Permission required |\
> \| 4713 | Organization owner cannot be removed |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/users":{"delete":{"summary":"Remove User or Cancel Invitation","responses":{"200":{"description":"User removed or invitation cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Email not found in organization or pending invitations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4318":{"description":"Not a valid email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4318Response"}}}},"4319":{"description":"Email not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4319Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}},"4713":{"description":"Organization owner cannot be removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4713Response"}}}}},"tags":["Users"],"description":"Remove a member from the organization or cancel a pending invitation.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `email`\\* | String | Yes | User or invitee email to remove |\n| `keep_files` | Boolean | No | Whether to keep user files. Default: true |\n\n### Request Body Example\n\n``` json\n{\n  \"email\": \"user@vagon.io\",\n  \"keep_files\": true\n}\n\n ```\n\n### **Success Response Example**\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-10T15:56:54Z\"\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Email not found in organization or pending invitations |\n| 4318 | Not a valid email |\n| 4319 | Email not found |\n| 4710 | Permission required |\n| 4713 | Organization owner cannot be removed |","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","description":"User or invitee email to remove"},"keep_files":{"type":"boolean","description":"Whether to keep user files. Default true","default":true}}}}}}}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4318Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4319Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4713Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Assign User or Invitation to Machine

> Assign a user or pending invitation to an unassigned machine. If the machine is already assigned, revoke first.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`machine\_id\`\\\* | Integer | Yes | Machine ID to assign |\
> \| \`email\`\\\* | String | Yes | User or invitee email |\
> \
> \### Request Body Example\
> \
> \`\`\` json\
> {\
> &#x20; "machine\_id": 100,\
> &#x20; "email": "<computeruser@vagon.io>"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "name": "Computer User",\
> &#x20;   "email": "<computeruser@vagon.io>",\
> &#x20;   "status": "active",\
> &#x20;   "machine\_id": 100,\
> &#x20;   "uid": "683530d7-707a-aaaa-8d74-4ac8475e5051",\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-10T15:58:10Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`name\` | String or null | User display name (null for pending invitation) |\
> \| \`email\` | String | User or invitee email |\
> \| \`status\` | String | "active" or "invitation-pending" |\
> \| \`machine\_id\` | Integer | Assigned machine ID |\
> \| \`uid\` | String or null | User UUID (null for pending invitation) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Machine not found or email not in organization/invitations |\
> \| 4318 | Not a valid email |\
> \| 4319 | Email not found |\
> \| 4710 | Permission required |\
> \| 4715 | Machine already assigned. Revoke current assignment first. |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/users/assign":{"post":{"summary":"Assign User or Invitation to Machine","responses":{"200":{"description":"User or invitation assigned successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignUserResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine or user/email not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4318":{"description":"Not a valid email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4318Response"}}}},"4319":{"description":"Email not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4319Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}},"4715":{"description":"Machine already assigned. Revoke current assignment first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4715Response"}}}}},"tags":["Users"],"description":"Assign a user or pending invitation to an unassigned machine. If the machine is already assigned, revoke first.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `machine_id`\\* | Integer | Yes | Machine ID to assign |\n| `email`\\* | String | Yes | User or invitee email |\n\n### Request Body Example\n\n``` json\n{\n  \"machine_id\": 100,\n  \"email\": \"computeruser@vagon.io\"\n}\n\n ```\n\n### **Success Response Example**\n\n``` json\n{\n    \"name\": \"Computer User\",\n    \"email\": \"computeruser@vagon.io\",\n    \"status\": \"active\",\n    \"machine_id\": 100,\n    \"uid\": \"683530d7-707a-aaaa-8d74-4ac8475e5051\",\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-10T15:58:10Z\"\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `name` | String or null | User display name (null for pending invitation) |\n| `email` | String | User or invitee email |\n| `status` | String | \"active\" or \"invitation-pending\" |\n| `machine_id` | Integer | Assigned machine ID |\n| `uid` | String or null | User UUID (null for pending invitation) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Machine not found or email not in organization/invitations |\n| 4318 | Not a valid email |\n| 4319 | Email not found |\n| 4710 | Permission required |\n| 4715 | Machine already assigned. Revoke current assignment first. |","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["machine_id","email"],"properties":{"machine_id":{"type":"integer","description":"Machine ID to assign"},"email":{"type":"string","description":"User or invitee email"}}}}}}}}},"components":{"schemas":{"AssignUserResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"name":{"type":"string","nullable":true},"email":{"type":"string"},"status":{"type":"string","enum":["active","invitation-pending"]},"machine_id":{"type":"integer"},"uid":{"type":"string","nullable":true}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4318Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4319Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4715Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Revoke User or Invitation from Machine

> Revoke the user or invitation assigned to a machine (lookup by email).\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`email\`\\\* | String | Yes | User or invitee email to revoke from their assigned machine |\
> \| \`keep\_files\` | Boolean | No | Whether to keep user files. Default: true |\
> \
> \### Request Body Example\
> \
> \`\`\` json\
> {\
> &#x20; "email": "<user@example.com>",\
> &#x20; "keep\_files": true\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-10T16:01:24Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Email does not match any user or invitation |\
> \| 4318 | Not a valid email |\
> \| 4710 | Permission required |\
> \| 4714 | User or invitation not assigned to any machine |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/users/revoke":{"post":{"summary":"Revoke User or Invitation from Machine","responses":{"200":{"description":"User or invitation revoked from machine","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Email does not match any user or invitation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4318":{"description":"Not a valid email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4318Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}},"4714":{"description":"User or invitation not assigned to any machine","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4714Response"}}}}},"tags":["Users"],"description":"Revoke the user or invitation assigned to a machine (lookup by email).\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `email`\\* | String | Yes | User or invitee email to revoke from their assigned machine |\n| `keep_files` | Boolean | No | Whether to keep user files. Default: true |\n\n### Request Body Example\n\n``` json\n{\n  \"email\": \"user@example.com\",\n  \"keep_files\": true\n}\n\n ```\n\n### **Success Response Example**\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-10T16:01:24Z\"\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Email does not match any user or invitation |\n| 4318 | Not a valid email |\n| 4710 | Permission required |\n| 4714 | User or invitation not assigned to any machine |","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","description":"User or invitee email to revoke from their assigned machine"},"keep_files":{"type":"boolean","description":"Whether to keep user files. Default true","default":true}}}}}}}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4318Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4714Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Create Invitations

> Create invitations for one or more emails. Requires invitations to be enabled for the organization.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`emails\`\\\* | Array\\\[String\\] | Yes | List of email addresses to invite |\
> \
> \### Request Body Example\
> \
> \`\`\` json\
> {\
> &#x20; "emails": \[\
> &#x20;   "<user1@example.com>", \
> &#x20;   "<user2@example.com>"\
> &#x20; ]\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "invitation\_results": {\
> &#x20;       "success": \[\
> &#x20;         "<user1@example.com>"\
> &#x20;       ],\
> &#x20;       "failed": \[\
> &#x20;         "<user2@example.com>"\
> &#x20;       ]\
> &#x20;   },\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-09T12:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`invitation\_results\` | Object | Result of invitation requests |\
> \| \`invitation\_results.success\` | Array\\\[String\\] | Emails invited successfully |\
> \| \`invitation\_results.failed\` | Array\\\[String\\] | Emails that failed (invalid or not allowed) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 403 | Invitations not enabled for organization |\
> \| 404 | Not Found |\
> \| 4710 | Permission required |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/users/invite":{"post":{"summary":"Create Invitations","responses":{"200":{"description":"Invitation results (success and failed arrays)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationResultsResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"403":{"description":"Invitations not enabled for organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error403Response"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Users"],"description":"Create invitations for one or more emails. Requires invitations to be enabled for the organization.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `emails`\\* | Array\\[String\\] | Yes | List of email addresses to invite |\n\n### Request Body Example\n\n``` json\n{\n  \"emails\": [\n    \"user1@example.com\", \n    \"user2@example.com\"\n  ]\n}\n\n ```\n\n### **Success Response Example**\n\n``` json\n{\n    \"invitation_results\": {\n        \"success\": [\n          \"user1@example.com\"\n        ],\n        \"failed\": [\n          \"user2@example.com\"\n        ]\n    },\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-09T12:00:00Z\"\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `invitation_results` | Object | Result of invitation requests |\n| `invitation_results.success` | Array\\[String\\] | Emails invited successfully |\n| `invitation_results.failed` | Array\\[String\\] | Emails that failed (invalid or not allowed) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 403 | Invitations not enabled for organization |\n| 404 | Not Found |\n| 4710 | Permission required |","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["emails"],"properties":{"emails":{"type":"array","items":{"type":"string"},"description":"List of email addresses to invite"}}}}}}}}},"components":{"schemas":{"InvitationResultsResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"invitation_results":{"type":"object","properties":{"success":{"type":"array","items":{"type":"string"},"description":"Emails that were invited successfully"},"failed":{"type":"array","items":{"type":"string"},"description":"Emails that failed (invalid or not allowed)"}}}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error403Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````


# User Action Logs

## Get Recent Administrative Logs

> Retrieves user activity logs from the last 30 days.\
> \
> This endpoint fetches logs stored in PostgreSQL (recent logs within retention period). Logs older than 30 days are archived in S3 and must be accessed via the archived-download-urls endpoint.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Query Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`start\_date\` | DateTime | Yes | Start date in ISO 8601 format. E.g., \`2024-01-01T00:00:00Z\` |\
> \| \`end\_date\` | DateTime | Yes | End date in ISO 8601 format. Must be after \`start\_date\`. E.g., \`2024-01-31T23:59:59Z\` |\
> \| \`action\_type\` | String | No | Filter by action type. See action types list below |\
> \| \`user\_email\` | String | No | Filter by user email address |\
> \| \`organization\_machine\_id\` | Integer | No | Filter by machine ID |\
> \
> \### \*\*Retention Policy\*\*\
> \
> \- Logs from the last 30 days are stored in PostgreSQL (fast querying)\
> &#x20;   \
> \- Logs older than 30 days are archived in S3\
> &#x20;   \
> \- If date range extends beyond 30 days, only the recent portion is returned\
> &#x20;   \
> \- Maximum 1000 logs returned per request\
> &#x20;   \
> \
> \### \*\*Action Types\*\*\
> \
> \| Action Type | Description |\
> \| --- | --- |\
> \| \`machine\_started\` | Machine was started |\
> \| \`machine\_stopped\` | Machine was stopped |\
> \| \`machine\_reset\` | Machine was reset to factory settings |\
> \| \`machine\_type\_changed\` | Machine type was changed (upgrade/downgrade) |\
> \| \`machine\_external\_access\_created\` | External access token was created |\
> \| \`machine\_created\` | Machine was created |\
> \| \`file\_downloaded\` | File was downloaded |\
> \| \`file\_uploaded\` | File upload was completed |\
> \| \`file\_deleted\` | File or folder was deleted |\
> \| \`folder\_created\` | Folder was created |\
> \| \`user\_login\` | User logged in |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Not found |\
> \| 4221 | End date must be after start date |\
> \| 4710 | Permission required |\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`logs\` | Array | Array of log entry objects |\
> \| \`logs\[].id\` | Integer | Log entry ID |\
> \| \`logs\[].action\_type\` | String | Action type (see action types table above) |\
> \| \`logs\[].user\_id\` | Integer | User ID who performed the action |\
> \| \`logs\[].user\_email\` | String | Email address of user who performed the action |\
> \| \`logs\[].machine\_id\` | Integer | Machine ID (organization\_machine\_id). null if action not related to a machine |\
> \| \`logs\[].metadata\` | Object | Additional metadata specific to the action type. Structure varies by action |\
> \| \`logs\[].created\_at\` | String | ISO 8601 timestamp when log was created |\
> \| \`logs\[].updated\_at\` | String | ISO 8601 timestamp when log was last updated |\
> \| \`count\` | Integer | Total number of logs returned (max 1000) |\
> \| \`start\_date\` | String | Start date used in query (ISO 8601) |\
> \| \`end\_date\` | String | End date used in query (ISO 8601) |\
> \| \`note\` | String | Optional note if date range extends beyond retention period |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \#### \*\*Metadata Examples by Action Type\*\*\
> \
> \- \*\*machine\_started\*\*: \`{ "machine\_type\_id": 1, "machine\_type\_name": "Standard", "region": "dublin" }\`\
> &#x20;   \
> \- \*\*machine\_type\_changed\*\*: \`{ "old\_machine\_type\_id": 1, "new\_machine\_type\_id": 2, "machine\_type\_name": "Performance" }\`\
> &#x20;   \
> \- \*\*file\_deleted\*\*: \`{ "file\_id": 123, "file\_name": "document.pdf", "file\_size": 1048576, "file\_content\_type": "application/pdf", "is\_shared": false, "object\_type": "file" }\`\
> &#x20;   \
> \- \*\*file\_uploaded\*\*: \`{ "file\_id": 123, "file\_name": "document.pdf", "file\_size": 1048576 }\`\
> &#x20;   \
> \
> \### \*\*Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "logs": \[\
> &#x20;   {\
> &#x20;     "id": 1,\
> &#x20;     "action\_type": "machine\_started",\
> &#x20;     "user\_id": 123,\
> &#x20;     "user\_email": "<user@example.com>",\
> &#x20;     "machine\_id": 456,\
> &#x20;     "metadata": {\
> &#x20;       "machine\_type\_id": 1,\
> &#x20;       "machine\_type\_name": "Standard",\
> &#x20;       "region": "dublin"\
> &#x20;     },\
> &#x20;     "created\_at": "2024-01-15T10:30:00Z",\
> &#x20;     "updated\_at": "2024-01-15T10:30:00Z"\
> &#x20;   },\
> &#x20;   {\
> &#x20;     "id": 2,\
> &#x20;     "action\_type": "file\_deleted",\
> &#x20;     "user\_id": 123,\
> &#x20;     "user\_email": "<user@example.com>",\
> &#x20;     "machine\_id": 456,\
> &#x20;     "metadata": {\
> &#x20;       "file\_id": 789,\
> &#x20;       "file\_name": "document.pdf",\
> &#x20;       "file\_size": 1048576,\
> &#x20;       "file\_content\_type": "application/pdf",\
> &#x20;       "is\_shared": false,\
> &#x20;       "object\_type": "file"\
> &#x20;     },\
> &#x20;     "created\_at": "2024-01-15T11:00:00Z",\
> &#x20;     "updated\_at": "2024-01-15T11:00:00Z"\
> &#x20;   }\
> &#x20; ],\
> &#x20; "count": 150,\
> &#x20; "start\_date": "2024-01-01T00:00:00Z",\
> &#x20; "end\_date": "2024-01-31T23:59:59Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Note\*\*\
> \
> For logs older than 30 days, use the \`archived-download-urls\` endpoint. If the date range extends beyond the retention period, the response will include a \`note\` field indicating to use the archived endpoint.

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/user-action-logs":{"get":{"summary":"Get Recent Administrative Logs","responses":{"200":{"description":"User action logs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserActionLogsResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4221":{"description":"End date must be after start date","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4221Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"parameters":[{"name":"start_date","in":"query","description":"(Required) Start date. ISO 8601 format (e.g., 2024-01-01T00:00:00Z)","schema":{"type":"string"}},{"name":"end_date","in":"query","description":"(Required) End date. ISO 8601 format. Must be after start_date.","schema":{"type":"string"}},{"name":"action_type","in":"query","description":"(Optional) Action type filter. E.g., machine_started, machine_stopped, file_downloaded","schema":{"type":"string"}},{"name":"user_email","in":"query","description":"(Optional) Filter by user email","schema":{"type":"string"}},{"name":"organization_machine_id","in":"query","description":"(Optional) Filter by machine ID","schema":{"type":"string"}}],"tags":["User Action Logs"],"description":"Retrieves user activity logs from the last 30 days.\n\nThis endpoint fetches logs stored in PostgreSQL (recent logs within retention period). Logs older than 30 days are archived in S3 and must be accessed via the archived-download-urls endpoint.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Query Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `start_date` | DateTime | Yes | Start date in ISO 8601 format. E.g., `2024-01-01T00:00:00Z` |\n| `end_date` | DateTime | Yes | End date in ISO 8601 format. Must be after `start_date`. E.g., `2024-01-31T23:59:59Z` |\n| `action_type` | String | No | Filter by action type. See action types list below |\n| `user_email` | String | No | Filter by user email address |\n| `organization_machine_id` | Integer | No | Filter by machine ID |\n\n### **Retention Policy**\n\n- Logs from the last 30 days are stored in PostgreSQL (fast querying)\n    \n- Logs older than 30 days are archived in S3\n    \n- If date range extends beyond 30 days, only the recent portion is returned\n    \n- Maximum 1000 logs returned per request\n    \n\n### **Action Types**\n\n| Action Type | Description |\n| --- | --- |\n| `machine_started` | Machine was started |\n| `machine_stopped` | Machine was stopped |\n| `machine_reset` | Machine was reset to factory settings |\n| `machine_type_changed` | Machine type was changed (upgrade/downgrade) |\n| `machine_external_access_created` | External access token was created |\n| `machine_created` | Machine was created |\n| `file_downloaded` | File was downloaded |\n| `file_uploaded` | File upload was completed |\n| `file_deleted` | File or folder was deleted |\n| `folder_created` | Folder was created |\n| `user_login` | User logged in |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Not found |\n| 4221 | End date must be after start date |\n| 4710 | Permission required |\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `logs` | Array | Array of log entry objects |\n| `logs[].id` | Integer | Log entry ID |\n| `logs[].action_type` | String | Action type (see action types table above) |\n| `logs[].user_id` | Integer | User ID who performed the action |\n| `logs[].user_email` | String | Email address of user who performed the action |\n| `logs[].machine_id` | Integer | Machine ID (organization_machine_id). null if action not related to a machine |\n| `logs[].metadata` | Object | Additional metadata specific to the action type. Structure varies by action |\n| `logs[].created_at` | String | ISO 8601 timestamp when log was created |\n| `logs[].updated_at` | String | ISO 8601 timestamp when log was last updated |\n| `count` | Integer | Total number of logs returned (max 1000) |\n| `start_date` | String | Start date used in query (ISO 8601) |\n| `end_date` | String | End date used in query (ISO 8601) |\n| `note` | String | Optional note if date range extends beyond retention period |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n#### **Metadata Examples by Action Type**\n\n- **machine_started**: `{ \"machine_type_id\": 1, \"machine_type_name\": \"Standard\", \"region\": \"dublin\" }`\n    \n- **machine_type_changed**: `{ \"old_machine_type_id\": 1, \"new_machine_type_id\": 2, \"machine_type_name\": \"Performance\" }`\n    \n- **file_deleted**: `{ \"file_id\": 123, \"file_name\": \"document.pdf\", \"file_size\": 1048576, \"file_content_type\": \"application/pdf\", \"is_shared\": false, \"object_type\": \"file\" }`\n    \n- **file_uploaded**: `{ \"file_id\": 123, \"file_name\": \"document.pdf\", \"file_size\": 1048576 }`\n    \n\n### **Response Example**\n\n``` json\n{\n  \"logs\": [\n    {\n      \"id\": 1,\n      \"action_type\": \"machine_started\",\n      \"user_id\": 123,\n      \"user_email\": \"user@example.com\",\n      \"machine_id\": 456,\n      \"metadata\": {\n        \"machine_type_id\": 1,\n        \"machine_type_name\": \"Standard\",\n        \"region\": \"dublin\"\n      },\n      \"created_at\": \"2024-01-15T10:30:00Z\",\n      \"updated_at\": \"2024-01-15T10:30:00Z\"\n    },\n    {\n      \"id\": 2,\n      \"action_type\": \"file_deleted\",\n      \"user_id\": 123,\n      \"user_email\": \"user@example.com\",\n      \"machine_id\": 456,\n      \"metadata\": {\n        \"file_id\": 789,\n        \"file_name\": \"document.pdf\",\n        \"file_size\": 1048576,\n        \"file_content_type\": \"application/pdf\",\n        \"is_shared\": false,\n        \"object_type\": \"file\"\n      },\n      \"created_at\": \"2024-01-15T11:00:00Z\",\n      \"updated_at\": \"2024-01-15T11:00:00Z\"\n    }\n  ],\n  \"count\": 150,\n  \"start_date\": \"2024-01-01T00:00:00Z\",\n  \"end_date\": \"2024-01-31T23:59:59Z\"\n}\n\n ```\n\n### **Note**\n\nFor logs older than 30 days, use the `archived-download-urls` endpoint. If the date range extends beyond the retention period, the response will include a `note` field indicating to use the archived endpoint."}}},"components":{"schemas":{"UserActionLogsResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"logs":{"type":"array","description":"List of user action logs","items":{"$ref":"#/components/schemas/UserActionLog"}},"count":{"type":"integer","description":"Total number of logs"},"start_date":{"type":"string","format":"date-time","description":"Query start date"},"end_date":{"type":"string","format":"date-time","description":"Query end date"},"note":{"type":"string","nullable":true,"description":"Additional notes about the response"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"UserActionLog":{"type":"object","description":"Record of a user action in the system","properties":{"id":{"type":"integer","description":"Log entry ID"},"action_type":{"type":"string","enum":["machine_started","machine_stopped","machine_reset","machine_type_changed","machine_external_access_created","machine_created","file_downloaded","file_uploaded","file_deleted","folder_created","user_login"],"description":"Type of action performed"},"user_id":{"type":"integer","description":"ID of the user who performed the action"},"user_email":{"type":"string","description":"Email of the user who performed the action"},"machine_id":{"type":"integer","nullable":true,"description":"Associated machine ID (if applicable)"},"metadata":{"type":"object","additionalProperties":true,"description":"Additional action-specific metadata"},"created_at":{"type":"string","format":"date-time","description":"Timestamp when the action occurred"},"updated_at":{"type":"string","format":"date-time","description":"Timestamp when the log entry was last updated"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4221Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Get Archived Administrative Logs

> Generates presigned S3 download URLs for archived logs older than 30 days.\
> \
> This endpoint provides download URLs for logs that have been archived to S3. Logs are archived monthly, so each URL typically contains one month of logs.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Query Parameters\*\*\
> \
> \| Parameter | Type | Required | Default | Description |\
> \| --- | --- | --- | --- | --- |\
> \| \`start\_date\` | DateTime | Yes | \\- | Start date in ISO 8601 format. Must be older than 30 days. E.g., \`2023-01-01T00:00:00Z\` |\
> \| \`end\_date\` | DateTime | Yes | \\- | End date in ISO 8601 format. Must be older than 30 days. Must be after \`start\_date\`. E.g., \`2023-12-31T23:59:59Z\` |\
> \| \`expires\_in\` | Integer | No | 600 | Presigned URL validity duration in seconds. Default: 600 (10 minutes). Maximum recommended: 3600 (1 hour) |\
> \
> \##### \*\*Restrictions\*\*\
> \
> \- Can only be used for logs older than 30 days\
> &#x20;   \
> \- Use the main \`/user-action-logs\` endpoint for logs from the last 30 days\
> &#x20;   \
> \- Date range must be entirely within the archived period\
> &#x20;   \
> \
> \##### \*\*Validation\*\*\
> \
> \- \`end\_date\` must be after \`start\_date\`\
> &#x20;   \
> \- Both dates must be older than 30 days\
> &#x20;   \
> \- Both dates must be in the past\
> &#x20;   \
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 4222 | This endpoint is for archived logs only |\
> \| 4710 | Permission required |\
> \
> \*\*Response Fields:\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`download\_urls\` | Array | Array of presigned S3 download URLs. Each URL typically contains one month of logs |\
> \| \`download\_urls\[]\` | String | Presigned S3 URL for downloading archived log file. URL expires after \`expires\_in\` seconds |\
> \| \`count\` | Integer | Number of download URLs generated |\
> \| \`start\_date\` | String | Start date used in query (ISO 8601) |\
> \| \`end\_date\` | String | End date used in query (ISO 8601) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \*\*Response Example:\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "download\_urls": \[\
> &#x20;   "<https://s3.amazonaws.com/vagon-logs/org-123/2023-01.json.gz?X-Amz-Signature=abc123...\\&X-Amz-Expires=600",\\>
> &#x20;   "<https://s3.amazonaws.com/vagon-logs/org-123/2023-02.json.gz?X-Amz-Signature=def456...\\&X-Amz-Expires=600",\\>
> &#x20;   "<https://s3.amazonaws.com/vagon-logs/org-123/2023-03.json.gz?X-Amz-Signature=ghi789...\\&X-Amz-Expires=600"\\>
> &#x20; ],\
> &#x20; "count": 12,\
> &#x20; "start\_date": "2023-01-01T00:00:00Z",\
> &#x20; "end\_date": "2023-12-31T23:59:59Z",\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \*\*Usage Instructions:\*\*\
> \
> 1\. \*\*Download Files\*\*: Make HTTP GET requests to each URL in \`download\_urls\` array\
> &#x20;   \
> 2\. \*\*File Format\*\*: Files are in \`.json.gz\` format (gzip-compressed JSON)\
> &#x20;   \
> 3\. \*\*Content\*\*: Each file typically contains one month of logs in JSON format\
> &#x20;   \
> 4\. \*\*Decompression\*\*: Decompress the \`.gz\` files to get JSON data\
> &#x20;   \
> 5\. \*\*URL Expiration\*\*: URLs expire after \`expires\_in\` seconds (default 10 minutes)\
> &#x20;   \
> 6\. \*\*Download Timing\*\*: Download all URLs promptly after receiving the response\
> &#x20;   \
> \
> \*\*File Structure:\*\*  \
> Each downloaded file contains an array of log objects with the same structure as the main endpoint response.

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/user-action-logs/archived-download-urls":{"get":{"summary":"Get Archived Administrative Logs","responses":{"200":{"description":"Archived log download URLs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArchivedLogsResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"4222":{"description":"This endpoint is for archived logs only","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4222Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"parameters":[{"name":"start_date","in":"query","description":"(Required) Start date. Must be older than 30 days.","schema":{"type":"string"}},{"name":"end_date","in":"query","description":"(Required) End date. Must be older than 30 days.","schema":{"type":"string"}},{"name":"expires_in","in":"query","description":"(Optional) URL validity duration (seconds). Default: 600 (10 minutes)","schema":{"type":"integer"}}],"tags":["User Action Logs"],"description":"Generates presigned S3 download URLs for archived logs older than 30 days.\n\nThis endpoint provides download URLs for logs that have been archived to S3. Logs are archived monthly, so each URL typically contains one month of logs.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Query Parameters**\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `start_date` | DateTime | Yes | \\- | Start date in ISO 8601 format. Must be older than 30 days. E.g., `2023-01-01T00:00:00Z` |\n| `end_date` | DateTime | Yes | \\- | End date in ISO 8601 format. Must be older than 30 days. Must be after `start_date`. E.g., `2023-12-31T23:59:59Z` |\n| `expires_in` | Integer | No | 600 | Presigned URL validity duration in seconds. Default: 600 (10 minutes). Maximum recommended: 3600 (1 hour) |\n\n##### **Restrictions**\n\n- Can only be used for logs older than 30 days\n    \n- Use the main `/user-action-logs` endpoint for logs from the last 30 days\n    \n- Date range must be entirely within the archived period\n    \n\n##### **Validation**\n\n- `end_date` must be after `start_date`\n    \n- Both dates must be older than 30 days\n    \n- Both dates must be in the past\n    \n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 4222 | This endpoint is for archived logs only |\n| 4710 | Permission required |\n\n**Response Fields:**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `download_urls` | Array | Array of presigned S3 download URLs. Each URL typically contains one month of logs |\n| `download_urls[]` | String | Presigned S3 URL for downloading archived log file. URL expires after `expires_in` seconds |\n| `count` | Integer | Number of download URLs generated |\n| `start_date` | String | Start date used in query (ISO 8601) |\n| `end_date` | String | End date used in query (ISO 8601) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n**Response Example:**\n\n``` json\n{\n  \"download_urls\": [\n    \"https://s3.amazonaws.com/vagon-logs/org-123/2023-01.json.gz?X-Amz-Signature=abc123...&X-Amz-Expires=600\",\n    \"https://s3.amazonaws.com/vagon-logs/org-123/2023-02.json.gz?X-Amz-Signature=def456...&X-Amz-Expires=600\",\n    \"https://s3.amazonaws.com/vagon-logs/org-123/2023-03.json.gz?X-Amz-Signature=ghi789...&X-Amz-Expires=600\"\n  ],\n  \"count\": 12,\n  \"start_date\": \"2023-01-01T00:00:00Z\",\n  \"end_date\": \"2023-12-31T23:59:59Z\",\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n**Usage Instructions:**\n\n1. **Download Files**: Make HTTP GET requests to each URL in `download_urls` array\n    \n2. **File Format**: Files are in `.json.gz` format (gzip-compressed JSON)\n    \n3. **Content**: Each file typically contains one month of logs in JSON format\n    \n4. **Decompression**: Decompress the `.gz` files to get JSON data\n    \n5. **URL Expiration**: URLs expire after `expires_in` seconds (default 10 minutes)\n    \n6. **Download Timing**: Download all URLs promptly after receiving the response\n    \n\n**File Structure:**  \nEach downloaded file contains an array of log objects with the same structure as the main endpoint response."}}},"components":{"schemas":{"ArchivedLogsResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"download_urls":{"type":"array","description":"List of URLs to download archived log files","items":{"type":"string","format":"uri"}},"count":{"type":"integer","description":"Total number of download URLs"},"start_date":{"type":"string","format":"date-time","description":"Query start date"},"end_date":{"type":"string","format":"date-time","description":"Query end date"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error4222Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````


# Images

## List Available Images

> Lists all organization images (templates).\
> \
> This endpoint returns all silver images (templates) created by the organization. Images can be created from machines or installed with pre-configured software.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Query Parameters\*\*\
> \
> \| Parameter | Type | Default | Description |\
> \| --- | --- | --- | --- |\
> \| \`page\` | Integer | 1 | Page number |\
> \| \`per\_page\` | Integer | 20 | Record count per page |\
> \| \`q\` | String | \\- | Search query by image name |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "images": \[\
> &#x20;       {\
> &#x20;           "id": "347",\
> &#x20;           "type": "image",\
> &#x20;           "attributes": {\
> &#x20;               "id": 347,\
> &#x20;               "name": "My Custom Template",\
> &#x20;               "size": 75,\
> &#x20;               "status": "available",\
> &#x20;               "source": "seat",\
> &#x20;               "created\_at": "2026-02-04T12:47:07.761Z",\
> &#x20;               "updated\_at": "2026-02-04T12:48:11.194Z",\
> &#x20;               "softwares": \[]\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "346",\
> &#x20;           "type": "image",\
> &#x20;           "attributes": {\
> &#x20;               "id": 346,\
> &#x20;               "name": "Template #346",\
> &#x20;               "size": 21,\
> &#x20;               "status": "available",\
> &#x20;               "source": "pre\_installation",\
> &#x20;               "created\_at": "2026-02-03T14:37:20.238Z",\
> &#x20;               "updated\_at": "2026-02-03T14:48:13.643Z",\
> &#x20;               "softwares": \[\
> &#x20;                   {\
> &#x20;                       "id": "1",\
> &#x20;                       "type": "software",\
> &#x20;                       "attributes": {\
> &#x20;                           "id": 1,\
> &#x20;                           "name": "Blender",\
> &#x20;                           "size": 1.4\
> &#x20;                       }\
> &#x20;                   }\
> &#x20;               ]\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "count": 2,\
> &#x20;   "page": 1,\
> &#x20;   "next\_page": 2,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T12:50:06Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`images\` | Array | Array of image objects |\
> \| \`images\[].id\` | String | Image ID |\
> \| \`images\[].type\` | String | Always "image" |\
> \| \`images\[].attributes.id\` | Integer | Image ID (numeric) |\
> \| \`images\[].attributes.name\` | String | Image name |\
> \| \`images\[].attributes.size\` | Integer | Image size in GB |\
> \| \`images\[].attributes.status\` | String | Image status: \`pending\`, \`building\`, \`available\`, \`failed\` |\
> \| \`images\[].attributes.source\` | String | Image source: \`pre\_installation\` (created with software) or \`seat\` (created from machine) |\
> \| \`images\[].attributes.created\_at\` | String | Creation timestamp (ISO 8601) |\
> \| \`images\[].attributes.updated\_at\` | String | Last update timestamp (ISO 8601) |\
> \| \`images\[].attributes.softwares\` | Array | Array of pre-installed software (if source is \`pre\_installation\`) |\
> \| \`count\` | Integer | Total number of images |\
> \| \`page\` | Integer | Current page number |\
> \| \`next\_page\` | Integer | Next page number. null if last page |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/images":{"get":{"summary":"List Available Images","parameters":[{"name":"page","in":"query","description":"(Optional) Page number. Default: 1","schema":{"type":"integer"}},{"name":"per_page","in":"query","description":"(Optional) Records per page. Default: 20","schema":{"type":"integer"}},{"name":"q","in":"query","description":"(Optional) Search by image name","schema":{"type":"string"}}],"responses":{"200":{"description":"List of images","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListImagesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Images"],"description":"Lists all organization images (templates).\n\nThis endpoint returns all silver images (templates) created by the organization. Images can be created from machines or installed with pre-configured software.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Query Parameters**\n\n| Parameter | Type | Default | Description |\n| --- | --- | --- | --- |\n| `page` | Integer | 1 | Page number |\n| `per_page` | Integer | 20 | Record count per page |\n| `q` | String | \\- | Search query by image name |\n\n### **Success Response Example**\n\n``` json\n{\n    \"images\": [\n        {\n            \"id\": \"347\",\n            \"type\": \"image\",\n            \"attributes\": {\n                \"id\": 347,\n                \"name\": \"My Custom Template\",\n                \"size\": 75,\n                \"status\": \"available\",\n                \"source\": \"seat\",\n                \"created_at\": \"2026-02-04T12:47:07.761Z\",\n                \"updated_at\": \"2026-02-04T12:48:11.194Z\",\n                \"softwares\": []\n            }\n        },\n        {\n            \"id\": \"346\",\n            \"type\": \"image\",\n            \"attributes\": {\n                \"id\": 346,\n                \"name\": \"Template #346\",\n                \"size\": 21,\n                \"status\": \"available\",\n                \"source\": \"pre_installation\",\n                \"created_at\": \"2026-02-03T14:37:20.238Z\",\n                \"updated_at\": \"2026-02-03T14:48:13.643Z\",\n                \"softwares\": [\n                    {\n                        \"id\": \"1\",\n                        \"type\": \"software\",\n                        \"attributes\": {\n                            \"id\": 1,\n                            \"name\": \"Blender\",\n                            \"size\": 1.4\n                        }\n                    }\n                ]\n            }\n        }\n    ],\n    \"count\": 2,\n    \"page\": 1,\n    \"next_page\": 2,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T12:50:06Z\"\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `images` | Array | Array of image objects |\n| `images[].id` | String | Image ID |\n| `images[].type` | String | Always \"image\" |\n| `images[].attributes.id` | Integer | Image ID (numeric) |\n| `images[].attributes.name` | String | Image name |\n| `images[].attributes.size` | Integer | Image size in GB |\n| `images[].attributes.status` | String | Image status: `pending`, `building`, `available`, `failed` |\n| `images[].attributes.source` | String | Image source: `pre_installation` (created with software) or `seat` (created from machine) |\n| `images[].attributes.created_at` | String | Creation timestamp (ISO 8601) |\n| `images[].attributes.updated_at` | String | Last update timestamp (ISO 8601) |\n| `images[].attributes.softwares` | Array | Array of pre-installed software (if source is `pre_installation`) |\n| `count` | Integer | Total number of images |\n| `page` | Integer | Current page number |\n| `next_page` | Integer | Next page number. null if last page |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |"}}},"components":{"schemas":{"ListImagesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"images":{"type":"array","items":{"$ref":"#/components/schemas/Image"}},"count":{"type":"integer","description":"Total number of images"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Image":{"type":"object","description":"Image (template) object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/ImageAttributes"}}},"ImageAttributes":{"type":"object","description":"Image (template) attributes","properties":{"id":{"type":"integer","description":"Image ID"},"name":{"type":"string","description":"Image name"},"size":{"type":"integer","description":"Image size in GB"},"status":{"type":"string","enum":["pending","building","available","failed"],"description":"Image build status"},"source":{"type":"string","enum":["pre_installation","seat"],"description":"How the image was created"},"created_at":{"type":"string","format":"date-time","description":"Image creation timestamp"},"updated_at":{"type":"string","format":"date-time","description":"Image last update timestamp"},"softwares":{"type":"array","description":"List of pre-installed software in this image","items":{"$ref":"#/components/schemas/SoftwareData"}}}},"SoftwareData":{"type":"object","description":"Software data with id, type, and attributes wrapper","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/Software"}}},"Software":{"type":"object","description":"Software package that can be pre-installed on images","properties":{"id":{"type":"integer","description":"Software ID"},"name":{"type":"string","description":"Software name"},"size":{"type":"number","format":"float","description":"Software size in GB"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Create Image from Machine

> Creates an image (template) from an existing machine.\
> \
> The machine must be stopped (off) and have an available image. The created image can then be assigned to other machines.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`machine\_id\`\\\* | Integer | Yes | Machine ID to create image from |\
> \| \`name\` | String | No | Custom name for the image (max 30 characters). If not provided, auto-generated as "Template #{image\_id}" |\
> \
> \### Request Body\
> \
> \`\`\` json\
> {\
> &#x20; "machine\_id": 1,\
> &#x20; "name": "My Custom Template"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "id": "347",\
> &#x20;   "type": "image",\
> &#x20;   "attributes": {\
> &#x20;       "id": 347,\
> &#x20;       "name": "My Custom Template",\
> &#x20;       "size": 75,\
> &#x20;       "status": "pending",\
> &#x20;       "source": "seat",\
> &#x20;       "created\_at": "2026-02-04T12:47:07.761Z",\
> &#x20;       "updated\_at": "2026-02-04T12:47:07.761Z",\
> &#x20;       "softwares": \[]\
> &#x20;   },\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T12:47:07Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Machine not found or does not belong to organization |\
> \| 4208 | Machine image not found |\
> \| 4209 | Machine is not stopped |\
> \| 4212 | Machine image is still being created |\
> \| 4710 | Permission required |\
> \
> \### \*\*Notes\*\*\
> \
> \- Machine status will be set to \`installing\` during image creation\
> \- Image creation is asynchronous and may take time\
> \- Image status will be \`pending\` initially, then \`building\`, and finally \`available\` when ready\
> \- Only machines that are stopped (off) can be used to create images

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/images":{"post":{"summary":"Create Image from Machine","responses":{"200":{"description":"Image created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateImageResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4208":{"description":"Machine has no image","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4208Response"}}}},"4209":{"description":"Machine is not stopped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4209Response"}}}},"4212":{"description":"Machine has pending image","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4212Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Images"],"description":"Creates an image (template) from an existing machine.\n\nThe machine must be stopped (off) and have an available image. The created image can then be assigned to other machines.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `machine_id`\\* | Integer | Yes | Machine ID to create image from |\n| `name` | String | No | Custom name for the image (max 30 characters). If not provided, auto-generated as \"Template #{image_id}\" |\n\n### Request Body\n\n``` json\n{\n  \"machine_id\": 1,\n  \"name\": \"My Custom Template\"\n}\n\n ```\n\n### **Success Response Example**\n\n``` json\n{\n    \"id\": \"347\",\n    \"type\": \"image\",\n    \"attributes\": {\n        \"id\": 347,\n        \"name\": \"My Custom Template\",\n        \"size\": 75,\n        \"status\": \"pending\",\n        \"source\": \"seat\",\n        \"created_at\": \"2026-02-04T12:47:07.761Z\",\n        \"updated_at\": \"2026-02-04T12:47:07.761Z\",\n        \"softwares\": []\n    },\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T12:47:07Z\"\n}\n\n ```\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Machine not found or does not belong to organization |\n| 4208 | Machine image not found |\n| 4209 | Machine is not stopped |\n| 4212 | Machine image is still being created |\n| 4710 | Permission required |\n\n### **Notes**\n\n- Machine status will be set to `installing` during image creation\n- Image creation is asynchronous and may take time\n- Image status will be `pending` initially, then `building`, and finally `available` when ready\n- Only machines that are stopped (off) can be used to create images","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["machine_id","name"],"properties":{"machine_id":{"type":"integer","description":"ID of the machine to create image from"},"name":{"type":"string","maxLength":30,"description":"Name for the new image template. Max 30 characters."}}}}}}}}},"components":{"schemas":{"CreateImageResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"$ref":"#/components/schemas/Image"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Image":{"type":"object","description":"Image (template) object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/ImageAttributes"}}},"ImageAttributes":{"type":"object","description":"Image (template) attributes","properties":{"id":{"type":"integer","description":"Image ID"},"name":{"type":"string","description":"Image name"},"size":{"type":"integer","description":"Image size in GB"},"status":{"type":"string","enum":["pending","building","available","failed"],"description":"Image build status"},"source":{"type":"string","enum":["pre_installation","seat"],"description":"How the image was created"},"created_at":{"type":"string","format":"date-time","description":"Image creation timestamp"},"updated_at":{"type":"string","format":"date-time","description":"Image last update timestamp"},"softwares":{"type":"array","description":"List of pre-installed software in this image","items":{"$ref":"#/components/schemas/SoftwareData"}}}},"SoftwareData":{"type":"object","description":"Software data with id, type, and attributes wrapper","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/Software"}}},"Software":{"type":"object","description":"Software package that can be pre-installed on images","properties":{"id":{"type":"integer","description":"Software ID"},"name":{"type":"string","description":"Software name"},"size":{"type":"number","format":"float","description":"Software size in GB"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4208Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4209Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4212Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Create Image from Application List

> Creates an image (template) with pre-installed software.\
> \
> This endpoint creates a new image by installing software on a base image. The image can then be assigned to machines.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`name\` | String | No | Custom name for the image (max 30 characters). If not provided, auto-generated as "Template #{base\_image\_id}" |\
> \| \`software\_ids\` | Array\\\[Integer\\] | No | Array of software IDs to pre-install. Use \`GET /software\` to see available software. Default: empty array |\
> \| \`base\_image\_id\` | Integer | No | Base image ID. If not provided, uses the latest base image. Use \`GET /software\` to see available base images |\
> \
> \### Request Body\
> \
> \`\`\` json\
> {\
> &#x20; "name": "Design Suite Template",\
> &#x20; "software\_ids": \[1, 2],\
> &#x20; "base\_image\_id": 1\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "id": "1",\
> &#x20; "type": "image",\
> &#x20; "attributes": {\
> &#x20;   "id": 1,\
> &#x20;   "name": "Design Suite Template",\
> &#x20;   "size": 107374182400,\
> &#x20;   "status": "pending",\
> &#x20;   "source": "pre\_installation",\
> &#x20;   "created\_at": "2024-01-15T10:00:00Z",\
> &#x20;   "updated\_at": "2024-01-15T10:00:00Z",\
> &#x20;   "softwares": {\
> &#x20;     "data": \[\
> &#x20;       {\
> &#x20;         "id": "1",\
> &#x20;         "type": "software",\
> &#x20;         "attributes": {\
> &#x20;           "id": 1,\
> &#x20;           "name": "Adobe Photoshop",\
> &#x20;           "size": 5583457484\
> &#x20;         }\
> &#x20;       },\
> &#x20;       {\
> &#x20;         "id": "1",\
> &#x20;         "type": "software",\
> &#x20;         "attributes": {\
> &#x20;           "id": 2,\
> &#x20;           "name": "Blender",\
> &#x20;           "size": 5583457484\
> &#x20;         }\
> &#x20;       }\
> &#x20;     ]\
> &#x20;   }\
> &#x20; }\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | String | Image ID |\
> \| \`type\` | String | Always "image" |\
> \| \`attributes.id\` | Integer | Image ID (numeric) |\
> \| \`attributes.name\` | String | Image name |\
> \| \`attributes.size\` | Integer | Image size in GB (includes 5% buffer) |\
> \| \`attributes.status\` | String | Image status: \`pending\` initially, then \`building\`, and finally \`available\` |\
> \| \`attributes.source\` | String | Always \`pre\_installation\` for this endpoint |\
> \| \`attributes.created\_at\` | String | Creation timestamp (ISO 8601) |\
> \| \`attributes.updated\_at\` | String | Last update timestamp (ISO 8601) |\
> \| \`attributes.softwares\` | Object | Array of pre-installed software |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Base image not found (if base\_image\_id provided) |\
> \| 4710 | Permission required |\
> \
> \### \*\*Notes\*\*\
> \
> \- Image creation is asynchronous and may take time\
> &#x20;   \
> \- Image size is calculated with a 5% buffer\
> &#x20;   \
> \- If \`software\_ids\` is empty, only the base image size (with buffer) is used\
> &#x20;   \
> \- Image status will be \`pending\` initially, then \`building\`, and finally \`available\` when ready\
> &#x20;   \
> \- Use \`GET /images/:id\` to check image status

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/images/install":{"post":{"summary":"Create Image from Application List","responses":{"200":{"description":"Image created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateImageResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Base image not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Images"],"description":"Creates an image (template) with pre-installed software.\n\nThis endpoint creates a new image by installing software on a base image. The image can then be assigned to machines.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `name` | String | No | Custom name for the image (max 30 characters). If not provided, auto-generated as \"Template #{base_image_id}\" |\n| `software_ids` | Array\\[Integer\\] | No | Array of software IDs to pre-install. Use `GET /software` to see available software. Default: empty array |\n| `base_image_id` | Integer | No | Base image ID. If not provided, uses the latest base image. Use `GET /software` to see available base images |\n\n### Request Body\n\n``` json\n{\n  \"name\": \"Design Suite Template\",\n  \"software_ids\": [1, 2],\n  \"base_image_id\": 1\n}\n\n ```\n\n### **Success Response Example**\n\n``` json\n{\n  \"id\": \"1\",\n  \"type\": \"image\",\n  \"attributes\": {\n    \"id\": 1,\n    \"name\": \"Design Suite Template\",\n    \"size\": 107374182400,\n    \"status\": \"pending\",\n    \"source\": \"pre_installation\",\n    \"created_at\": \"2024-01-15T10:00:00Z\",\n    \"updated_at\": \"2024-01-15T10:00:00Z\",\n    \"softwares\": {\n      \"data\": [\n        {\n          \"id\": \"1\",\n          \"type\": \"software\",\n          \"attributes\": {\n            \"id\": 1,\n            \"name\": \"Adobe Photoshop\",\n            \"size\": 5583457484\n          }\n        },\n        {\n          \"id\": \"1\",\n          \"type\": \"software\",\n          \"attributes\": {\n            \"id\": 2,\n            \"name\": \"Blender\",\n            \"size\": 5583457484\n          }\n        }\n      ]\n    }\n  }\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `id` | String | Image ID |\n| `type` | String | Always \"image\" |\n| `attributes.id` | Integer | Image ID (numeric) |\n| `attributes.name` | String | Image name |\n| `attributes.size` | Integer | Image size in GB (includes 5% buffer) |\n| `attributes.status` | String | Image status: `pending` initially, then `building`, and finally `available` |\n| `attributes.source` | String | Always `pre_installation` for this endpoint |\n| `attributes.created_at` | String | Creation timestamp (ISO 8601) |\n| `attributes.updated_at` | String | Last update timestamp (ISO 8601) |\n| `attributes.softwares` | Object | Array of pre-installed software |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Base image not found (if base_image_id provided) |\n| 4710 | Permission required |\n\n### **Notes**\n\n- Image creation is asynchronous and may take time\n    \n- Image size is calculated with a 5% buffer\n    \n- If `software_ids` is empty, only the base image size (with buffer) is used\n    \n- Image status will be `pending` initially, then `building`, and finally `available` when ready\n    \n- Use `GET /images/:id` to check image status","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","base_image_id"],"properties":{"name":{"type":"string","maxLength":30,"description":"Name for the new image template. Max 30 characters."},"software_ids":{"type":"array","description":"List of software IDs to pre-install","items":{"type":"integer"}},"base_image_id":{"type":"integer","description":"Base image ID to build from"}}}}}}}}},"components":{"schemas":{"CreateImageResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"$ref":"#/components/schemas/Image"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Image":{"type":"object","description":"Image (template) object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/ImageAttributes"}}},"ImageAttributes":{"type":"object","description":"Image (template) attributes","properties":{"id":{"type":"integer","description":"Image ID"},"name":{"type":"string","description":"Image name"},"size":{"type":"integer","description":"Image size in GB"},"status":{"type":"string","enum":["pending","building","available","failed"],"description":"Image build status"},"source":{"type":"string","enum":["pre_installation","seat"],"description":"How the image was created"},"created_at":{"type":"string","format":"date-time","description":"Image creation timestamp"},"updated_at":{"type":"string","format":"date-time","description":"Image last update timestamp"},"softwares":{"type":"array","description":"List of pre-installed software in this image","items":{"$ref":"#/components/schemas/SoftwareData"}}}},"SoftwareData":{"type":"object","description":"Software data with id, type, and attributes wrapper","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/Software"}}},"Software":{"type":"object","description":"Software package that can be pre-installed on images","properties":{"id":{"type":"integer","description":"Software ID"},"name":{"type":"string","description":"Software name"},"size":{"type":"number","format":"float","description":"Software size in GB"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Assign Image to Machines

> Assigns an image (template) to one or more machines.\
> \
> This endpoint assigns a template image to machines. The machines will be terminated and recreated with the assigned image on next start. Only images with \`available\` status can be assigned.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Image ID to assign |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`machine\_ids\`\\\* | Array\\\[Integer\\] | Yes | Array of machine IDs to assign the image to |\
> \
> \### Request Body\
> \
> \`\`\` json\
> {\
> &#x20; "machine\_ids": \[1, 2, 3]\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-01-15T15:14:09Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Image not found or does not belong to organization |\
> \| 4210 | Image status is not available (must be \`available\`) |\
> \| 4211 | No machines found or machines do not belong to organization |\
> \| 4214 | Machine is not assignable for template (has pending session image) |\
> \| 4510 | Image size exceeds machine disk size |\
> \| 4710 | Permission required |\
> \
> \### \*\*Notes\*\*\
> \
> \- Only images with \`available\` status can be assigned.\
> &#x20;   \
> \- Machine data will be reset and recreated with the assigned image on next start.\
> &#x20;   \
> \- Image size must not exceed the machine's disk size.\
> &#x20;   \
> \- Machine will be turned to installing machine state, at the first run after the image/template assignment.

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/images/{id}/assign":{"post":{"summary":"Assign Image to Machines","responses":{"200":{"description":"Image assigned successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Image not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4210":{"description":"Image status is not available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4210Response"}}}},"4211":{"description":"No machines found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4211Response"}}}},"4214":{"description":"Machine not assignable for template","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4214Response"}}}},"4510":{"description":"Image size exceeds machine disk size","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4510Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Images"],"description":"Assigns an image (template) to one or more machines.\n\nThis endpoint assigns a template image to machines. The machines will be terminated and recreated with the assigned image on next start. Only images with `available` status can be assigned.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Image ID to assign |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `machine_ids`\\* | Array\\[Integer\\] | Yes | Array of machine IDs to assign the image to |\n\n### Request Body\n\n``` json\n{\n  \"machine_ids\": [1, 2, 3]\n}\n\n ```\n\n### **Success Response**\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-01-15T15:14:09Z\"\n}\n\n ```\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Image not found or does not belong to organization |\n| 4210 | Image status is not available (must be `available`) |\n| 4211 | No machines found or machines do not belong to organization |\n| 4214 | Machine is not assignable for template (has pending session image) |\n| 4510 | Image size exceeds machine disk size |\n| 4710 | Permission required |\n\n### **Notes**\n\n- Only images with `available` status can be assigned.\n    \n- Machine data will be reset and recreated with the assigned image on next start.\n    \n- Image size must not exceed the machine's disk size.\n    \n- Machine will be turned to installing machine state, at the first run after the image/template assignment.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["machine_ids"],"properties":{"machine_ids":{"type":"array","description":"List of machine IDs to assign the image to","items":{"type":"integer"}}}}}}}}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4210Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4211Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4214Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4510Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Delete Image

> Deletes an image (template).\
> \
> This endpoint deletes an organization image. Images that are currently being built cannot be deleted.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Image ID to delete |\
> \
> \### \*\*Success Response\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-01-15T15:14:09Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Image not found or does not belong to organization |\
> \| 4213 | Image is building (cannot delete while building) |\
> \| 4710 | Permission required |\
> \
> \### \*\*Notes\*\*\
> \
> \- Images with \`building\` status cannot be deleted\
> &#x20;   \
> \- Images with \`pending\` or \`available\` status can be deleted\
> &#x20;   \
> \- Deletion is asynchronous and may take time to complete\
> &#x20;   \
> \- The image will be marked as deleted and cleaned up

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/images/{id}":{"delete":{"summary":"Delete Image","responses":{"200":{"description":"Image deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Image not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4213":{"description":"Image is building","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4213Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Images"],"description":"Deletes an image (template).\n\nThis endpoint deletes an organization image. Images that are currently being built cannot be deleted.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Image ID to delete |\n\n### **Success Response**\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-01-15T15:14:09Z\"\n}\n\n ```\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Image not found or does not belong to organization |\n| 4213 | Image is building (cannot delete while building) |\n| 4710 | Permission required |\n\n### **Notes**\n\n- Images with `building` status cannot be deleted\n    \n- Images with `pending` or `available` status can be deleted\n    \n- Deletion is asynchronous and may take time to complete\n    \n- The image will be marked as deleted and cleaned up"}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4213Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````


# Usages

## List Total Account Usage

> Get account/organization level usage information in minutes.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`usage\_minutes\` | Integer | Available usage in minutes |\
> \| \`machine\_type\` | String | Machine type name (e.g., "Planet") |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "usage\_minutes": 2669,\
> &#x20;   "machine\_type": "Planet",\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T13:26:14Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/usage":{"get":{"summary":"List Total Account Usage","responses":{"200":{"description":"Account usage information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Usages"],"description":"Get account/organization level usage information in minutes.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `usage_minutes` | Integer | Available usage in minutes |\n| `machine_type` | String | Machine type name (e.g., \"Planet\") |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Success Response Example**\n\n``` json\n{\n    \"usage_minutes\": 2669,\n    \"machine_type\": \"Planet\",\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T13:26:14Z\"\n}\n\n ```"}}},"components":{"schemas":{"UsageResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","description":"Organization-level usage information","properties":{"usage_minutes":{"type":"integer","description":"Available usage time in minutes"},"machine_type":{"type":"string","description":"Machine type for usage calculation"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## List All Machines Usage

> Get remaining usage information in minutes for all machines.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`machines\` | Array | Array of machine usage objects |\
> \| \`machines\[].machine\_id\` | Integer | Machine ID |\
> \| \`machines\[].machine\_name\` | String | Machine Name |\
> \| \`machines\[].usage\_minutes\` | Integer | Usage minutes based on total balance (including credits) |\
> \| \`machines\[].machine\_type\` | String | Machine type name (e.g., "Planet") |\
> \| \`machines\[].usage\_source\` | String | Usage source - "machine" (only assigned usages) or "team\_balance" (can use team balance when no additional usage on machine) |\
> \| \`count\` | Integer | Total number of machines |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "machines": \[\
> &#x20;       {\
> &#x20;           "machine\_id": 512,\
> &#x20;           "machine\_name": "Computer #512",\
> &#x20;           "usage\_minutes": 0,\
> &#x20;           "machine\_type": "Planet",\
> &#x20;           "usage\_source": "machine"\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "machine\_id": 509,\
> &#x20;           "machine\_name": "Computer #509",\
> &#x20;           "usage\_minutes": 0,\
> &#x20;           "machine\_type": "Planet",\
> &#x20;           "usage\_source": "machine"\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "count": 2,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-01-28T08:46:22Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/usage/machines":{"get":{"summary":"List All Machines Usage","responses":{"200":{"description":"Machine usage list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MachineUsageListResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Usages"],"description":"Get remaining usage information in minutes for all machines.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `machines` | Array | Array of machine usage objects |\n| `machines[].machine_id` | Integer | Machine ID |\n| `machines[].machine_name` | String | Machine Name |\n| `machines[].usage_minutes` | Integer | Usage minutes based on total balance (including credits) |\n| `machines[].machine_type` | String | Machine type name (e.g., \"Planet\") |\n| `machines[].usage_source` | String | Usage source - \"machine\" (only assigned usages) or \"team_balance\" (can use team balance when no additional usage on machine) |\n| `count` | Integer | Total number of machines |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Success Response Example**\n\n``` json\n{\n    \"machines\": [\n        {\n            \"machine_id\": 512,\n            \"machine_name\": \"Computer #512\",\n            \"usage_minutes\": 0,\n            \"machine_type\": \"Planet\",\n            \"usage_source\": \"machine\"\n        },\n        {\n            \"machine_id\": 509,\n            \"machine_name\": \"Computer #509\",\n            \"usage_minutes\": 0,\n            \"machine_type\": \"Planet\",\n            \"usage_source\": \"machine\"\n        }\n    ],\n    \"count\": 2,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-01-28T08:46:22Z\"\n}\n\n ```"}}},"components":{"schemas":{"MachineUsageListResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","description":"Usage information for all machines","properties":{"machines":{"type":"array","items":{"$ref":"#/components/schemas/MachineUsageItem"}},"count":{"type":"integer","description":"Total number of machines"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"MachineUsageItem":{"type":"object","description":"Usage information for a single machine","properties":{"machine_id":{"type":"integer","description":"Machine ID"},"machine_name":{"type":"string","description":"Machine name"},"usage_minutes":{"type":"integer","description":"Remaining usage in minutes"},"machine_type":{"type":"string","description":"Machine performance type"},"usage_source":{"type":"string","enum":["machine","team_balance"],"description":"\"machine\" means only assigned usages; \"team_balance\" means can use team balance when no additional usage on machine."}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## List Machine Usages by ID

> Get remaining machine usage information in minutes for a specific machine.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\`\\\* | Integer | Machine ID |\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`machine\_id\` | Integer | Machine ID |\
> \| \`machine\_name\` | String | Machine name |\
> \| \`usage\_minutes\` | Integer | Usage minutes based on total balance (including credits) |\
> \| \`machine\_type\` | String | Machine type friendly name (e.g., "Planet") |\
> \| \`usage\_source\` | String | Usage source - "machine" (only assigned usages) or "team\_balance" (can use team balance when no additional usage on machine) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "machine\_id": 717,\
> &#x20;   "machine\_name": "Computer #717",\
> &#x20;   "usage\_minutes": 1172,\
> &#x20;   "machine\_type": "Planet",\
> &#x20;   "usage\_source": "machine",\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T13:28:19Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Machine not found |\
> \| 4709 | Seat not found for machine |\
> \| 4710 | Permission required |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/usage/machines/{id}":{"get":{"summary":"List Machine Usages by ID","responses":{"200":{"description":"Machine usage information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MachineUsageResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4709":{"description":"Seat not found for machine","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4709Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Usages"],"description":"Get remaining machine usage information in minutes for a specific machine.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `id`\\* | Integer | Machine ID |\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `machine_id` | Integer | Machine ID |\n| `machine_name` | String | Machine name |\n| `usage_minutes` | Integer | Usage minutes based on total balance (including credits) |\n| `machine_type` | String | Machine type friendly name (e.g., \"Planet\") |\n| `usage_source` | String | Usage source - \"machine\" (only assigned usages) or \"team_balance\" (can use team balance when no additional usage on machine) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Success Response Example**\n\n``` json\n{\n    \"machine_id\": 717,\n    \"machine_name\": \"Computer #717\",\n    \"usage_minutes\": 1172,\n    \"machine_type\": \"Planet\",\n    \"usage_source\": \"machine\",\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T13:28:19Z\"\n}\n\n ```\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Machine not found |\n| 4709 | Seat not found for machine |\n| 4710 | Permission required |"}}},"components":{"schemas":{"MachineUsageResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","description":"Usage information for a specific machine","properties":{"machine_id":{"type":"integer","description":"Machine ID"},"machine_name":{"type":"string","description":"Machine name"},"usage_minutes":{"type":"integer","description":"Remaining usage in minutes"},"machine_type":{"type":"string","description":"Machine performance type"},"usage_source":{"type":"string","enum":["machine","team_balance"],"description":"\"machine\" means only assigned usages; \"team_balance\" means can use team balance when no additional usage on machine."}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4709Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Assign Machine Usage

> Assign usage in minutes from team balance to a machine.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`machine\_id\`\\\* | Integer | Yes | Machine ID |\
> \| \`minutes\`\\\* | Integer | Yes | Number of minutes to assign |\
> \
> \### Request Body Example\
> \
> \`\`\` json\
> {\
> &#x20; "machine\_id": 717,\
> &#x20; "minutes": 1\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`assigned\_minutes\` | Integer | Number of minutes assigned |\
> \| \`machine\_id\` | Integer | Machine ID that received the assignment |\
> \| \`machine\_type\` | String | Machine type friendly name used for pricing calculation (e.g., "Planet") |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "assigned\_minutes": 1,\
> &#x20;   "machine\_id": 717,\
> &#x20;   "machine\_type": "Planet",\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T13:31:47Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (missing required parameters) |\
> \| 404 | Machine not found |\
> \| 480 | Insufficient organization balance |\
> \| 482 | Balance assignment failed |\
> \| 4710 | Permission required |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/usage/assign":{"post":{"summary":"Assign Machine Usage","responses":{"200":{"description":"Usage assigned successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignUsageResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"480":{"description":"Insufficient organization balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error480Response"}}}},"482":{"description":"Balance assignment failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error482Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Usages"],"description":"Assign usage in minutes from team balance to a machine.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `machine_id`\\* | Integer | Yes | Machine ID |\n| `minutes`\\* | Integer | Yes | Number of minutes to assign |\n\n### Request Body Example\n\n``` json\n{\n  \"machine_id\": 717,\n  \"minutes\": 1\n}\n\n ```\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `assigned_minutes` | Integer | Number of minutes assigned |\n| `machine_id` | Integer | Machine ID that received the assignment |\n| `machine_type` | String | Machine type friendly name used for pricing calculation (e.g., \"Planet\") |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Success Response Example**\n\n``` json\n{\n    \"assigned_minutes\": 1,\n    \"machine_id\": 717,\n    \"machine_type\": \"Planet\",\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T13:31:47Z\"\n}\n\n ```\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (missing required parameters) |\n| 404 | Machine not found |\n| 480 | Insufficient organization balance |\n| 482 | Balance assignment failed |\n| 4710 | Permission required |","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["machine_id","minutes"],"properties":{"machine_id":{"type":"integer","description":"Machine ID to assign usage to"},"minutes":{"type":"integer","description":"Number of minutes to assign"}}}}}}}}},"components":{"schemas":{"AssignUsageResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","description":"Response after assigning usage to a machine","properties":{"assigned_minutes":{"type":"integer","description":"Number of minutes assigned"},"machine_id":{"type":"integer","description":"Machine ID that received the usage"},"machine_type":{"type":"string","description":"Machine performance type"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error480Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error482Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Retrieve Machine Usage

> Retrieve extra assigned usage from machine back to team balance.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`machine\_id\`\\\* | Integer | Yes | Machine ID |\
> \| \`minutes\`\\\* | Integer | Yes | Number of minutes to retrieve. Cannot exceed available usage. |\
> \
> \### Request Body Example\
> \
> \`\`\` json\
> {\
> &#x20; "machine\_id": 717,\
> &#x20; "minutes": 60\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`retrieved\_minutes\` | Integer | Number of minutes retrieved |\
> \| \`machine\_id\` | Integer | Machine ID |\
> \| \`machine\_type\` | String | Machine type name |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "retrieved\_minutes": 1,\
> &#x20;   "machine\_id": 717,\
> &#x20;   "machine\_type": "Planet",\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T13:51:41Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (missing required parameters) |\
> \| 404 | Machine not found |\
> \| 480 | No usages left in machine |\
> \| 482 | Usage retrieval failed |\
> \| 4710 | Permission required |

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.12"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/usage/retrieve":{"post":{"summary":"Retrieve Machine Usage","responses":{"200":{"description":"Usage retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetrieveUsageResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"480":{"description":"No usages left in machine","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error480Response"}}}},"482":{"description":"Usage retrieval failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error482Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Usages"],"description":"Retrieve extra assigned usage from machine back to team balance.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `machine_id`\\* | Integer | Yes | Machine ID |\n| `minutes`\\* | Integer | Yes | Number of minutes to retrieve. Cannot exceed available usage. |\n\n### Request Body Example\n\n``` json\n{\n  \"machine_id\": 717,\n  \"minutes\": 60\n}\n\n ```\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `retrieved_minutes` | Integer | Number of minutes retrieved |\n| `machine_id` | Integer | Machine ID |\n| `machine_type` | String | Machine type name |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Success Response Example**\n\n``` json\n{\n    \"retrieved_minutes\": 1,\n    \"machine_id\": 717,\n    \"machine_type\": \"Planet\",\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T13:51:41Z\"\n}\n\n ```\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (missing required parameters) |\n| 404 | Machine not found |\n| 480 | No usages left in machine |\n| 482 | Usage retrieval failed |\n| 4710 | Permission required |","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["machine_id","minutes"],"properties":{"machine_id":{"type":"integer","description":"Machine ID to retrieve usage from"},"minutes":{"type":"integer","description":"Number of minutes to retrieve (cannot exceed available usage)"}}}}}}}}},"components":{"schemas":{"RetrieveUsageResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","description":"Response after retrieving usage from a machine","properties":{"retrieved_minutes":{"type":"integer","description":"Number of minutes retrieved"},"machine_id":{"type":"integer","description":"Machine ID from which usage was retrieved"},"machine_type":{"type":"string","description":"Machine performance type"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error480Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error482Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````


# Teams API Documentation

## **Create Computers**

<mark style="color:green;">`POST`</mark> `/organization-management/v1/seats`

This endpoint allows you to create computer(s) with selected configurations.

#### Request Body

```json
{
  "seat_plan_id": 999999, // Contact Vagon team to learn Plan ID options.
  "quantity": 1,
  "software_ids": [],
  "base_image_id": null,
  "permissions": {
    "public_internet_access": true,
    "can_download_from_vagon_workstation": true,
    "analytics_collection_enabled": false,
    "clipboard_enabled": true,
    "screen_recording_enabled": false,
    "input_recording_enabled": false
  }
}
```

<table><thead><tr><th width="329.91796875">Name</th><th width="123.046875">Type</th><th>Description</th></tr></thead><tbody><tr><td>seat_plan_id</td><td>integer</td><td>Contact Vagon team to learn Plan ID options.</td></tr><tr><td>quantity</td><td>integer</td><td>Number of the computers</td></tr><tr><td>software_ids</td><td>array of integer</td><td>Apps to be preinstalled to computers, check <strong>List Preinstall Applications &#x26; Images</strong> endpoint</td></tr><tr><td>base_image_id</td><td>integer</td><td>Base image selection for computers, check <strong>List Preinstall Applications &#x26; Images</strong> endpoint</td></tr><tr><td>permissions.public_internet_access</td><td>boolean</td><td>Ability to access internet inside computers, default <code>true</code></td></tr><tr><td>permissions.can_download_from_vagon_workstation</td><td>boolean</td><td>Ability to download files from computers, default <code>true</code></td></tr><tr><td>permissions.analytics_collection_enabled</td><td>boolean</td><td>Enhanced app usage analytics for computers, default <code>false</code></td></tr><tr><td>permissions.clipboard_enabled</td><td>boolean</td><td>Copy &#x26; paste functionality inside computers, default <code>true</code></td></tr><tr><td>permissions.screen_recording_enabled</td><td>boolean</td><td>Session recording for computers, default <code>false</code></td></tr><tr><td>permissions.input_recording_enabled</td><td>boolean</td><td>Mouse &#x26; keyboard action logging, default <code>false</code></td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}
{% code fullWidth="false" %}

```json
{
    "client_code": 200,
    "timestamp": "2026-01-09T13:30:52Z"
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## **List Preinstall Applications & Images**

<mark style="color:blue;">`GET`</mark> `/organization-management/v1/software`

List of the applications and base images that can be used while creating computers. Selected plan disk storage size should be larger than the total size of the selected images and the base image (golden image).

Only a single base image(golden image) can be selected at the same time.

#### Headers

<table><thead><tr><th width="192">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
    "softwares": [
        {
            "id": "33",
            "type": "software",
            "attributes": {
                "id": 33,
                "name": "Blender",
                "size": 1.4
            }
        },
        {
            "id": "36",
            "type": "software",
            "attributes": {
                "id": 36,
                "name": "Cinema 4D",
                "size": 3.0
            }
        },
        {
            "id": "37",
            "type": "software",
            "attributes": {
                "id": 37,
                "name": "CLO3D",
                "size": 3.0
            }
        },
    ],
    "golden_images": [
        {
            "id": "94",
            "type": "golden_image",
            "attributes": {
                "id": 94,
                "name": "Video Production",
                "size": 59.0
            }
        },
        {
            "id": "95",
            "type": "golden_image",
            "attributes": {
                "id": 95,
                "name": "Unreal Engine Bundle",
                "size": 110.0
            }
        }
    ],
    "client_code": 200,
    "timestamp": "2026-01-14T15:01:30Z"
}
```

{% endtab %}
{% endtabs %}

## **List Computers**

<mark style="color:blue;">`GET`</mark> `/organization-management/v1/seats`

#### Query Parameters

<table><thead><tr><th width="161">Name</th><th width="256">Value</th><th>Description</th></tr></thead><tbody><tr><td>page<mark style="color:red;">*</mark></td><td>1</td><td>Page number (optional)</td></tr><tr><td>per_page<mark style="color:red;">*</mark></td><td>100</td><td>Items per page (optional)</td></tr><tr><td>q</td><td></td><td>Items per page (optional)</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="192">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "seats": [
    {
      "id": "668",
      "type": "seat",
      "attributes": {
        "status": "active",
        "auto_stop_threshold": 900,
        "file_storage_size": 25,
        "disk_size": 75,
        "network_credit": 10637356601,
        "remaining_usage": 1514,
        "deposited_usage": 0,
        "name": "Computer #668",
        "friendly_status": "off",
        "permissions": {
            "public_internet_access": true,
            "can_download_from_vagon_workstation": true,
            "analytics_collection_enabled": false,
            "clipboard_enabled": true,
            "screen_recording_enabled": false,
            "input_recording_enabled": false
        },
        "user": {
          "id": "c336bb9a-d27e-449b-9a9f-1388c8e327ef",
          "type": "user",
          "attributes": {
            "email": "jane@amazingdesign.co",
            "name": "Jane Doe"
          }
        },
        "machine": {
          "id": "568",
          "type": "machine",
          "attributes": {
            "status": "stopped",
            "name": "Computer #668",
            "region": "dublin",
            "last_session_start_at": "2025-09-30T07:29:37.108Z",
            "machine_type": "Lake"
          }
        }
      }
    }
  ],
  "count": 1,
  "page": 1,
  "next_page": null,
  "client_code": 200,
  "timestamp": "2025-09-30T10:35:16Z"
}
```

{% endtab %}

{% tab title="404: Not Found" %}

```json
{
  "message": "Not Found",
  "client_code": 404,
  "timestamp": "2024-03-27T10:11:43Z"
}
```

{% endtab %}

{% tab title="401: Unauthorized " %}

```json
```

{% endtab %}
{% endtabs %}

## **Start Computer**

<mark style="color:green;">`POST`</mark> `/organization-management/v1/machines/{machine-id}/start`

<table><thead><tr><th width="161">Name</th><th width="124.796875">Value</th><th>Description</th></tr></thead><tbody><tr><td>machine_id</td><td>100</td><td>Can be got from List Computers endpoint.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "client_code": 200,
  "timestamp": "2025-09-30T11:19:55Z"
}
```

{% endtab %}
{% endtabs %}

## **List Available Performance Types**

<mark style="color:blue;">`GET`</mark> `/organization-management/v1/machines/{seat-id}/available-machine-types`

#### Path Parameters

<table><thead><tr><th width="161">Name</th><th width="124.796875">Value</th><th>Description</th></tr></thead><tbody><tr><td>seat_id</td><td>100</td><td>Can be got from List Computers endpoint.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "client_code": 200,
  "timestamp": "2025-09-30T11:19:55Z"
}
```

{% endtab %}
{% endtabs %}

## **Set Performance Type**

<mark style="color:green;">`POST`</mark> `/organization-management/v1/machines/{machine-id}/machine-type`

#### Path Parameters

<table><thead><tr><th width="161">Name</th><th width="124.796875">Value</th><th>Description</th></tr></thead><tbody><tr><td>machine_type_id<mark style="color:red;">*</mark></td><td>5</td><td>Parameter options can be got via Get Available Performance Types endpoint. Check <a href="https://vagon.io/pricing">link</a> for the performance specs &#x26; pricings.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "client_code": 200,
  "timestamp": "2025-09-30T11:19:55Z"
}
```

{% endtab %}
{% endtabs %}

## **Stop Computer**

<mark style="color:green;">`POST`</mark> `/organization-management/v1/machines/{machine-id}/stop`

#### Path Parameters

<table><thead><tr><th width="161">Name</th><th width="126.70703125">Value</th><th>Description</th></tr></thead><tbody><tr><td>machine_id</td><td>100</td><td>Can be got from List Computers endpoint.</td></tr></tbody></table>

#### Request Body

```json
{
    "gracefully": true
}
```

<table><thead><tr><th width="146.125">Name</th><th width="137.87109375">Type</th><th>Description</th></tr></thead><tbody><tr><td>gracefully</td><td>boolean</td><td>optional, use to prevent any file interruptions.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "client_code": 200,
  "timestamp": "2025-09-30T11:19:55Z"
}
```

{% endtab %}
{% endtabs %}

## **Get Access Link for Team Computer**

<mark style="color:green;">`POST`</mark> `/organization-management/v1/machines/{machine-id}/access`

#### Path Parameters

<table><thead><tr><th width="161">Name</th><th width="102.55859375">Value</th><th>Description</th></tr></thead><tbody><tr><td>machine_id</td><td>100</td><td>Can be got from List Computers endpoint.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

#### Request Body

| Name        | Type    | Description |
| ----------- | ------- | ----------- |
| expires\_in | integer | minutes     |

{% tabs %}
{% tab title="200: OK " %}

```json
{
  "id": "1",
  "type": "machine_external_access",
  "attributes": {
    "uid": "62ba2d60-5ee2-46c7-aa64-957da90ef117",
    "expires_at": "2024-10-01T04:00:06.307Z",
    "connection_link": "https://app.vagon.io/team/session/62ba2d60-5ee2-46c7-aa64-957da90ef117"
  },
  "client_code": 200,
  "timestamp": "2025-09-30T11:20:06Z"
}
```

{% endtab %}
{% endtabs %}

## **Reset Computer to Initial State**

<mark style="color:green;">`POST`</mark> `/organization-management/v1/machines/{machine-id}/reset`

Reset all files and data inside the computer, and revert it to the initial machine image state.

#### Path Parameters

<table><thead><tr><th width="161">Name</th><th width="133.94921875">Value</th><th>Description</th></tr></thead><tbody><tr><td>machine_id</td><td>100</td><td>Can be got from List Computers endpoint.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}
{% code fullWidth="false" %}

```json
{
    "client_code": 200,
    "timestamp": "2026-01-14T15:13:17Z"
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## **List Files & Folders in Computer**

<mark style="color:green;">`POST`</mark> `/organization-management/v1/seats/{seat-id}/list-content`

#### Path Parameters

<table><thead><tr><th width="161">Name</th><th width="133.94921875">Value</th><th>Description</th></tr></thead><tbody><tr><td>seat_id</td><td>100</td><td>Can be got from List Computers endpoint.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

#### Request Body

```json
{
  "path": "C:\\Users"
}
```

| Name | Type   | Description  |
| ---- | ------ | ------------ |
| path | string | "C:\\\Users" |

{% tabs %}
{% tab title="200: OK " %}
{% code fullWidth="false" %}

```json
{
  "content": [
    {
      "path": "C:\\Sample Folder",
      "name": "Sample Folder",
      "is_directory": true
    },
    {
      "path": "",
      "name": "sample.json",
      "is_directory": false
    }
  ],
  "client_code": 200,
  "timestamp": "2025-10-08T11:31:48Z"
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## **List Individual Files & Folders in Vagon Files**

<mark style="color:blue;">`GET`</mark> `/organization-management/v1/seats/{seat-id}/files`

#### Query Parameters

<table><thead><tr><th width="161">Name</th><th width="133.94921875">Value</th><th>Description</th></tr></thead><tbody><tr><td>parent_id</td><td>0</td><td>Parent folder ID (0 for root)</td></tr><tr><td>page</td><td>1</td><td>Page number (optional)</td></tr><tr><td>per_page</td><td>20</td><td>Items per page (optional)</td></tr><tr><td>q</td><td></td><td>Search query (optional)</td></tr></tbody></table>

#### Path Parameters

<table><thead><tr><th width="161">Name</th><th width="133.94921875">Value</th><th>Description</th></tr></thead><tbody><tr><td>seat_id</td><td>100</td><td>Can be got from List Computers endpoint.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}
{% code fullWidth="false" %}

```json
{
    "files": [
        {
            "id": "1507",
            "type": "file",
            "attributes": {
                "name": "Computer #592 Folder",
                "size": 0,
                "content_type": "directory",
                "uid": "0c642b3a-b7af-44c1-8e73-ab229a277138",
                "region": "dublin",
                "status": "upload_completed",
                "object_type": "root",
                "path": null,
                "parent_id": null,
                "last_modified_date": null,
                "organization_seat_id": 592,
                "file_storage_size": 26843545600,
                "file_storage_usage": 0
            }
        }
    ],
    "current": {
        "id": "1507",
        "type": "file",
        "attributes": {
            "name": "Computer #592 Folder",
            "size": 0,
            "content_type": "directory",
            "uid": "0c642b3a-b7af-44c1-8e73-ab229a277138",
            "region": "dublin",
            "status": "upload_completed",
            "object_type": "root",
            "path": null,
            "parent_id": null,
            "last_modified_date": null,
            "organization_seat_id": 592,
            "file_storage_size": 26843545600,
            "file_storage_usage": 0
        }
    },
    "count": 1,
    "page": 1,
    "next_page": null,
    "client_code": 200,
    "timestamp": "2026-01-09T13:22:41Z"
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## **List Shared Files & Folders in Vagon Files**

<mark style="color:blue;">`GET`</mark> `/organization-management/v1/files`

#### Query Parameters

<table><thead><tr><th width="161">Name</th><th width="133.94921875">Value</th><th>Description</th></tr></thead><tbody><tr><td>parent_id</td><td>0</td><td>Parent folder ID (0 for root)</td></tr><tr><td>page</td><td>1</td><td>Page number (optional)</td></tr><tr><td>per_page</td><td>20</td><td>Items per page (optional)</td></tr><tr><td>q</td><td></td><td>Search query (optional)</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}
{% code fullWidth="false" %}

```json
{
    "files": [
        {
            "id": "1508",
            "type": "file",
            "attributes": {
                "name": "Teams Shared Folder",
                "size": 0,
                "content_type": "directory",
                "uid": "fd54f58c-5b4c-4dca-95d0-99ed7a7ea2bc",
                "region": "dublin",
                "status": "upload_completed",
                "object_type": "root",
                "path": null,
                "parent_id": null,
                "last_modified_date": null,
                "organization_seat_id": null,
                "file_storage_size": 5368709120,
                "file_storage_usage": 0
            }
        },
        {
            "id": "1507",
            "type": "file",
            "attributes": {
                "name": "Computer #592 Folder",
                "size": 0,
                "content_type": "directory",
                "uid": "0c642b3a-b7af-44c1-8e73-ab229a277138",
                "region": "dublin",
                "status": "upload_completed",
                "object_type": "root",
                "path": null,
                "parent_id": null,
                "last_modified_date": null,
                "organization_seat_id": 592,
                "file_storage_size": 26843545600,
                "file_storage_usage": 0
            }
        }
    ],
    "current": {
        "id": "1508",
        "type": "file",
        "attributes": {
            "name": "Teams Shared Folder",
            "size": 0,
            "content_type": "directory",
            "uid": "fd54f58c-5b4c-4dca-95d0-99ed7a7ea2bc",
            "region": "dublin",
            "status": "upload_completed",
            "object_type": "root",
            "path": null,
            "parent_id": null,
            "last_modified_date": null,
            "organization_seat_id": null,
            "file_storage_size": 5368709120,
            "file_storage_usage": 0
        }
    },
    "count": 2,
    "page": 1,
    "next_page": null,
    "client_code": 200,
    "timestamp": "2026-01-09T13:23:50Z"
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## **Generate Download Link for a File**

<mark style="color:blue;">`GET`</mark> `/organization-management/v1/files/{file-id}/download`

This endpoint only works for the files inside Vagon Files and Shared Vagon Files Folders.

<table><thead><tr><th width="161">Name</th><th width="133.94921875">Value</th><th>Description</th></tr></thead><tbody><tr><td>file_id</td><td>250</td><td>File id of the file would like to download.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}
{% code fullWidth="false" %}

```json
{
    "url": "https://sb-vagon-file-manager-dublin.s3.eu-west-1.amazonaws.com/323/592/1767965315/image%20%2822%29.png?response-content-disposition=attachment%3B%20filename%3Dimage-22.png&x-amz-checksum-mode=ENABLED&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIASKYTEWIYPSXYJGRJ%2F20260109%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20260109T132853Z&X-Amz-Expires=900&X-Amz-Security-Token=IQoJb3JpZ2luX2V",
    "name": "image.png",
    "content_type": "image/png",
    "client_code": 200,
    "timestamp": "2026-01-09T13:28:53Z"
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## **Delete File from Vagon Files**

<mark style="color:red;">`DELETE`</mark> `/organization-management/v1/files/{file-id}`

This endpoint only works for the files inside Vagon Files and Shared Vagon Files Folders.

#### Path Parameters

<table><thead><tr><th width="161">Name</th><th width="133.94921875">Value</th><th>Description</th></tr></thead><tbody><tr><td>file_id</td><td>250</td><td>File id of the file would like to download.</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}
{% code fullWidth="false" %}

```json
{
    "client_code": 200,
    "timestamp": "2026-01-09T13:30:52Z"
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## **Get Administrative Logs**

<mark style="color:blue;">`GET`</mark> `/organization-management/v1/user-action-logs`

Get administrative and user-level action logs for the last 30 days. This feature is available upon request.

#### Query Parameters

<table><thead><tr><th width="226.05078125">Name</th><th width="133.94921875">Type / Value</th><th>Description</th></tr></thead><tbody><tr><td>start_date</td><td>2026-01-01T00:00:00Z</td><td>(Required) Start date. ISO 8601 format (e.g., 2024-01-01T00:00:00Z)</td></tr><tr><td>end_date</td><td>2026-01-31T23:59:59Z</td><td>(Required) End date. ISO 8601 format. Must be after start_date.</td></tr><tr><td>action_type</td><td></td><td>(Optional) Action type filter. e.g., machine_started, machine_stopped, file_downloaded</td></tr><tr><td>user_email</td><td></td><td>(Optional) Filter by user email</td></tr><tr><td>organization_machine_id</td><td></td><td>(Optional) Filter by machine ID</td></tr></tbody></table>

#### Headers

<table><thead><tr><th width="191">Name</th><th width="367">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authorization<mark style="color:red;">*</mark></td><td>HMAC {key}:{signature}:{nonce}:{timestamp}</td><td></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}
{% code fullWidth="false" %}

```json
{
    "logs": [
        {
            "id": "222",
            "type": "user_action_log",
            "attributes": {
                "id": 222,
                "action_type": "machine_stopped",
                "metadata": {},
                "user_id": null,
                "user_email": null,
                "organization_machine_id": 570,
                "created_at": "2026-01-14T13:54:27.176Z",
                "updated_at": "2026-01-14T13:54:27.176Z"
            }
        },
        {
            "id": "221",
            "type": "user_action_log",
            "attributes": {
                "id": 221,
                "action_type": "machine_started",
                "metadata": {
                    "machine_type_id": 7,
                    "machine_type_name": "Sand"
                },
                "user_id": 525,
                "user_email": "admin@vagon.io",
                "organization_machine_id": 570,
                "created_at": "2026-01-14T13:50:18.256Z",
                "updated_at": "2026-01-14T13:50:18.256Z"
            }
        },
        {
            "id": "220",
            "type": "user_action_log",
            "attributes": {
                "id": 220,
                "action_type": "machine_created",
                "metadata": {
                    "disk_size": 75,
                    "seat_plan_id": 209,
                    "seat_plan_name": "Creative Works Plan",
                    "file_storage_size": 25
                },
                "user_id": 525,
                "user_email": "admin@vagon.io",
                "organization_machine_id": 575,
                "created_at": "2026-01-14T13:49:56.091Z",
                "updated_at": "2026-01-14T13:49:56.091Z"
            }
        },
        {
            "id": "122",
            "type": "user_action_log",
            "attributes": {
                "id": 122,
                "action_type": "initial_connection_initiated",
                "metadata": {
                    "connection_type": "external_access"
                },
                "user_id": null,
                "user_email": null,
                "organization_machine_id": 570,
                "created_at": "2026-01-14T11:06:31.865Z",
                "updated_at": "2026-01-14T11:06:31.865Z"
            }
        },
        {
            "id": "121",
            "type": "user_action_log",
            "attributes": {
                "id": 121,
                "action_type": "machine_external_access_created",
                "metadata": {
                    "expires_at": "2026-01-14T12:06:27Z"
                },
                "user_id": 525,
                "user_email": "admin@vagon.io",
                "organization_machine_id": 570,
                "created_at": "2026-01-14T11:06:27.602Z",
                "updated_at": "2026-01-14T11:06:27.602Z"
            }
        },
    ]
}
```

{% endcode %}
{% endtab %}
{% endtabs %}


# Cloud Computer

Vagon Computer is your personal high-performance Windows cloud computer, streamed to any device with persistent storage, flexible performance, and end-to-end encryption.

Vagon Computer is your personal cloud computer, accessible from any device, anywhere. Each computer is an isolated Windows machine running in the cloud with flexible performance options, persistent storage, and support for any application you install. You connect to it through a modern browser or through the Vagon Desktop Application for macOS and Windows over an encrypted real-time stream.

Use this documentation to create your computer, connect from different devices, manage files, optimize performance, and resolve common issues.

## When to Use Vagon Computer

Vagon Computer is designed to add capability to your setup without replacing your local machine. Consider using it when you need:

* **Additional processing power.** Run demanding software in the cloud while keeping your local device free for everyday work.
* **Mobility for heavy workloads.** Use a laptop, tablet, or mobile device to reach a powerful workstation instead of carrying one with you.
* **Flexible performance.** Switch between performance tiers as your project evolves. Start light during planning and scale up only when you need more power, while keeping the same files and setup.
* **A persistent cloud workstation.** Your files, installed software, and settings stay between sessions, so the computer behaves like a workstation you return to rather than a temporary environment.

{% hint style="info" %}
You can change your performance option at any time without losing data. This is useful when a project moves from planning to rendering, or when you need a temporary boost for a specific task.
{% endhint %}

## How Vagon Computer Works

When you create a Vagon Computer, Vagon provisions an isolated Windows virtual machine in a cloud region near you. You connect to it from a browser or the Desktop Application, and your inputs and the streamed video both travel over an encrypted real-time channel. Files, installed apps, and settings persist on the machine between sessions.

## Security and Personal Data

Every Vagon Computer is an isolated virtual machine that no other user can access. It is your personal computer, hosted in the cloud so you can reach it from anywhere. Treat it like any workstation where you sign in to apps, store files, and run licensed software.

### How Vagon Protects Your Computer

* **Isolated virtual machines.** Each Vagon Computer runs on its own dedicated environment. Other users have no access to it.
* **Encrypted connections.** Sessions between your device and your Vagon Computer are always encrypted in transit.
* **Monitored infrastructure.** Vagon's technical team continually monitors infrastructure for vulnerabilities and keeps it updated.

{% content-ref url="/pages/jUyY3e46bN7chxmKnLiM" %}
[How to Use Vagon Computers](/computer/introduction/how-to-use-vagon-computers)
{% endcontent-ref %}

{% content-ref url="/pages/MgZr1gNjEtqsUSRFuUUn" %}
[Inside Computer](/computer/introduction/inside-computer)
{% endcontent-ref %}


# How to Use Vagon Computers

Sign up, create your first Vagon Computer, connect from a browser or the Desktop Application, and learn what to do once your cloud machine is live.

This guide walks you from account setup to an active session on your Vagon Computer. Follow it in order the first time you set up a computer, and use it later as a reference for connecting from new devices.

## Before You Start

Make sure you have:

* A verified Vagon account at [app.vagon.io/register](https://app.vagon.io/register).
* A stable internet connection.
* A modern browser such as Google Chrome or Microsoft Edge, or the Vagon Desktop Application.
* Enough balance or an active subscription to start a computer. Your balance covers performance usage and subscription renewal payments.

{% hint style="warning" %}
A Vagon Computer starts using credits the moment it powers on. Confirm your balance and plan before launching your first session.
{% endhint %}

## Create Your Computer

1. Sign in to your Vagon dashboard.
2. Name your Vagon Computer and click **Create Computer**.
3. Select your intended use case so Vagon can tailor the recommended setup.
4. Choose a server region. Vagon recommends the closest available region automatically, but you can override the suggestion manually.
5. Configure disk storage size and pick any preinstalled applications you want bundled.
6. Choose a subscription plan and set your account balance amount.
7. Add a payment method and complete the transaction.
8. Launch your computer from the dashboard and click **Connect** to open the session.

{% hint style="info" %}
Preinstalled applications are a convenience, not a limit. You can download and install any Windows application after your computer is created.
{% endhint %}

### Operating System Options

New Vagon Computers run on Windows Server 2025 with a refreshed Windows 11 interface. This baseline brings a more modern desktop experience, stronger application and game compatibility, smoother handling of background updates during long sessions, and a more stable foundation for demanding workloads.

{% hint style="info" %}
Vagon Computers created before this rollout were not migrated automatically to avoid interruptions. If you want to move an existing computer to Windows Server 2025, contact Vagon support.
{% endhint %}

### A Note on Region

Physical distance between you and your Vagon Computer directly affects latency and streaming quality. Stick with the recommended region during initial setup for the smoothest experience. You can migrate between regions later if you move or travel.

{% content-ref url="/pages/Ax4h5BhjfAeinlY4wQfF" %}
[Region Selection & Migration](/computer/features/region-selection-and-migration)
{% endcontent-ref %}

## Connect to Your Computer

You can reach your Vagon Computer from any device, anywhere. The two supported entry points are a modern web browser and the Vagon Desktop Application for macOS and Windows. Both deliver an encrypted real-time stream of your cloud machine.

### From a Browser

1. Sign in to your Vagon dashboard.
2. Open your computer and click **Connect**.
3. Allow browser permissions when prompted for microphone, clipboard, or file access.

Use a current version of Chrome or Edge for the most reliable WebRTC performance.

### From the Desktop Application

The Vagon Desktop Application is recommended when you need the most stable streaming, better input handling, or repeated daily usage.

1. Download the Desktop Application for [macOS](https://app.vagon.io/apps/Vagon.dmg) or [Windows](https://app.vagon.io/apps/Vagon.zip), or visit [vagon.io/download](https://vagon.io/download).
2. Install and sign in with your Vagon account.
3. Select your computer.
4. Click **Connect**.

{% hint style="info" %}
If keyboard shortcuts, full-screen behavior, or audio matter to your workflow, prefer the Desktop Application over the browser.
{% endhint %}

### From a Tablet or Mobile Device

Vagon also works on tablets and mobile devices through the browser or the dedicated mobile experience. Touch-first devices benefit from a few extra settings covered in the device guide.

{% content-ref url="/pages/S0YApECnUuanAE3INGZP" %}
[Using on Tablet & Mobile Devices](/computer/features/using-on-tablet-and-mobile-devices)
{% endcontent-ref %}

## Next Steps

{% content-ref url="/pages/MgZr1gNjEtqsUSRFuUUn" %}
[Inside Computer](/computer/introduction/inside-computer)
{% endcontent-ref %}

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/PiN6uprcnzayurXd7PCc" %}
[Preinstall App Catalog](/computer/features/preinstall-app-catalog)
{% endcontent-ref %}

{% content-ref url="/pages/dOrYDK5NrHlLBbnJ3opQ" %}
[Vagon Desktop Apps](/computer/features/vagon-desktop-apps)
{% endcontent-ref %}

{% content-ref url="/pages/trydFd4oFnVWu0wQKAQd" %}
[Computer Connection](/computer/troubleshooting/computer-connection)
{% endcontent-ref %}


# Inside Computer

Tour the in-session interface of your Vagon Computer, including the Dock Menu, audio and microphone controls, copy and paste, and the Windows keyboard layout.

Once you are connected, your Vagon Computer behaves like any Windows workstation. The main difference is the in-session **Dock Menu**, which collects the controls you use most often while streaming: sound, display, file transfers, copy and paste, and shutdown.

## The Dock Menu

The Dock Menu opens from the settings icon on the right edge of your session. It is the same whether you connect through a browser or the Desktop Application, and it holds most of the settings you would otherwise look for in the dashboard.

The Dock Menu is organized into three tabs.

### General

* Sound level.
* Screen size.
* Copy and paste between your local device and the Vagon Computer.
* Mouse scroll direction.
* Auto Turn-Off behavior for the session.

### Display

* Screen resolution.
* Stream Preferences, used to balance image quality and responsiveness against your internet connection speed.

### Files

* Access to Vagon Files storage.
* File transfers between your Vagon Computer and your local device.

{% hint style="info" %}
If the stream looks soft or stutters, open the Display tab and lower the stream quality. Lower image quality is often the right trade for a more responsive session on slower networks.
{% endhint %}

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

## Audio and Microphone

Vagon Computers stream system audio to your local device by default, and they also support microphone input so you can join calls, talk to teammates, or record audio inside the session. Microphone support is enabled by default on any Vagon Computer created after November 2021.

To turn on the microphone:

1. Open the **Dock Menu** on the right edge of the session.
2. Activate the microphone option.
3. When the browser prompts for microphone access, allow it. This is a one-time permission – future sessions reuse the choice.

![Activate the microphone from the Dock Menu](/files/g4Jto63d3GIhV9F1h3t4)

{% hint style="info" %}
If your Vagon Computer was created before November 2021 and you do not see the microphone option, contact support to have the feature enabled on your computer.
{% endhint %}

If audio or microphone behavior is unreliable in the browser, test the Vagon Desktop Application, which generally handles audio devices more consistently. If a browser denied microphone access earlier, reset the permission in your browser's site settings and reconnect.

## Copy and Paste Between Devices

The clipboard is not shared automatically between your local computer and your Vagon Computer. The Dock Menu provides dedicated actions to move text in either direction.

### From Your Local Computer to Vagon

1. Copy text on your local computer as usual.
2. Inside the Vagon session, open the **Dock Menu**.
3. Click **Copy Text to Vagon**.

The text is now in the Vagon clipboard and you can paste it anywhere inside the session.

![Copy text to Vagon from the Dock Menu](/files/VOuk2ZDZNFDvuXU0nCPS)

### From Vagon to Your Local Computer

1. Copy text inside the Vagon Computer as usual.
2. Open the **Dock Menu**.
3. Click **Copy Text from Vagon**.

The text is now in your local clipboard and you can paste it anywhere on your own machine.

![Copy text from Vagon to your local clipboard](/files/YapREbmIp1UTAJYNkwiF)

{% hint style="info" %}
The Dock Menu actions move text only. To move files, screenshots, or larger assets, use Vagon Files or the in-session file transfer tools.
{% endhint %}

## Keyboard Layout and Shortcuts

Your Vagon Computer runs Windows, so keyboard behavior, shortcuts, and clipboard handling follow Windows conventions. Computers ship with an **English** layout by default, and you can install and switch to any other language at any time.

To change the layout:

1. Connect to your Vagon Computer.
2. Open the Start menu and search for **Edit language and keyboard options**, or go to **Settings → Time & Language → Language**.
3. Click **Add a language**, choose the language you want, and let Windows finish the installation.
4. Switch between layouts from the language indicator in the Windows taskbar.

{% hint style="info" %}
If a specific key feels wrong (for example, an at sign or quote mark in the wrong place), it is almost always a layout mismatch between your local keyboard and the Windows layout selected inside Vagon. Match the two and the problem disappears.
{% endhint %}

### Shortcut Differences Across Operating Systems

* On macOS, **Cmd** maps to **Ctrl** inside Vagon (for example, copy is **Ctrl + C**, not **Cmd + C**).
* OS-level shortcuts that belong to your local machine (Mission Control, Spotlight, window snapping) are handled by your local OS and do not reach the Vagon session.
* Some browser shortcuts may be intercepted by your browser before they reach the streamed session. The Vagon Desktop Application passes shortcuts straight through to the Vagon Computer.

{% hint style="info" %}
If keyboard shortcuts are critical to your workflow – for example, in editing or 3D applications – use the Vagon Desktop Application instead of the browser to make sure shortcuts reach the cloud computer reliably.
{% endhint %}

## Shutting Down a Session

You can shut down a running Vagon Computer in three ways:

1. **From the Dock Menu:** open the Dock Menu and click **Turn Off Computer**.
2. **From the Dashboard:** open the Vagon dashboard in your browser and choose **Shut Down** on the running computer.
3. **From the Start Menu:** use the standard Windows Start menu inside the session and shut down the operating system normally.

Any of these options ends the session cleanly. Persistent storage is preserved according to your plan; only the running session is stopped.

![Shut down from the Dock Menu](/files/9KOXbksJXZkeHjjUVGeu)

![Shut down from the Dashboard](/files/ZqUzSroB2OooC6zGvKp4)

![Shut down from the Start menu](/files/pJJ8d4E1bfLYf6EtxZ9X)

### Idle Sessions and Auto Turn-Off

By default, a session that has been idle for 15 minutes is automatically turned off so you do not continue to use credits while you are away. You can change this:

* In the **Dashboard**, change the Auto Turn-Off interval under **Run in Background**, or choose **Always On** if you do not want the session to stop automatically.
* In a running session, open the **Dock Menu** and adjust the Auto Turn-Off setting under **General**.

{% hint style="warning" %}
Sessions that are not idle keep running and keep using credits. If you choose **Always On**, the computer continues consuming credits or plan time until you stop it yourself.
{% endhint %}

## Next Steps

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/iosVTQk1MfV77ifsCOJr" %}
[Vagon Files Directory](/computer/features/vagon-files-directory)
{% endcontent-ref %}

{% content-ref url="/pages/dOrYDK5NrHlLBbnJ3opQ" %}
[Vagon Desktop Apps](/computer/features/vagon-desktop-apps)
{% endcontent-ref %}

{% content-ref url="/pages/6F5apZyWmFvGWE0IU3YH" %}
[USB & External Hard Disk Support](/computer/features/usb-and-external-hard-disk-support)
{% endcontent-ref %}

{% content-ref url="/pages/S5Y14Lj21Bxc3t1x2ka0" %}
[Computer Performance](/computer/troubleshooting/computer-performance)
{% endcontent-ref %}


# No Latency Streaming

How Vagon streams a real Windows machine to your device in real time, what makes it feel native, and what affects responsiveness on your end.

Vagon streams a real cloud Windows machine to your local device in real time. Instead of running a remote desktop session over a generic protocol, Vagon uses a low-latency streaming pipeline so the cursor, keyboard, and screen feel like a local computer rather than a remote one.

## How the Streaming Works

Vagon delivers your session through **VISPr3**, its in-house low-latency streaming technology built on WebRTC. The pipeline is tuned for interactive workloads, so the cursor, keyboard, and screen feel like a local computer rather than a remote one.

The actual hardware sits in a Vagon data center, but the experience is closer to working on a local high-end PC than to operating a traditional remote desktop.

## What Affects Latency on Your Side

Two sessions on the same plan can feel different depending on the local setup. The biggest factors are:

* **Region.** Pick the region closest to where you actually are. A short physical distance to the data center is the easiest win for latency.
* **Wired vs Wi-Fi.** Ethernet is consistently better than Wi-Fi for interactive streaming. If you have to use Wi-Fi, stay close to the router on the 5 GHz band.
* **ISP and network quality.** Packet loss and jitter matter more than raw bandwidth. A stable 25-35 Mbps connection usually outperforms a noisy 200 Mbps one.
* **Local device load.** A device that is also decoding video, running heavy background tasks, or low on battery can add latency on the receiving side.

{% hint style="info" %}
If a session feels sluggish, try switching to a closer region or moving to a wired connection before changing your performance tier. Network conditions are usually the cause, not the cloud hardware.
{% endhint %}

## Display Settings and Resolution

Resolution is set from inside the session, not from the dashboard. The Dock Menu on the right edge of the screen contains all display controls, including resolution presets up to 4K.

To change the resolution:

1. Click the **Dock Menu** icon on the right side of the screen.
2. Open the **Display** section.
3. Choose the resolution you want and click **Apply**.

After a short moment the screen reapplies at the new resolution.

![Open the Dock Menu Display section](/files/qNOpTBdEht07KQ4DPbix)

![Pick the resolution you want and apply it](/files/q4O12sEsE5tHT6aPoOzt)

{% hint style="info" %}
For 4K to work end-to-end, your local display must also support the resolution you select inside Vagon. If your local screen tops out below 4K, choose a resolution your monitor can render.
{% endhint %}

### Multiple Monitors

Multi-monitor output from a single Vagon Computer is not currently supported. Sessions stream to a single display on your local device. The team is actively working on infrastructure improvements, and multi-monitor support is one of the features under development.

## Next Steps

{% content-ref url="/pages/RAZObY49RDgKOCsGaOwW" %}
[Connection Performance](/computer/troubleshooting/connection-performance)
{% endcontent-ref %}

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/dOrYDK5NrHlLBbnJ3opQ" %}
[Vagon Desktop Apps](/computer/features/vagon-desktop-apps)
{% endcontent-ref %}


# Performance Scalability

Change your Vagon Computer's performance tier between sessions to match each workload without losing files, applications, or settings.

Vagon Computer is not locked to a single hardware configuration. You can change the performance tier between sessions to match the workload in front of you, and your files, installed applications, and settings stay exactly where you left them.

## Why Scaling Matters

Most real workflows are not heavy all the time. A typical day might mix:

* Email, browsing, and light productivity.
* Application installs and large downloads.
* Heavy GPU rendering or video exports.
* Long compute-bound simulations.

Paying for a top-tier machine during the lighter parts is wasted cost. Paying for a light-tier machine during a render is wasted time. Performance scalability lets you match the tier to the task on a session-by-session basis.

## How Scaling Works

Each Vagon Computer keeps its disk, files, and installed software in place across sessions. The performance tier only defines the CPU, GPU, and RAM that get attached when you start the session.

* Start the computer on a lighter tier for setup, installs, or admin work.
* Stop the session and switch to a Graphics Accelerated tier for rendering, 3D, or VFX.
* Drop back down to a lighter tier afterwards to run reviews, exports, or routine work.

Nothing has to be reinstalled or reconfigured between changes. The machine you boot into is the same one, with different horsepower.

## Picking the Right Tier for the Job

Vagon groups its hardware into three categories so you can match the tier to the workload:

* **Graphics Accelerated.** GPU-driven tiers (such as Galaxy) for rendering, real-time 3D, VFX, and other GPU-bound work.
* **Compute Accelerated.** High-frequency CPU tiers for compute-heavy applications, simulations, and parallel processing.
* **General Purpose.** Lighter tiers (such as Planet) for everyday productivity, setup, and browser-based work.

A common pattern is to keep most sessions on a lighter tier and only scale up when the workload genuinely needs the extra hardware.

{% hint style="info" %}
Pricing changes with the tier you select. Scaling down between heavy sessions is one of the easiest ways to keep monthly usage costs predictable.
{% endhint %}

## No Long-Term Commitment

There is no contract tying your computer to a specific tier. You can change tiers as often as you like, even multiple times per day, as long as the session is stopped before each change. This makes it practical to:

* Try a heavier tier for a single project and step back down afterwards.
* Use the same Vagon Computer for both client work and personal projects.
* Adjust to seasonal workload spikes without provisioning new hardware.

## Next Steps

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/BFi4Fi2Y15LM3l9Mzdga" %}
[Computer Plans](/computer/plans-and-billing/computer-plans)
{% endcontent-ref %}

{% content-ref url="/pages/s3fNasLVpbt4Y0idwk2H" %}
[Expandable Disk Storage](/computer/features/expandable-disk-storage)
{% endcontent-ref %}


# Performance Options & Specs

Pick the right Vagon performance tier across the Graphics Accelerated and Computing Accelerated categories, change it between sessions, and review the current CPU, GPU, and RAM specs for each option.

Vagon performance options define the cloud hardware available to your computer. Choose the option that matches your workload instead of only choosing the largest available machine, and adjust it whenever your needs change.

## Choosing a Performance Option

Use a stronger performance option for:

* GPU rendering.
* 3D design and visualization.
* Video workflows.
* Large scenes or datasets.

Use a lighter option for:

* General productivity.
* Browser-based work.
* Lightweight design or review workflows.

Vagon groups its hardware into two main categories. Within Graphics Accelerated, there is a latest-generation line built on NVIDIA RTX A10G GPUs and a standard line on NVIDIA Tesla T4 GPUs. Computing Accelerated covers high-frequency CPU options without dedicated GPUs.

{% hint style="info" %}
Hourly rates vary by performance tier and by region. For current pricing in your region, see [vagon.io/pricing](https://vagon.io/pricing) and [vagon.io/region-prices](https://vagon.io/region-prices).
{% endhint %}

## Graphics Accelerated — Latest Generation (RTX A10G)

Built on the NVIDIA A10G Tensor Core GPU. These tiers are the strongest option for GPU rendering, real-time 3D, ray tracing, and complex video workflows.

| Tier      | CPU      | GPU            | RAM    |
| --------- | -------- | -------------- | ------ |
| **Spark** | 4 cores  | 24 GB A10G     | 16 GB  |
| **Flame** | 8 cores  | 24 GB A10G     | 32 GB  |
| **Blaze** | 16 cores | 24 GB A10G     | 64 GB  |
| **Lava**  | 48 cores | 4 × 24 GB A10G | 192 GB |

{% hint style="info" %}
Blaze is a strong default for complex 3D scenes and video work. Step up to Lava when you need multi-GPU rendering or very large scenes.
{% endhint %}

## Graphics Accelerated — Standard (Tesla T4)

Built on the NVIDIA Tesla T4 GPU. A reliable, lower-cost path for everyday graphics workloads.

| Tier       | CPU      | GPU                | RAM    |
| ---------- | -------- | ------------------ | ------ |
| **Planet** | 4 cores  | 16 GB Tesla T4     | 16 GB  |
| **Star**   | 16 cores | 16 GB Tesla T4     | 64 GB  |
| **Galaxy** | 48 cores | 4 × 16 GB Tesla T4 | 192 GB |

Planet is the trial entry point and a cost-effective tier for daily graphics work that does not need the latest-generation GPU.

## Computing Accelerated

High-frequency Intel CPUs without a dedicated GPU. Suitable for compute-heavy workloads, general productivity, and CPU-bound development.

| Tier      | CPU                | RAM    |
| --------- | ------------------ | ------ |
| **Sand**  | 2 cores @ 3.1 GHz  | 4 GB   |
| **Lake**  | 2 cores @ 4.0 GHz  | 16 GB  |
| **Sea**   | 8 cores @ 4.0 GHz  | 64 GB  |
| **Ocean** | 24 cores @ 4.0 GHz | 192 GB |

{% hint style="info" %}
Computing Accelerated tiers have no dedicated GPU. If your application requires a GPU for rendering, real-time 3D, or video acceleration, pick a Graphics Accelerated tier instead.
{% endhint %}

## Changing Performance

You are not locked into a single performance tier. You can upgrade or downgrade your Vagon Computer at any time while keeping the same data, files, and installed applications. The Vagon team compares this to "modifying your car in a racing game" – the vehicle stays yours, the parts change.

To change the performance option:

1. Open your **Dashboard** and select the computer you want to change.
2. Make sure the computer is **stopped**. You cannot change performance while a session is running.
3. Click **Change** next to the current performance option.
4. Pick the new tier and click **Save**.
5. Start the computer again to use the new hardware.

![Open the performance settings from the Dashboard](/files/CkMKTyhMxLRdlWgd2nW1)

![Select a new performance tier and save](/files/c8qz71EoRrRthFFvSCw9)

{% hint style="info" %}
Start with a lighter option for setup, installation, and downloads, then upgrade to a stronger option when you are ready to render or run heavier workloads. Pricing changes with the tier you choose and varies by region – check the live rates at [vagon.io/pricing](https://vagon.io/pricing) and [vagon.io/region-prices](https://vagon.io/region-prices) before starting long sessions.
{% endhint %}

## Next Steps

{% content-ref url="/pages/jUyY3e46bN7chxmKnLiM" %}
[How to Use Vagon Computers](/computer/introduction/how-to-use-vagon-computers)
{% endcontent-ref %}

{% content-ref url="/pages/BFi4Fi2Y15LM3l9Mzdga" %}
[Computer Plans](/computer/plans-and-billing/computer-plans)
{% endcontent-ref %}

{% content-ref url="/pages/Euj9ioJdqhUxCYMbWepx" %}
[Credits and Balance](/computer/plans-and-billing/credits-and-balance)
{% endcontent-ref %}

{% content-ref url="/pages/PiN6uprcnzayurXd7PCc" %}
[Preinstall App Catalog](/computer/features/preinstall-app-catalog)
{% endcontent-ref %}


# Preinstall App Catalog

Pick from the Computer Composer pre-install catalog or install your own software inside a Vagon Computer, and bring your own licenses for the apps you already own.

A Vagon Computer behaves like a standard Windows workstation. Almost any software that runs on Windows will run inside Vagon, as long as the application supports the operating system and your license allows cloud or virtual machine usage.

## The Computer Composer Pre-Install Catalog

When you create a Vagon Computer, the Computer Composer lets you pick from a curated list of applications that are pre-installed for you. The list is maintained continuously, with new applications and updated versions added regularly.

Common workflows the catalog supports include:

* Video editing and rendering with Adobe Premiere Pro.
* Game development with Unity or Unreal Engine.
* 3D modelling and rendering with Blender or Cinema 4D.
* Engineering simulations such as computational fluid dynamics or finite element analysis.
* General productivity, browsing, and creative apps.

![Pre-install applications from the Computer Composer](/files/MymyB4FGlblxwwJjsrEY)

## Installing Applications Manually

You are not limited to the pre-installed list. After your computer is created, you can download and install any application you need, exactly as you would on a regular Windows PC. Vagon Computers have an internet connection of up to **2 Gbps**, so installers and large assets typically download in a fraction of the time you would expect locally.

![Install additional apps inside the Vagon Computer](/files/mLsRwzR2NGaCls2BfpnB)

A short checklist before you install something heavy:

* Download installers from the official vendor source.
* Have your license credentials available.
* Restart the computer if the installer requests it.
* Confirm that the application lives in persistent storage if you need it for future sessions.

## GPU Drivers

Vagon manages GPU drivers across the fleet for you – manual driver updates are not recommended.

{% content-ref url="/pages/fjJUvWUFqRo7MaD13CyM" %}
[GPU Driver Issues](/computer/troubleshooting/gpu-driver-issues)
{% endcontent-ref %}

## Software Licenses

Vagon operates on a bring-your-own-license model. You can use any software you have a valid license for, but Vagon does not provide licenses for third-party applications on standard plans.

* Install the software inside your Vagon Computer as usual.
* Sign in to the vendor's account or activate the license from inside the session.
* Depending on the vendor, you may need to sign in again each session, or the activation may persist with your installation.

If you need extended license management – floating licenses, centrally managed activations, or volume entitlements – consider **Vagon Teams**, which provides additional support for license handling across an organisation.

## Application Performance

If an application feels slow, check whether the selected performance option matches the application requirements. Switching to a higher tier for rendering or simulation work is often the simplest fix.

## Next Steps

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/s3fNasLVpbt4Y0idwk2H" %}
[Expandable Disk Storage](/computer/features/expandable-disk-storage)
{% endcontent-ref %}

{% content-ref url="/pages/fjJUvWUFqRo7MaD13CyM" %}
[GPU Driver Issues](/computer/troubleshooting/gpu-driver-issues)
{% endcontent-ref %}


# Vagon Files Directory

Use the Vagon Files directory to move files between your local device and your Vagon Computer. Vagon Files is optimized for transfer, not for working on files in place.

Vagon Files is a cloud storage area built into your Vagon account, designed to optimize file transfer between your local device and your Vagon Computer. It behaves much like a personal cloud drive such as Google Drive: a staging area for moving files in and out, not a working directory.

{% hint style="warning" %}
Do not open, edit, or run project files directly from the Vagon Files folder inside your session. Vagon Files is optimized for transfer, not for live read/write workloads. Opening large project files, rendering, or saving directly to Vagon Files can cause noticeable performance issues, slow saves, and unresponsive applications. **Always sync files onto the Vagon Computer's local disk before working on them, and move outputs back to Vagon Files only when you are done.**
{% endhint %}

## How Vagon Files Works

Vagon Files is separate from your Vagon Computer's internal disk. Files you place in Vagon Files live in the cloud and stay available even when your computer is shut down. You can share, send, and manage these files without starting a session, then move them onto the computer only when you need them.

Because Vagon Files sits next to your computer rather than inside it:

* Files stored there do not consume your Vagon Computer's disk space.
* You can prepare uploads in advance, removing wait time when you start a session.
* You can keep working with your files on the dashboard while the computer is offline.

The trade-off for this separation is that Vagon Files is reached over network calls rather than as a local disk. That is fine for moving files in and out, but it is not designed to back the kind of constant random reads and writes that creative, editing, and rendering applications perform on their working files.

## Working on Files: Sync First, Then Work

The recommended workflow for any non-trivial file is:

1. Upload the file to **Vagon Files** from your Dashboard or from inside the session.
2. **Sync** the file onto the Vagon Computer's local disk (for example, into Documents or a project folder on `C:\`).
3. Open and work on the file from the local disk path so all reads and writes go to the fast local volume.
4. When you are done, save a copy back to Vagon Files (or upload the final outputs) so they persist outside the computer.

This applies to creative projects (3D scenes, video timelines, image stacks), code repositories, large datasets, and anything else that an application reads from and writes to repeatedly during a session.

## Dual Access Points

Vagon Files is reachable from two places, depending on whether your Vagon Computer is running:

* **Computer off:** Open the **Files** section from your Vagon Dashboard.
* **Computer on:** Open the **Vagon Files** shortcut on the desktop or from the Dock menu inside the session.

## Storage Allocation

Every Vagon account starts with **5 GB** of Vagon Files storage. You can raise this limit at any time from the Files section on the Dashboard.

{% hint style="warning" %}
Increasing your Vagon Files storage is irreversible. Once you raise the limit, it cannot be lowered again later.
{% endhint %}

## Upload Files to Vagon

### Small Files: Drag and Drop

For quick transfers, drag a file from your local computer directly into the Vagon session window. The file is copied straight onto the Vagon Computer's disk.

### Large Files: Sync to Vagon

For larger transfers, route files through Vagon Files. It is an independent but integrated cloud storage area attached to your Vagon account.

1. Upload the files from your local device into **Vagon Files** on the Dashboard.
2. Open your Vagon Computer.
3. Use the **Sync to Vagon** button to copy the files onto the computer when you need them.

Because files in Vagon Files live in the cloud, they do not occupy disk space on your Vagon Computer until you sync them across.

{% hint style="info" %}
Uploading to Vagon Files in advance removes wait time at the start of a session. Your assets are ready as soon as you connect.
{% endhint %}

## Download Files from Vagon

### Direct Download

1. Right-click the file inside your Vagon Computer.
2. Select **Download from Vagon**.
3. Confirm the download in the modal that appears.

The file is transferred straight to your local device.

### Upload to Vagon Files

For larger files, or when you want a copy that persists outside the computer:

1. Inside your Vagon Computer, select the file and use the **Upload to Vagon Files** button.
2. Open the **Files** section on your Dashboard.
3. Download the file from the Vagon Files directory to your local device.

Files held in the Vagon Files directory do not consume disk space on the Vagon Computer, which is useful when you are managing storage limits.

## Mobile and Tablet Transfers

Direct file transfers from tablets and mobile devices into Vagon are not currently supported. To move files from a mobile device, upload them to Vagon Files from a desktop or browser first, then access them from your session.

## Large or Slow Transfers

For large files or slow connections:

* Keep the session connected until the transfer finishes.
* Avoid refreshing the browser tab while a transfer is in progress.
* Prefer Vagon Files over direct drag and drop for multi-gigabyte uploads.
* Use a wired internet connection where possible.

{% hint style="warning" %}
Closing the browser tab or disconnecting the desktop app during an active transfer can interrupt the upload or download. Wait for the transfer indicator to finish before ending the session.
{% endhint %}

## Common Uses

Vagon Files is a transfer and persistence layer. Use it to:

* Upload project assets before starting a session, then sync them onto the computer's disk to work on them.
* Move finished outputs back into the cloud after a session so they persist when the computer is stopped.
* Move files between multiple local devices through a single shared location.
* Hold static reference libraries that you only read occasionally (not files an application reads and writes during active work).

{% hint style="info" %}
Keep project files organized in clearly named folders. It speeds up uploads, downloads, and any troubleshooting with the Vagon support team.
{% endhint %}

{% hint style="warning" %}
If an application feels sluggish or saves take a long time, check whether the file is being opened from a Vagon Files path. Move the working copy to the Vagon Computer's local disk and re-open it from there.
{% endhint %}

## Next Steps

{% content-ref url="/pages/s3fNasLVpbt4Y0idwk2H" %}
[Expandable Disk Storage](/computer/features/expandable-disk-storage)
{% endcontent-ref %}

{% content-ref url="/pages/S0YApECnUuanAE3INGZP" %}
[Using on Tablet & Mobile Devices](/computer/features/using-on-tablet-and-mobile-devices)
{% endcontent-ref %}

{% content-ref url="/pages/6F5apZyWmFvGWE0IU3YH" %}
[USB & External Hard Disk Support](/computer/features/usb-and-external-hard-disk-support)
{% endcontent-ref %}


# Expandable Disk Storage

Understand how Vagon Computer disk storage works, how to expand it, and what happens to your data when your subscription ends.

Your Vagon Computer comes with a fixed amount of disk storage that you can grow as your projects expand. How long your data stays available depends on whether your subscription is active.

## Default Storage

Every Vagon Computer starts with **50 GB** of internal storage in its initial setup. This holds your operating system, installed applications, project files, and anything else saved to the computer's disk.

For lighter workflows the default is usually enough. Heavier 3D, video, and rendering projects often need more space.

## Increase Your Computer Storage

You can increase storage from the **Storage** section on your Dashboard. The computer must be shut down before you can adjust the limit.

1. Shut down your Vagon Computer.
2. Open the **Storage** section on the Dashboard.
3. Click the **Increase** button.

![Dashboard storage selected](/files/rqFLfNv7iSFJWwPnFQn7)

4. Choose how much extra storage to add. Storage grows in **50 GB** steps up to a maximum of **500 GB**.
5. Click **Confirm & Pay** to apply the new size.

![Storage increment selection](/files/yIw462W8eVu8cFOE0Fby)

Each 50 GB increment adds a flat monthly fee on top of your existing subscription. For the current rate per increment, see [vagon.io/pricing](https://vagon.io/pricing).

{% hint style="warning" %}
Storage increases are irreversible. The Vagon infrastructure does not currently support reducing computer storage once it has been raised, so add only what you need.
{% endhint %}

## Save Files in the Right Place

Save important files to your computer's disk or to Vagon Files. Files placed only in temporary system locations can be lost when the computer stops, resets, or is recreated.

Before stopping work:

* Save and close your applications.
* Confirm any uploads or downloads are complete.
* Move critical outputs to Vagon Files for cloud backup.
* Download a local copy of anything you cannot afford to lose.

## What Happens When Your Subscription Ends

Your Vagon Computer stays active until the end of your current billing cycle. After the subscription period ends:

* Your Vagon Computer is decommissioned.
* The data stored on the computer's disk is deleted from the cloud.
* You can start a new subscription at any time, but a new Vagon Computer is provisioned and previous disk contents are not restored.

{% hint style="warning" %}
Data on the Vagon Computer disk is removed when your subscription ends. Download anything you want to keep, or move it to Vagon Files, before your billing cycle closes.
{% endhint %}

{% hint style="info" %}
Vagon Files is tied to your account rather than to a single computer, which makes it the safer place to keep files you may need across future subscriptions.
{% endhint %}

## Next Steps

{% content-ref url="/pages/iosVTQk1MfV77ifsCOJr" %}
[Vagon Files Directory](/computer/features/vagon-files-directory)
{% endcontent-ref %}

{% content-ref url="/pages/xLH94nGFCBVD3uGThLIk" %}
[Subscription and Payments](/computer/plans-and-billing/subscription-and-payments)
{% endcontent-ref %}

{% content-ref url="/pages/BFi4Fi2Y15LM3l9Mzdga" %}
[Computer Plans](/computer/plans-and-billing/computer-plans)
{% endcontent-ref %}


# Region Selection & Migration

Choose the Vagon region closest to you for the smoothest connection, and understand how changing regions affects latency and your computer data.

Your Vagon Computer runs in a specific physical region in the cloud. The region you choose directly shapes latency, streaming quality, and how snappy the workstation feels. Vagon picks a recommended region based on your network so you get the best experience without manual tuning.

## How Region Affects Your Session

The closer your Vagon Computer is to you physically, the less time the stream spends travelling between the data center and your device. Picking the recommended region gives you the smoothest connection.

![Region selection](/files/k3gr9kVbGly8951BZWTu)

The connection quality indicator reflects this. A region close to you reports a **Smooth** connection.

![Smooth quality](/files/6DtWaqxa0tbUcENZgl7I)

Switching to a distant region degrades the experience. For example, moving from Dublin to California downgrades quality from **Smooth** to **Acceptable**.

![Region change](/files/pAP49bGRtyVRL9e2Q8BB)

{% hint style="warning" %}
Stick with the recommended region during initial setup. As distance between you and your Vagon Computer increases, you may experience noticeable lag and latency.
{% endhint %}

## Pricing Varies by Region

Hourly rates for performance options differ between regions. The region you pick affects not only latency but also how much each session costs.

{% hint style="info" %}
Before provisioning or migrating, check the live rates for your region on [vagon.io/region-prices](https://vagon.io/region-prices). The general pricing model is documented at [vagon.io/pricing](https://vagon.io/pricing).
{% endhint %}

## When You Might Change Regions

Most users never need to change region. Consider migrating when:

* You move countries or continents long-term.
* You need to collaborate from a location far from your original region.
* Your network conditions change and the recommended region is no longer the best match.

If you only travel occasionally, the existing region is usually still acceptable – test the connection quality indicator before migrating.

## What Happens to Your Data on a Region Change

A Vagon Computer is tied to the region it was provisioned in. Moving regions means starting fresh on hardware in the new location.

* The disk contents of your existing computer do not automatically follow you to a new region.
* Anything you need to keep should be moved to **Vagon Files** before migrating, because Vagon Files is tied to your account rather than to a single computer.
* After migration, restore your assets by syncing them down from Vagon Files into the new computer.

{% hint style="info" %}
Plan a region migration like a fresh setup: back up your project files to Vagon Files first, then provision the new computer and pull the assets back down once you reconnect.
{% endhint %}

## Next Steps

{% content-ref url="/pages/jUyY3e46bN7chxmKnLiM" %}
[How to Use Vagon Computers](/computer/introduction/how-to-use-vagon-computers)
{% endcontent-ref %}

{% content-ref url="/pages/iosVTQk1MfV77ifsCOJr" %}
[Vagon Files Directory](/computer/features/vagon-files-directory)
{% endcontent-ref %}

{% content-ref url="/pages/RAZObY49RDgKOCsGaOwW" %}
[Connection Performance](/computer/troubleshooting/connection-performance)
{% endcontent-ref %}


# Virtual Reality on Cloud

Run any Vagon Computer application inside a VR headset using Vagon VR. Plus guidance on building VR content in the cloud and what to expect from live headset streaming.

Vagon VR brings your cloud computer into a virtual-reality environment, so you can use any application on Vagon as if you were sitting in front of a native desktop inside the headset. Vagon VR is currently in beta and works alongside the existing strengths of Vagon Computer for VR content creation.

## Vagon VR

Vagon VR is enabled from inside an active Vagon session. The first time you turn it on, Vagon downloads and installs the supporting tools in seconds; subsequent sessions are instant.

1. Put on your VR headset.
2. Open a browser inside the headset, sign in to your Vagon dashboard, and run your Vagon Computer.
3. Connect to the computer and enable **VR mode** from the Dock Menu.
4. Wait briefly while Vagon installs the required tools on first use.
5. Launch any VR-supported application and start using it in the headset.

Because Vagon VR runs through the browser, it works on any device that has a browser inside the headset. That includes standalone headsets, tethered headsets used with a host PC, and even a mobile phone in a simple cardboard viewer.

{% hint style="info" %}
Vagon VR is in beta. Expect rapid iteration, and share feedback with the Vagon team to help shape the next versions.
{% endhint %}

## VR Development and Content Creation

For building VR content, Vagon works the same way as a local high-end workstation. On a Graphics Accelerated tier you can:

* Install Unreal Engine, Unity, Blender, or other VR-capable tools.
* Build, iterate, and preview scenes inside the editor.
* Use the engine's editor-side VR preview windows on the streamed desktop.
* Render high-resolution stills, 360 captures, and pre-rendered VR video.

The cloud GPU runs the engine, and you see the editor on your local device just like any other application.

## What to Expect from Live VR Streaming

Streaming a live, head-tracked, stereoscopic VR session from the cloud to a headset is fundamentally different from streaming a desktop. It depends on:

* Very low motion-to-photon latency to avoid discomfort.
* Per-eye rendering at high frame rates and resolutions.
* A network path that can sustain latency-sensitive load.

Vagon VR handles the connection flow for you, but the in-headset experience still depends on the specific application, your headset, your network, and your local hardware.

## Recommended Setup on Your Side

If you plan to use Vagon VR regularly, the user-side setup matters as much as the cloud-side hardware:

* **A wired connection.** Ethernet on your local machine, ideally with a wired link between your headset and PC where the headset supports it.
* **Strong Wi-Fi for standalone headsets.** A 5 GHz or Wi-Fi 6 network with the headset close to the router.
* **A nearby region.** Pick the Vagon region closest to your physical location to minimise round-trip time.
* **A capable local device.** The device decoding the stream still has to keep up at VR frame rates.

## Picking a Tier

VR workloads are GPU-bound. Choose a Graphics Accelerated tier with enough GPU and RAM for your scene complexity. For rendering passes, you can scale up further on the same computer without losing any project data.

## Next Steps

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/5qygulGn5ikywMX1xn7v" %}
[No Latency Streaming](/computer/features/no-latency-streaming)
{% endcontent-ref %}

{% content-ref url="/pages/MgZr1gNjEtqsUSRFuUUn" %}
[Inside Computer](/computer/introduction/inside-computer)
{% endcontent-ref %}

{% content-ref url="/pages/Vn9oGCSCSnsyLgKUHTcQ" %}
[Vagon for Creative Professionals](/computer/use-cases/vagon-for-creative-professionals)
{% endcontent-ref %}


# Vagon Desktop Apps

Download, install, and use the Vagon Desktop Application for macOS and Windows for a smoother streaming experience than the browser.

The Vagon Desktop Application is the recommended way to connect when you use Vagon frequently or need a more consistent workstation experience. The native apps for macOS and Windows produce smoother input handling, more reliable audio, and better full-screen behavior than a browser tab.

## When to Use the Desktop App

Use the desktop app when:

* Browser streaming feels less responsive.
* You use keyboard shortcuts heavily.
* You need better full-screen behavior.
* Your browser extensions or settings interfere with streaming.

Vagon provides a dedicated desktop application for both macOS and Windows. Connecting through the app generally produces smoother input handling, more reliable audio, and better full-screen behavior than a browser tab.

## Download Links

Download the installer that matches your operating system:

* **macOS:** <https://app.vagon.io/apps/Vagon.dmg>
* **Windows:** <https://app.vagon.io/apps/Vagon.zip>

You can also visit [vagon.io/download](https://vagon.io/download) for the latest builds.

## Install on macOS

1. Open the downloaded `.dmg` file.
2. Wait for the installer to complete.
3. Drag the Vagon icon into the **Applications** folder.
4. The first time you launch the app, approve the system verification prompt.
5. Sign in with your Vagon account.

## Install on Windows

1. Extract the downloaded `.zip` archive.
2. Run the installer.
3. If Windows SmartScreen shows a security warning because the application is not yet classified, click **More info** and then **Run anyway** to continue.
4. Sign in with your Vagon account once installation finishes.

Once installation finishes, you can connect to any of your Vagon Computers from inside the app.

## In-Session Controls

The Dock Menu inside a running session gives you control over sound, display, files, resolution, and shutdown – the same on both the desktop app and the browser.

{% content-ref url="/pages/MgZr1gNjEtqsUSRFuUUn" %}
[Inside Computer](/computer/introduction/inside-computer)
{% endcontent-ref %}

## Auto Turn-Off at the Dashboard Level

If you forget to shut your Vagon Computer down, it does not stay on indefinitely. By default, a session that has been idle for 15 minutes is automatically turned off so you do not continue to use credits while you are away.

You can adjust this behavior from the Dashboard:

* Change the Auto Turn-Off interval under **Run in Background**.
* Choose **Always On** if you do not want the session to stop automatically.

{% hint style="warning" %}
Sessions that are not idle keep running and keep using credits. If you choose **Always On**, the computer continues consuming credits or plan time until you stop it yourself.
{% endhint %}

## Basic Checks

If the desktop app does not connect:

* Confirm you are using the latest version.
* Restart the app and reconnect.
* Test from a different network if you suspect firewall or VPN interference.
* Try the browser connection to isolate whether the problem is app-specific.

## Next Steps

{% content-ref url="/pages/MgZr1gNjEtqsUSRFuUUn" %}
[Inside Computer](/computer/introduction/inside-computer)
{% endcontent-ref %}

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/trydFd4oFnVWu0wQKAQd" %}
[Computer Connection](/computer/troubleshooting/computer-connection)
{% endcontent-ref %}


# Using on Tablet & Mobile Devices

Access your Vagon Computer from tablets and mobile devices, including how to add Vagon to your home screen for a smoother experience.

You can access Vagon from tablets and mobile devices in addition to laptops and desktops. The experience depends on the device, browser, network quality, and the application you are running, but for many workflows a tablet is enough.

## Recommended Usage

Mobile and tablet access works best for:

* Reviewing files or lightweight applications.
* Quick checks on an existing computer.
* Touch-friendly workflows.

For keyboard-heavy, mouse-heavy, or GPU-intensive work, use a desktop browser or the Vagon Desktop Application.

## Add Vagon to Your Home Screen

For the smoothest mobile experience, add Vagon to your device home screen so it opens like a native app.

**1. Go to** [**app.vagon.io**](https://app.vagon.io) **and open the share menu, then tap the option to add Vagon to your home screen.**

![Open share menu](/files/EeyVQROnHhAoKJaNmFjX)

**2. Tap Add to confirm.**

![Tap Add](/files/4GksN1a2muPqmBPhr3ko)

**3. The Vagon icon appears on your home screen. From now on you can launch Vagon directly from your tablet or mobile device.**

![Vagon icon on home screen](/files/V1GfiQjT1zEUvrx9TanU)

## File Transfers

If you need to move files from a mobile or tablet device, use Vagon Files or the browser upload flow when available.

## Next Steps

{% content-ref url="/pages/dOrYDK5NrHlLBbnJ3opQ" %}
[Vagon Desktop Apps](/computer/features/vagon-desktop-apps)
{% endcontent-ref %}

{% content-ref url="/pages/iosVTQk1MfV77ifsCOJr" %}
[Vagon Files Directory](/computer/features/vagon-files-directory)
{% endcontent-ref %}

{% content-ref url="/pages/RAZObY49RDgKOCsGaOwW" %}
[Connection Performance](/computer/troubleshooting/connection-performance)
{% endcontent-ref %}


# USB & External Hard Disk Support

Use drawing tablets, Apple Pencil, USB peripherals, and external hard disks with your Vagon Computer. Tablets are natively supported; storage devices use the VirtualHere and ZeroTier workaround.

Peripheral support on Vagon depends on the type of device. Drawing tablets and Apple Pencil work natively with no driver setup. USB storage devices and other generic peripherals are handled through a network-tunnelling workaround using VirtualHere and ZeroTier.

## Drawing Tablets and Apple Pencil

Drawing tablets and Apple Pencil are now natively supported on Vagon Cloud Computer with real-time precision and pressure sensitivity. There is nothing to install inside the cloud computer.

1. Connect your drawing tablet (or use Apple Pencil) on your local device.
2. Launch your Vagon Cloud Computer.
3. Start creating immediately.

If the device works on your local machine, it works on Vagon. This applies to the most popular drawing tablets as well as touchscreen devices that act as pen input.

{% hint style="info" %}
Native tablet support makes Vagon suitable for digital painting and illustration, high-detail 3D sculpting in ZBrush or Blender, precision modeling, and detailed masking or rotoscoping in post-production.
{% endhint %}

## USB Memory and External Storage

Direct USB pass-through for arbitrary devices – including USB memory sticks and external hard disks – is not natively supported. For storage hardware, the recommended path is either Vagon Files or a network tunnel.

For most workflows, transferring files through Vagon Files is faster and simpler than tunnelling a USB drive. Reach for the tunnel only when you need the device itself, not just the files on it.

{% content-ref url="/pages/iosVTQk1MfV77ifsCOJr" %}
[Vagon Files Directory](/computer/features/vagon-files-directory)
{% endcontent-ref %}

### VirtualHere and ZeroTier Setup

You can reach a USB storage device from inside Vagon by tunnelling it over a private network using third-party tools. The high-level setup:

1. Install **VirtualHere Server** on your local computer to share the USB device.
2. Install **VirtualHere Client** inside your Vagon Computer to consume the shared device.
3. Install **ZeroTier One** on both your local computer and the Vagon Computer.
4. Create a ZeroTier network, join both devices to it, and authorise them from the ZeroTier dashboard so they can see each other privately.
5. From the VirtualHere Client inside Vagon, locate your shared USB device and **use** it to mount it inside the session.

{% hint style="warning" %}
The free tier of VirtualHere supports only one USB device at a time. If you need to share more than one device simultaneously, a paid VirtualHere license is required. Always download VirtualHere and ZeroTier from their official sources.
{% endhint %}

## Other Peripherals

For other USB peripherals that are not drawing tablets or storage devices – controllers, audio interfaces, dongles – check whether the vendor provides a Windows installer that can be installed directly inside the Vagon session. Devices that rely on raw USB pass-through cannot currently be used without a tunnel.

## Next Steps

{% content-ref url="/pages/iosVTQk1MfV77ifsCOJr" %}
[Vagon Files Directory](/computer/features/vagon-files-directory)
{% endcontent-ref %}

{% content-ref url="/pages/s3fNasLVpbt4Y0idwk2H" %}
[Expandable Disk Storage](/computer/features/expandable-disk-storage)
{% endcontent-ref %}

{% content-ref url="/pages/Vn9oGCSCSnsyLgKUHTcQ" %}
[Vagon for Creative Professionals](/computer/use-cases/vagon-for-creative-professionals)
{% endcontent-ref %}

{% content-ref url="/pages/trydFd4oFnVWu0wQKAQd" %}
[Computer Connection](/computer/troubleshooting/computer-connection)
{% endcontent-ref %}


# Vagon for Creative Professionals

How 3D artists, VFX professionals, motion designers, and video editors use Vagon Computer as a cloud workstation for heavy creative workloads.

Vagon Computer gives creative professionals an on-demand, GPU-accelerated Windows workstation in the cloud. Instead of buying and maintaining a tower, you spin up the hardware you need for the project in front of you and step back down when the work is done.

## Who This Is For

This setup fits creators who routinely push local hardware to its limits:

* 3D artists working in Blender, Maya, Cinema 4D, or 3ds Max.
* VFX and motion designers using After Effects, Houdini, or Nuke.
* Architectural visualizers building large scenes in Twinmotion, Lumion, or Unreal Engine.
* Video editors and colorists in DaVinci Resolve, Premiere Pro, or Final Cut workflows that move through Windows tools.
* GPU rendering pipelines built on Octane, V-Ray, Redshift, or Cycles.

If your bottleneck is render time, scene size, or the lifespan of an aging GPU, Vagon Computer is designed to take that off your plate.

## The Typical Workflow

A creative session on Vagon usually looks like this:

1. Start the Vagon Computer on a Graphics Accelerated tier such as Galaxy.
2. Open your tools from the preinstalled app catalog or install your own.
3. Pull project files from cloud storage, or upload them through Vagon Files and **sync them onto the Vagon Computer's local disk** before opening them.
4. Work in the editor from the local disk path, iterate, and render directly on the cloud GPU.
5. Move finished deliverables back to Vagon Files or client storage and stop the session.

Because the disk, files, and applications persist between sessions, the next time you start the computer everything is exactly where you left it.

## Recommended Tier

Graphics Accelerated tiers (such as Galaxy) are the right starting point for GPU-heavy creative work. For lighter passes -- review, conform, light edits -- you can drop to a lower tier on the same computer and scale back up for the next render.

{% hint style="info" %}
Install and configure your tools on a lighter tier to save on usage costs, then switch up to a Graphics Accelerated tier when you are ready to render.
{% endhint %}

## What Makes the Workflow Practical

A few Vagon features matter most for creative pipelines:

* **Native drawing tablet support.** Drawing tablets and Apple Pencil work plug-and-connect with real-time pressure sensitivity, so digital painting, sculpting, masking, and rotoscoping feel native inside the cloud session.
* **Bring your own license.** Install the versions of the software you already pay for, signed in with your existing accounts.
* **Expandable disk storage.** Project files for film, VFX, and large 3D scenes get big fast. Disk can be expanded as projects grow.
* **Region selection.** Pick a region close to you for editing latency, or close to a collaborator or studio for transfer speeds.
* **Persistent setup.** Plugins, presets, color profiles, and project libraries stay in place across sessions.

## Next Steps

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/PiN6uprcnzayurXd7PCc" %}
[Preinstall App Catalog](/computer/features/preinstall-app-catalog)
{% endcontent-ref %}

{% content-ref url="/pages/s3fNasLVpbt4Y0idwk2H" %}
[Expandable Disk Storage](/computer/features/expandable-disk-storage)
{% endcontent-ref %}

{% content-ref url="/pages/iosVTQk1MfV77ifsCOJr" %}
[Vagon Files Directory](/computer/features/vagon-files-directory)
{% endcontent-ref %}

{% content-ref url="/pages/6F5apZyWmFvGWE0IU3YH" %}
[USB & External Hard Disk Support](/computer/features/usb-and-external-hard-disk-support)
{% endcontent-ref %}


# Vagon for Freelancers

How independent designers, developers, and consultants use Vagon Computer as a pay-as-you-go cloud workstation that scales with each client project.

Freelance work is uneven by definition. Some weeks need a render farm, others need a laptop and a browser. Vagon Computer fits that pattern: a high-performance Windows machine in the cloud that you pay for when you actually use it, and scale to the project you currently have on your desk.

## Who This Is For

This setup fits independents whose hardware needs change from project to project:

* Designers and 3D artists handling occasional heavy client work.
* Developers who need a clean Windows environment, sometimes with a GPU.
* Consultants demoing software to clients without lugging hardware around.
* Anyone who works between locations, devices, or operating systems.

If buying a top-tier workstation for occasional spikes does not make sense, Vagon gives you the spike-capacity without the up-front cost.

## The Typical Workflow

A freelance month on Vagon usually mixes light and heavy days:

1. Keep the storage subscription active so your environment and project files stay in place.
2. Start a session on a light tier for admin, communication, and project setup.
3. Scale up to a heavier tier when a client project needs rendering, large datasets, or GPU power.
4. Stop the session as soon as you are done, since usage is billed by the minute.
5. Reach back into the same computer from a laptop, tablet, or borrowed machine when you travel.

## Recommended Approach

Most freelancers do well with a pay-as-you-go pattern on top of the base storage subscription:

* Use lighter tiers for the majority of sessions to keep usage costs low.
* Reserve Graphics Accelerated tiers for genuinely GPU-bound work.
* Treat Vagon as the heavy compute, and your laptop as the access device.

{% hint style="info" %}
Pay-as-you-go works best when sessions are intentional. Start, do the work, and stop. Leaving a session idle still meters usage on the selected tier.
{% endhint %}

## Working from Any Device

Vagon's cross-device support is especially useful for freelancers:

* Open the same computer from Mac, Windows, Linux, ChromeOS, iOS, and Android.
* Use a tablet or phone when travelling, then resume on a desktop at home.
* Demo work to clients directly from the browser without sending project files.

## Keeping Projects Portable

Vagon Files makes it easy to move work in and out of the cloud computer, which matters when you are handing deliverables to multiple clients. Upload assets to Vagon Files at the start of a project, sync them onto the Vagon Computer's local disk to work on them, then move final files back to Vagon Files when you ship. Vagon Files is a transfer layer, not a working directory — opening or saving live project files directly from it can slow applications down.

## Next Steps

{% content-ref url="/pages/BFi4Fi2Y15LM3l9Mzdga" %}
[Computer Plans](/computer/plans-and-billing/computer-plans)
{% endcontent-ref %}

{% content-ref url="/pages/S0YApECnUuanAE3INGZP" %}
[Using on Tablet & Mobile Devices](/computer/features/using-on-tablet-and-mobile-devices)
{% endcontent-ref %}

{% content-ref url="/pages/iosVTQk1MfV77ifsCOJr" %}
[Vagon Files Directory](/computer/features/vagon-files-directory)
{% endcontent-ref %}


# Vagon for Cloud Gaming

Using Vagon Computer to install and play PC games in the cloud, with honest expectations about how it compares to dedicated cloud gaming services.

Vagon Computer is a general-purpose cloud Windows machine, not a dedicated consumer cloud-gaming service. You can install game launchers, sign in with your own accounts, and play the games you own -- but the experience differs from a tuned service like a console-style cloud platform. This page sets clear expectations so the workflow lines up with what Vagon actually does well.

## Who This Is For

This setup fits players who need more horsepower than their local device can deliver:

* Gamers on lightweight laptops, Macs, or ChromeOS devices.
* Travelers who want access to their library from any screen.
* Players trying out games their local hardware cannot run.

## The Typical Workflow

A gaming session on Vagon usually looks like this:

1. Start the Vagon Computer on a Graphics Accelerated tier (such as Galaxy).
2. Install your game launchers -- Steam, Epic, GOG, Battle.net, and similar -- on the streamed desktop.
3. Sign in with your accounts and install the games you own.
4. Launch the game. For Steam, Big Picture or Gaming Mode gives the most controller-friendly interface.
5. Stop the session when you are done. Your installed games and saves stay on the computer for next time.

## Bring Your Own License

Vagon does not bundle game libraries. You play the games you already own through the storefronts you already use. Subscription services that require their own client (such as Game Pass for PC) can also be installed inside the session, subject to each service's terms.

## Gaming Mode

Vagon is designed and optimised for creative applications such as AutoCAD, Premiere Pro, Revit, and Blender, but it can also run games.

For the best experience while gaming:

* Use the **Vagon Desktop Application** rather than the browser.
* Activate **Gaming Mode** from the Dock Menu, or press **Ctrl + G**. Gaming Mode activates an in-game cursor and hides your local cursor so that mouse input behaves correctly inside the game.
* Press **Esc** to leave Gaming Mode.

![Activate Gaming Mode from the Dock Menu](/files/LUMccDbFODUbSToIctcO)

## Recommended Tier

Modern PC games are GPU-bound, so Graphics Accelerated tiers are the right starting point. Lighter tiers work for older or 2D titles but will struggle with current AAA games. Vagon's performance scalability means you can install on a lighter tier and switch up for actual play sessions.

{% hint style="info" %}
Installed games persist between sessions as long as your storage subscription stays active. You do not have to reinstall every time you play.
{% endhint %}

## What to Expect for Latency

Vagon streams in real time, but it is not literally zero latency. For most single-player and casual multiplayer games the experience is comfortable. For competitive titles that depend on frame-perfect input, expect the same trade-offs as any cloud-streamed setup. Latency depends on:

* The region you connect to -- pick the closest one.
* Wired vs Wi-Fi on your local device -- Ethernet is consistently better.
* Your ISP's stability, not just raw bandwidth.
* The capabilities of the device decoding the stream.

If competitive low-latency play is the main goal, a tuned consumer cloud-gaming service or local hardware will usually fit better than a general-purpose cloud workstation.

## Persistence and Saves

Because Vagon Computer is a real Windows machine, your games, launchers, mods, and local saves all stay in place between sessions. Cloud saves from the launchers themselves continue to work as they normally would.

## Next Steps

{% content-ref url="/pages/5qygulGn5ikywMX1xn7v" %}
[No Latency Streaming](/computer/features/no-latency-streaming)
{% endcontent-ref %}

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/PiN6uprcnzayurXd7PCc" %}
[Preinstall App Catalog](/computer/features/preinstall-app-catalog)
{% endcontent-ref %}


# Computer Plans

Understand Vagon Computer pricing, plan types, the trial, and how to pick the right plan for your usage pattern.

Vagon Computer pricing is split into two parts so you only pay for what you actually use. A small monthly storage subscription keeps your computer and files on the cloud, and a separate usage fee covers the time you spend in active sessions.

## The Pricing Model

Vagon billing has two components:

* **Storage subscription.** A flat monthly fee keeps your Vagon Computer and its files available on the cloud. The subscription includes an initial storage allocation, and you can expand storage from your Dashboard if you need more room.
* **Usage fee.** You are charged for the time you spend in an active session, based on the performance option you selected. Usage is metered by the minute, while performance options are listed at hourly rates to keep them easy to compare.

{% hint style="info" %}
Usage is billed by the minute, not by the hour, so you only pay for the time the computer is actually active.
{% endhint %}

Hourly rates vary by performance tier and by region. For current rates of each performance option, storage tier, and region, see [vagon.io/pricing](https://vagon.io/pricing) and [vagon.io/region-prices](https://vagon.io/region-prices).

## Plan Types

Vagon supports a few different ways to pay for usage on top of the storage subscription:

* **Pay-as-you-go.** Add credit to your balance and spend it as you run sessions. Best for variable or unpredictable workloads.
* **Hourly usage on subscription.** Keep the monthly storage subscription active and pay only for the hours you actually use the computer.
* **Heavier subscription tiers.** Higher-tier plans pair storage with included usage and additional performance options.

Higher performance options cost more to run. If a task does not need a high-end GPU machine, pick a lighter option to keep usage costs down.

## Start Your Trial

Vagon offers a paid trial so new users can try the platform end to end.

1. Create a Vagon account.
2. Complete the initial computer setup and enter payment details.
3. The trial starts automatically once setup is complete.

The trial is a small one-time charge that includes one hour of Planet performance usage and one week of computer storage. The fee is in place to discourage abuse of trial accounts. Current trial pricing is listed on [vagon.io/pricing](https://vagon.io/pricing).

When the trial ends, your computer automatically renews into your chosen plan. The storage subscription is billed to your account balance or payment method, and usage is charged according to the performance option you select for each session.

{% hint style="info" %}
If you want to continue using Vagon after the trial without setting up a new computer, do not let your storage subscription lapse. Renewing before the current period ends keeps your installed applications and files in place.
{% endhint %}

## Picking the Right Plan

Match the plan to how often you actually plan to use the computer.

**Occasional use, once every few months.** Keep the monthly storage subscription only while you are actively using Vagon. Pay for usage as you go, then end your subscription when you are finished. You will need to reinstall your applications the next time you start because data is removed when the subscription ends.

**Short-term projects.** Create the computer, work through the project, and end the subscription when you are done. Your data stays in place until the end of the current plan period, so there is no need to keep paying for additional months after the project wraps.

**Regular use, monthly or more often.** Keep a continuous subscription. It is more cost-efficient than restarting from scratch each time, and you avoid having to reinstall applications between sessions.

## Multiple Computers per Account

Each Vagon account currently supports one Vagon Computer per subscription. Support for multiple computers in a single subscription is on the roadmap.

If you need several computers for a team, use Vagon for Teams, which is designed to manage multiple cloud computers and users together.

## Discounts

Vagon keeps profit margins intentionally slim to keep ongoing usage fees low, so general-purpose discounts are limited. Pricing improves over time as the user base grows.

## Next Steps

{% content-ref url="/pages/Euj9ioJdqhUxCYMbWepx" %}
[Credits and Balance](/computer/plans-and-billing/credits-and-balance)
{% endcontent-ref %}

{% content-ref url="/pages/xLH94nGFCBVD3uGThLIk" %}
[Subscription and Payments](/computer/plans-and-billing/subscription-and-payments)
{% endcontent-ref %}

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/jUyY3e46bN7chxmKnLiM" %}
[How to Use Vagon Computers](/computer/introduction/how-to-use-vagon-computers)
{% endcontent-ref %}


# Credits and Balance

Add credit to your Vagon balance, understand how hourly usage is metered, and review past session charges.

Your Vagon balance funds your sessions and any related plan charges. You can top it up at any time and review exactly how each session draws against it.

## Add Credit to Your Balance

You can add credit while creating your computer or any time after setup.

**After your computer is set up:**

1. Open your Vagon Dashboard.
2. Select **Payment** in the left sidebar.
3. Click **Add Balance**.
4. Choose a preset amount or enter a custom value.
5. Click **Pay** to complete the transaction.

**During initial computer setup:**

1. Choose a deposit amount on the payment step, or skip it to pay only for trial usage.
2. Enter your payment details on the next screen.
3. Click **Pay & Create** to finish setup and open the Dashboard.

{% hint style="info" %}
Stripe applies a processing fee on each deposit. Larger top-ups reduce how often that fixed fee applies. See [vagon.io/pricing](https://vagon.io/pricing) for current processing fee details.
{% endhint %}

## How Hourly Usage Is Metered

Usage is billed by the minute, even though performance options are listed at hourly rates for easier comparison. You only pay for the time the computer is actually active. Hourly rates vary by performance tier and region — see [vagon.io/pricing](https://vagon.io/pricing) and [vagon.io/region-prices](https://vagon.io/region-prices) for current rates.

Switching to a lighter performance option for tasks that do not need a high-end machine is a quick way to make your balance last longer.

## Low Balance

If your balance runs low, you may not be able to start new sessions or continue long ones. Top up before starting work that should not be interrupted.

## View Session Details

You can check usage both during a session and in your full history.

**During an active session.** Open the Dock Menu by clicking the settings icon on the right side of your Vagon Computer. The menu shows how long the current session has been running.

![Dock menu showing session duration](/files/qNOpTBdEht07KQ4DPbix)

**All past sessions.** Open the **Sessions** tab from the left sidebar of your Dashboard. Each entry lists the session date, duration in minutes, and the charge applied. Sessions during the trial period appear with no charge.

![Sessions tab in the Dashboard](/files/uuxg2KxvxHIygPASEREf)

![Session duration column](/files/L7WoO8SrnSFHeosecgrL)

![Session minutes detail](/files/9wkOy2PpVQDvO8AZoS5R)

## Next Steps

{% content-ref url="/pages/xLH94nGFCBVD3uGThLIk" %}
[Subscription and Payments](/computer/plans-and-billing/subscription-and-payments)
{% endcontent-ref %}

{% content-ref url="/pages/BFi4Fi2Y15LM3l9Mzdga" %}
[Computer Plans](/computer/plans-and-billing/computer-plans)
{% endcontent-ref %}

{% content-ref url="/pages/Ri2LrHg9nJ1MpPBcCdPK" %}
[Subscription & Pricing](/computer/troubleshooting/subscription-and-pricing)
{% endcontent-ref %}


# Subscription and Payments

Manage payment methods, understand the monthly storage fee, and learn what happens when you end your Vagon subscription.

Use the billing area of your Vagon Dashboard to manage payment methods, review invoices, top up your balance, and control your subscription.

## Accepted Payment Methods

Vagon accepts:

* Credit cards
* Debit cards
* Prepaid cards

PayPal and other alternative payment methods are not supported.

## Payment Processor and Security

All payments are handled through Stripe. Card details are stored and transactions are processed securely on Stripe's infrastructure, not directly on Vagon's servers. You can review Stripe's security and compliance details at stripe.com.

## Add an Additional Payment Method

You can keep more than one card on file and choose which one is preferred.

1. Open the Dashboard and select **Payments** from the left sidebar.

   ![Payments section in the Dashboard sidebar](/files/8axqmQaxp1OFAxAX1nSu)
2. Click the **+** icon to add another payment method.

   ![Add payment method button](/files/Z7NDI4Zn7EZa9oBirc0z)
3. Fill in the card details in the form that opens. The new method is added to your account.

   ![Payment method form](/files/MYz22mFvau0bFa4u5x14)

After adding a new card, mark one of your payment methods as preferred so future charges use the right one.

## The Monthly Storage Fee

The base monthly charge on your Vagon Computer is a storage subscription. It keeps your computer and files available on the cloud between sessions and includes an initial storage allowance.

You can expand storage from the Dashboard if you need more room than the included allocation.

{% hint style="info" %}
The monthly fee is for storage only. Time spent in active sessions is billed separately according to the performance option you choose.
{% endhint %}

## End Your Subscription

You can stop your subscription at any time from the Dashboard.

1. Open the Dashboard and select **Settings** in the left sidebar.
2. Open the **End Subscription** tab.
3. Confirm the request.

Your subscription stays active until the end of the current billing period, then ends on the next renewal date. You will not be charged for the following period. You can find the exact end date in the **Subscription Renewal** section of Settings.

{% hint style="warning" %}
When your subscription ends, your Vagon Computer and all files in your Vagon Files directory are removed along with any attached data. Back up anything you want to keep before the end date.
{% endhint %}

## After Ending a Subscription

**Your balance is preserved.** Ending a subscription does not affect the credit on your account. Whatever balance you had remains there and is available the next time you start a subscription.

**You can restart any time.** Starting a new subscription is always an option. If you renew before your current plan expires, your installed applications and files stay in place. If you wait until after the plan has ended, your computer will need to be set up again because cloud-stored data is removed when the subscription period closes.

## Payment Method Checks

If a payment fails:

* Confirm the card details are current.
* Check bank approval or 3D Secure prompts.
* Try another payment method on file.
* Contact support if the payment is charged but your balance or subscription does not update.

## Next Steps

{% content-ref url="/pages/BFi4Fi2Y15LM3l9Mzdga" %}
[Computer Plans](/computer/plans-and-billing/computer-plans)
{% endcontent-ref %}

{% content-ref url="/pages/Euj9ioJdqhUxCYMbWepx" %}
[Credits and Balance](/computer/plans-and-billing/credits-and-balance)
{% endcontent-ref %}

{% content-ref url="/pages/Ri2LrHg9nJ1MpPBcCdPK" %}
[Subscription & Pricing](/computer/troubleshooting/subscription-and-pricing)
{% endcontent-ref %}

{% content-ref url="/pages/s3fNasLVpbt4Y0idwk2H" %}
[Expandable Disk Storage](/computer/features/expandable-disk-storage)
{% endcontent-ref %}


# Account Settings

Create a Vagon account, manage your profile, and learn where Teams and Enterprise plans fit in.

Use account settings to manage your Vagon profile, keep contact details current, and review the account-level information tied to your computers, files, and billing.

## Create a Vagon Account

A Vagon account is the entry point for every Vagon product. Setup takes a few minutes.

1. Open [vagon.io](https://vagon.io) and click **Sign Up**.

![Vagon sign-up page](/files/BlbqmFqmGftlAzZKPjvu)

2. Enter your name, email address, and a password, then click **Sign Up** to submit your details.
3. Open your inbox and confirm the verification email from Vagon.

![Account verification](/files/AIRwjuFeq3KkqT3h2Gb8)

Once your email is verified, you can sign in at [app.vagon.io/login](https://app.vagon.io/login) and start creating your first Vagon Computer.

{% hint style="info" %}
If the verification email does not arrive within a few minutes, check your spam or promotions folder before requesting a new one.
{% endhint %}

## Recommended Checks

* Verify the email address on file before changing plans or payment methods.
* Use a strong, unique password and rotate it periodically.
* Review account activity if you see sessions or charges you do not recognize.
* Contact support if you cannot update a critical account detail on your own.

## Vagon for Teams and Enterprises

Vagon offers dedicated plans for organizations that need cloud computers for multiple users. Teams and Enterprise plans include centralized billing, shared administration, and tailored configurations for company workloads.

To explore organization options:

* Visit [vagon.io/pricing](https://vagon.io/pricing) for current Teams and Enterprise plan details.
* Use the chat button on [vagon.io](https://vagon.io) to discuss your use case and request a custom setup.

{% hint style="info" %}
Individual Vagon Computer accounts and Vagon Teams accounts are managed separately. Reach out before migrating users so the right plan is provisioned for your organization.
{% endhint %}

## Next Steps

{% content-ref url="/pages/MEqP0ZrNYQfNsmg5f5NZ" %}
[Password and Login](/computer/account/password-and-login)
{% endcontent-ref %}

{% content-ref url="/pages/jUyY3e46bN7chxmKnLiM" %}
[How to Use Vagon Computers](/computer/introduction/how-to-use-vagon-computers)
{% endcontent-ref %}

{% content-ref url="/pages/opPQpTIQq9baECZGm583" %}
[Cloud Computer](/computer)
{% endcontent-ref %}

{% content-ref url="/pages/xLH94nGFCBVD3uGThLIk" %}
[Subscription and Payments](/computer/plans-and-billing/subscription-and-payments)
{% endcontent-ref %}


# Password and Login

Change your Vagon password from the dashboard or reset it from the sign-in page when you cannot log in.

Manage the credentials you use to sign in to Vagon. You can update your password from inside the dashboard, or trigger a reset email when you cannot sign in.

## Change Your Password From the Dashboard

Update your password whenever you suspect it has been shared, after using a shared device, or as part of routine account hygiene.

1. Sign in at [app.vagon.io/login](https://app.vagon.io/login) and open your dashboard.
2. Click the **Settings** tab.

![Open the Settings tab](/files/Sx1b0o3ligxK1dYNV9Ox)

3. Click **Change Password**.

![Change Password button](/files/DAsZQVsvI5f3Z2XqNKl6)

4. Enter your current password and the new one, then click **Change** to save.

![Confirm the new password](/files/ayC2Sqa2nNxlQNLgiAqd)

{% hint style="info" %}
Use a unique password that you do not reuse on other services. A password manager makes long, random passwords easy to keep.
{% endhint %}

## Reset Your Password When Locked Out

If you cannot sign in, use the password reset flow from the login page.

1. Open the Vagon sign-in page at [app.vagon.io/login](https://app.vagon.io/login).
2. Click the password reset option.
3. Enter your account email address.
4. Open the reset email from Vagon and follow the instructions.

## Still Cannot Sign In

If the reset email does not work or never arrives:

* Confirm you are using the email address you originally registered with.
* Check spam, promotions, and quarantine folders for the reset email.
* Make sure your mail provider is not filtering messages from Vagon.
* Contact support with your account email and a short description of the problem so the team can verify the account and help you regain access.

{% hint style="warning" %}
Never share your password or reset link with anyone, including people claiming to be from Vagon. Support will never ask for your password.
{% endhint %}

## Next Steps

{% content-ref url="/pages/FFBvvN19D9fCLHkFzBk9" %}
[Account Settings](/computer/account/account-settings)
{% endcontent-ref %}

{% content-ref url="/pages/opPQpTIQq9baECZGm583" %}
[Cloud Computer](/computer)
{% endcontent-ref %}

{% content-ref url="/pages/jUyY3e46bN7chxmKnLiM" %}
[How to Use Vagon Computers](/computer/introduction/how-to-use-vagon-computers)
{% endcontent-ref %}


# Computer Initialization

Resolve problems that appear while your Vagon Computer is starting up, including stuck connecting screens and slow first-time initialization.

A Vagon Computer usually finishes initializing and reaches the connecting screen within a couple of minutes after you press **Run**. When the initialization or connecting screen stays open longer than expected, the problem almost always falls into one of a few well-known patterns. Work through this guide before contacting support.

## Connecting Screen Stays Open Longer Than Expected

A healthy connection completes within roughly 2–4 minutes. If the connecting screen stalls past that window:

1. Refresh the page to start the connection attempt again.
2. If the second attempt also stalls, switch to the Vagon Desktop Application and retry from there.
3. If the Desktop Application also stalls, stop the computer from the dashboard and start it again instead of refreshing repeatedly.

{% hint style="info" %}
Repeated refreshes do not speed up initialization. If the first retry from a clean state does not work, move on to the checks below instead of refreshing in a loop.
{% endhint %}

## Recent Changes on the Vagon Computer

If initialization used to work and recently started stalling, something inside the Vagon Computer has likely changed. Check whether any of the following happened in your last successful session:

* GPU or system driver updates.
* Network configuration changes inside Windows.
* Windows OS version updates.
* Windows display setting changes.
* A new VPN connection or VPN client installed inside the Vagon Computer.

{% hint style="warning" %}
If you answered yes to any of the points above, contact support before making further changes. A failed driver or network modification is easier to recover when the support team can see the original state of the computer.
{% endhint %}

## Region Distance and Status

A computer that takes too long to come up can also be a sign of a region-level issue rather than a problem with your account.

* Check the Vagon status page for any ongoing incidents in your region.
* If you have recently traveled, confirm your computer is still in the closest region to your current location. Initialization is unaffected by region distance, but the connecting screen that follows will feel sluggish from far away.
* If the region has a known incident, wait for it to clear before retrying.

## Browser Cache and Extensions

A stale browser session can prevent the connecting screen from advancing even after the computer is ready.

* Clear cached data for the Vagon site, then sign in again.
* Disable extensions that block scripts, media, or WebRTC, and reload the page.
* Try an incognito or private window to rule out cached state.
* Update Chrome or Edge to the latest stable version.

## Reinstall the Desktop Application

If the browser path fails and the Desktop Application also stalls during initialization, reinstall the Desktop Application:

1. Quit the Vagon Desktop Application.
2. Uninstall it from your local operating system.
3. Download the latest version from the Vagon website and install it again.
4. Sign in and start the computer one more time.

## When to Contact Support

If initialization still does not complete after the steps above, contact support with:

* Your account email.
* The region your Vagon Computer is in.
* The performance option you tried to start on.
* Whether the issue happens in both the browser and the Desktop Application.
* The approximate time of your most recent failed attempt.

## Next Steps

{% content-ref url="/pages/trydFd4oFnVWu0wQKAQd" %}
[Computer Connection](/computer/troubleshooting/computer-connection)
{% endcontent-ref %}

{% content-ref url="/pages/RAZObY49RDgKOCsGaOwW" %}
[Connection Performance](/computer/troubleshooting/connection-performance)
{% endcontent-ref %}

{% content-ref url="/pages/fjJUvWUFqRo7MaD13CyM" %}
[GPU Driver Issues](/computer/troubleshooting/gpu-driver-issues)
{% endcontent-ref %}


# Computer Connection

Resolve problems connecting to a running Vagon Computer, including browser and Desktop App failures, missing audio, and interrupted file transfers.

Once your Vagon Computer is up, the session relies on a clean link between your local client and the cloud machine. Most connection issues come from a stale browser, a blocked extension, a missing permission, a Dock Menu toggle, or a brief network interruption during a file transfer. Work through the sections below in order.

## Cannot Connect from the Browser

If the computer is started but the browser will not connect or the stream fails to load:

* Update Chrome or Edge to the latest stable version.
* Disable extensions that may block scripts, media, or WebRTC.
* Clear site permissions, then allow microphone and clipboard permissions again when prompted.
* Try an incognito or private window to rule out cached state.
* Reload the page once. If it still fails on the second attempt, switch to the Vagon Desktop Application.

## Cannot Connect from the Desktop App

If the Vagon Desktop Application will not connect:

* Install the latest version of the Vagon Desktop Application.
* Restart the app.
* Sign out and sign in again.
* Test the same computer from a browser to compare behavior. If the browser also fails, the issue is not the client itself.

{% hint style="info" %}
When in doubt, run the same test in both clients. If only one fails, the problem is on that client. If both fail, look at the network, the account, or the Vagon Computer state.
{% endhint %}

## Both Browser and Desktop App Fail

If both clients fail, the issue is unlikely to be the client itself. Investigate:

* Network, VPN, proxy, or firewall settings on your local network.
* Account or subscription status in the dashboard.
* Region distance, if you recently traveled.
* Vagon Computer state — check whether it is suspended, out of credit, or mid-update.

## Audio Not Working

If sound is missing during your session, audio is most likely toggled off in the Dock Menu rather than broken.

1. Click the **Settings** icon on the right side of your Vagon Computer to open the **Dock Menu**.
2. In the **Shortcuts** section, find the **Sound** icon and click it to turn audio on.

{% hint style="info" %}
If you do not need audio for a session, leaving sound off reduces browser resource usage and can free up bandwidth for the video stream.
{% endhint %}

If sound is enabled in the Dock Menu but you still hear nothing:

* Check the volume and output device on your local computer.
* Verify the audio device inside Windows on the Vagon Computer (right-click the speaker icon in the system tray).
* Allow audio permissions for the Vagon site in your browser, or reinstall the Vagon Desktop Application.

## File Transfer Interrupts or Fails

File transfers in Vagon depend on a stable connection between your local device and the Vagon Computer, so most transfer issues come from network interruptions or a session ending mid-transfer.

### Upload Problems

* Keep the session and browser tab open until the upload finishes.
* Retry from a stable network.
* Check available storage inside the Vagon Computer.
* Try uploading fewer files at once.

### Download Problems

* Confirm the file exists in the expected location on the Vagon Computer.
* Avoid stopping the computer until the download finishes.
* Retry from the Vagon Desktop Application if browser download behavior is unreliable.

### Large Transfers

Large transfers are more sensitive to connection interruptions. When possible, compress many small files into one archive before transferring.

## Next Steps

{% content-ref url="/pages/6qzIh39BHLN505DsYmIn" %}
[Computer Initialization](/computer/troubleshooting/computer-initialization)
{% endcontent-ref %}

{% content-ref url="/pages/RAZObY49RDgKOCsGaOwW" %}
[Connection Performance](/computer/troubleshooting/connection-performance)
{% endcontent-ref %}

{% content-ref url="/pages/dOrYDK5NrHlLBbnJ3opQ" %}
[Vagon Desktop Apps](/computer/features/vagon-desktop-apps)
{% endcontent-ref %}

{% content-ref url="/pages/iosVTQk1MfV77ifsCOJr" %}
[Vagon Files Directory](/computer/features/vagon-files-directory)
{% endcontent-ref %}


# Connection Performance

Diagnose latency, lag, disconnects, and connection-quality issues when streaming your Vagon Computer, from internet speed requirements to VPN behavior.

Vagon streams your cloud computer in real time, so connection quality directly affects responsiveness, visual quality, and stability. Most performance complaints come from a small set of root causes: insufficient bandwidth, distance from the nearest region, an interfering network setup, or an outdated GPU driver inside the Vagon Computer.

## Internet Speed Requirements

Vagon does not need a high-end connection. A modest but stable link is enough to stream a cloud computer at usable quality.

* Minimum recommended speed on the lowest Stream Preference: **5 Mbps**.
* Higher Stream Preferences (sharper image, higher frame rate) require more headroom. Plan for additional bandwidth if you raise the quality.
* Test your connection at [speedtest.net](https://www.speedtest.net) before troubleshooting anything else.

{% hint style="info" %}
Speed alone is not the full picture. A 200 Mbps connection that fluctuates or shares the network with heavy traffic can feel worse than a steady 10 Mbps line.
{% endhint %}

## Unstable Network

Use a stable Wi-Fi signal or wired Ethernet connection when possible. While using Vagon, avoid:

* Heavy downloads or uploads on the same network.
* Cloud sync clients (Dropbox, Google Drive, OneDrive) actively transferring large files.
* Video calls and live streaming on other devices.
* Mobile hotspots or 4G/LTE connections — limited bandwidth and jitter on mobile networks regularly cause lag.

## Region Distance

Latency scales with physical distance. Vagon operates regions in North America, Europe, Mumbai, Singapore, and Sydney. Even a fast connection feels sluggish if you connect to a region on another continent.

* During first setup, Vagon tests your connection and suggests the closest region.
* If you have moved, traveled, or noticed lag after switching regions, recreate the computer in the nearest available region.

## Local Computer Requirements

The streaming client is lightweight. Vagon runs on most modern devices, including Chromebooks and MacBook Air 2014 models. There is no need for a powerful local GPU because the rendering happens in the cloud.

If your local device is very old or under heavy load, the client itself may not be able to decode the stream smoothly. Close other heavy applications, then reconnect.

## Browser Version and Plug-ins

Outdated browsers and some extensions interfere with WebRTC streaming.

* Update Chrome or Edge to the latest stable version, then restart the browser.
* Disable extensions that block scripts, media, or trackers and reconnect.
* Try an incognito/private window to rule out extension conflicts.
* If browser issues persist, switch to the Vagon Desktop Application, which avoids browser-layer interference entirely.

## VPN, Proxy, and Firewall

VPNs, proxies, corporate networks, and strict firewalls modify or restrict the traffic Vagon needs.

Try:

* Disabling VPN or proxy temporarily.
* Testing from a different network (for example, a personal hotspot).
* Asking your IT team to allow real-time media and WebRTC traffic.

### Using a VPN Inside the Vagon Computer

Running a VPN client *inside* your Vagon Computer can also cause streaming issues because the VPN modifies the network adapter that Vagon uses to stream back to you.

* Most consumer VPN clients change adapter settings in ways that break the stream.
* OpenVPN has been tested and works reliably inside Vagon when a VPN is required.

{% hint style="warning" %}
If you connect to a VPN inside your Vagon Computer and the session freezes or disconnects, you may need to wait for the session to end or contact support to restore connectivity.
{% endhint %}

## Cannot Connect After Changing Performance Option

When upgrading to a Fire-series performance option (Spark, Blaze, Fire, or Lava), the connecting screen can hang for more than a minute. This happens when the GPU driver on your Vagon Computer is out of date and does not support the new hardware tier. The full driver update flow is covered in the GPU Driver Issues guide.

{% content-ref url="/pages/fjJUvWUFqRo7MaD13CyM" %}
[GPU Driver Issues](/computer/troubleshooting/gpu-driver-issues)
{% endcontent-ref %}

## Upgraded Performance Still Feels Slow

A higher performance option gives your Vagon Computer more CPU, GPU, and memory, but the issue may be inside the Vagon Computer rather than on the network. If the connection itself is healthy but the apps inside the session still feel slow, see the Computer Performance guide.

{% content-ref url="/pages/S5Y14Lj21Bxc3t1x2ka0" %}
[Computer Performance](/computer/troubleshooting/computer-performance)
{% endcontent-ref %}

## What to Send Support

If the issue continues after the steps above, include:

* Your physical location.
* Selected Vagon region.
* Browser or desktop app version.
* Network type (wired, Wi-Fi, hotspot) and a current speed-test result.
* Performance option in use.
* A short pattern description, such as constant high latency, periodic lag, or random disconnects.

## Next Steps

{% content-ref url="/pages/5eC8iMR1VM0vuyIqNBEN" %}
[Performance Options & Specs](/computer/features/performance-options-and-specs)
{% endcontent-ref %}

{% content-ref url="/pages/dOrYDK5NrHlLBbnJ3opQ" %}
[Vagon Desktop Apps](/computer/features/vagon-desktop-apps)
{% endcontent-ref %}

{% content-ref url="/pages/trydFd4oFnVWu0wQKAQd" %}
[Computer Connection](/computer/troubleshooting/computer-connection)
{% endcontent-ref %}

{% content-ref url="/pages/S5Y14Lj21Bxc3t1x2ka0" %}
[Computer Performance](/computer/troubleshooting/computer-performance)
{% endcontent-ref %}




---

[Next Page](/llms-full.txt/1)

