# Welcome to Mithril

Mithril is a self-serve cloud platform for machine learning research and infrastructure teams

Mithril gives ML practitioners the flexibility to spin up short-term GPU instances for model experimentation, large-scale training, batch jobs, live inference, and more without long-term contracts.

{% hint style="success" %}
Mithril is generally available for work purposes. Individual users will be waitlisted for now.
{% endhint %}

## Getting started

<table data-view="cards"><thead><tr><th></th><th></th><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><strong>Compute</strong></td><td></td><td>Set up your account and start running your workloads in minutes.</td><td><a href="/files/uMYWg942ZWZt0zyFhcHq">/files/uMYWg942ZWZt0zyFhcHq</a></td><td><a href="/pages/aLxE28BcWFFWPz5ju7sb">/pages/aLxE28BcWFFWPz5ju7sb</a></td></tr></tbody></table>


# Account setup

Begin using compute on Mithril.

{% stepper %}
{% step %}

### Create your account at [app.mithril.ai](https://app.mithril.ai) using your work email for instant access

Mithril is generally available for work purposes (e.g., businesses, research labs). Individuals will be waitlisted at this time.
{% endstep %}

{% step %}

### Add your payment and billing information&#x20;

A valid payment method is required to use Mithril compute. All payment methods may have temporary authorization charges placed for verification.

{% hint style="info" %}
Remember to populate both the payment method and billing information in Stripe. Missing or invalid information may prevent you from spinning up compute.
{% endhint %}
{% endstep %}

{% step %}

### Create your [first instance](/compute-and-storage/compute-quickstart)!&#x20;

{% endstep %}

{% step %}

### Invite your team members and [setup your organization](/access-management/porting-iam-roles-and-permissions-from-aws-or-gcp)

{% endstep %}
{% endstepper %}


# Compute overview

Infrastructure designed to maximize price-performance for your ML workloads

Mithril offers two core mechanisms for provisioning compute:

1. **Short-term reserved instances:** Reservations give you guaranteed access to interconnected nodes. Reserved instances are typically useful for large, preplanned workloads like training that need to run uninterrupted. You can reserve instances in advance for as little as 3 hours and for up to 2 weeks. Reserved instance pricing is adjusted gradually based on overall supply and demand.
2. **Spot instances:** Spot instances provide a more dynamic way to access compute. To use spot instances, you submit a limit-price order that specifies the *maximum* price per GPU-hour you are willing to pay. Whenever the spot price is *lower* than your limit price, your spot instances spin up. See [Spot auction mechanics](/compute-and-storage/spot-bids/spot-auction-mechanics) to learn more.

## Provisioning compute

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Making reservations</strong></td><td></td><td>Reserve interconnected nodes for as little as 3 hours for preplanned workloads.</td><td><a href="/pages/5OBBfCrYpyo6EMbPdEmB">/pages/5OBBfCrYpyo6EMbPdEmB</a></td><td><a href="/files/Gn4mYFxqGLIedEnvEe0R">/files/Gn4mYFxqGLIedEnvEe0R</a></td></tr><tr><td><strong>Creating spot orders</strong></td><td></td><td>Burst capacity by placing limit-price orders for spot instances.</td><td><a href="/pages/VOGQX7oBbEBz7jPjAGuJ">/pages/VOGQX7oBbEBz7jPjAGuJ</a></td><td><a href="/files/Ur7RBY0wP2xVsTr91Sob">/files/Ur7RBY0wP2xVsTr91Sob</a></td></tr><tr><td><strong>Spot auction mechanics</strong></td><td></td><td>Understand how the Mithril spot auction works and best practices for limit-price bids.</td><td><a href="/pages/GqzrNbycr1vGn20E4kZW">/pages/GqzrNbycr1vGn20E4kZW</a></td><td><a href="/files/rWc96lZi9AgQavchCSlT">/files/rWc96lZi9AgQavchCSlT</a></td></tr></tbody></table>


# Compute quickstart

Set up your account and provision compute in minutes

{% hint style="info" %}
Mithril is generally available for work purposes. Individual users will be waitlisted for now.
{% endhint %}

## Create a reservation or spot bid

Once you've set up your account and determined which instance type you'd like to use, you're ready to create your first reservation or spot bid!

{% stepper %}
{% step %}

### Start

From the **Price chart** or **Instances** page, select **Create instances**.
{% endstep %}

{% step %}

### Choose if you'd like to create a reservation or a spot bid.&#x20;

Reservations give you guaranteed access to your instances for a set period of time. Spot bids allow you to use unreserved capacity as preemptible instances whenever the spot price is below the limit price that you set in your bid. See [Compute overview](/compute-and-storage/compute-overview) for additional information.
{% endstep %}

{% step %}

### Choose instance options and configuration

For step-by-step guides on creating reservations and spot bids, see [Reserving compute](/compute-and-storage/reserving-compute) and [Spot bids](/compute-and-storage/spot-bids), respectively.

{% hint style="info" %}
To attach persistent storage to your instances in this step, you must first provision storage in the same region. For details on provisioning persistent storage, see [Persistent storage](/compute-and-storage/persistent-storage).
{% endhint %}
{% endstep %}

{% step %}

### Check the status of your reservation or spot bids

Once you've submitted your reservation or bid, navigate to the **Instances** tab. Here, you can see all of your currently allocated instances. You can see the status of entire reservations and spot bids under the **Reservations** and **Spot Bids** tabs, respectively.
{% endstep %}

{% step %}

### Access your instances 🎉

Once your instance shows a status of <mark style="color:green;">`Allocated`</mark> you can access it with the selected SSH keys. You can click on the instance name to review details about the instance, including the selected SSH keys.
{% endstep %}
{% endstepper %}


# Using the price chart


# Instance types & specifications

Mithril offers several instances of various NVIDIA GPU types fit for your workloads. We will continue to add instance types over time.

Depending on your instance type, Ethernet or InfiniBand interconnect may be available.

## VM image

You can choose between one of the supported VM images. We recommend `Ubuntu24.04 2025.10.10` for the latest software, best performance, and updated security. This image is the default if none is specified in the launch specification.

<table><thead><tr><th width="225.6015625">Image name</th><th width="143.71484375">NVIDIA driver</th><th width="99.4375">CUDA</th><th width="266.5625">Notes</th><th width="166.41015625">NVIDIA container toolkit</th><th width="161.65625">OS</th><th data-hidden>Supported regions<select multiple><option value="FlBcdazsdepl" label="us-central1b" color="blue"></option><option value="HATYHkH84Ds7" label="us-central1-b" color="blue"></option><option value="eT95vvpRfwuX" label="us-central2-a" color="blue"></option><option value="RwntkCb0H5Jj" label="eu-central1-b" color="blue"></option><option value="1i2W3ZxlXaHm" label="all" color="blue"></option></select></th></tr></thead><tbody><tr><td>Ubuntu24.04 2025.10.10</td><td>580.95.05</td><td>13.0</td><td>Improved fileshare performance</td><td>1.17.8</td><td>Ubuntu 24.04 LTS</td><td></td></tr><tr><td>Ubuntu24.04 2025.08.01</td><td>570.86.10</td><td>12.8</td><td>Does not support executing binaries from persistent storage</td><td>1.17.8</td><td>Ubuntu 24.04 LTS</td><td><span data-option="1i2W3ZxlXaHm">all</span></td></tr><tr><td>Ubuntu22.04 2024.07.24</td><td>535.183.01</td><td>12.2</td><td></td><td></td><td>Ubuntu 22.04</td><td><span data-option="1i2W3ZxlXaHm">all</span></td></tr></tbody></table>

You can use [startup scripts](/compute-and-storage/startup-scripts) to customize your environment during the startup process of your instances.

## Hardware specifications

Each instance comes with its own ephemeral storage (outlined below) with NVMe SSD. This storage will exist until the instance has been terminated or pre-empted. There is no cost to use the ephemeral storage. Ephemeral storage is automatically mounted for you (and re-mounted after preemptions) at `/mnt/local`.

{% hint style="info" %}
Achieve 25% faster start-up times when configuring your instances with RAM lower than the default! RAM can be specified in the console or API, with smaller amounts enabling faster start-up time. Note the compute price does not change based on how much RAM you have — pricing is per GPU hour.
{% endhint %}

<table data-full-width="true"><thead><tr><th width="114.75">Instance</th><th width="109.63671875">GPU type</th><th width="85.25390625">GPUs</th><th width="115.09765625">VRAM per GPU (GB)</th><th width="94.77734375">CPU cores</th><th width="111.80078125">System RAM (GB)</th><th width="108.12109375">Boot disk (GB)</th><th width="150.54296875">Ephemeral NVMe (GB)</th></tr></thead><tbody><tr><td>1x A100 80GB SXM</td><td>A100 SXM</td><td>1</td><td>80</td><td>26</td><td>190</td><td>256</td><td>1,750</td></tr><tr><td>2x A100 80GB SXM</td><td>A100 SXM</td><td>2</td><td>80</td><td>52</td><td>380</td><td>256</td><td>3,500</td></tr><tr><td>4x A100 80GB SXM</td><td>A100 SXM</td><td>4</td><td>80</td><td>102</td><td>760</td><td>256</td><td>7,000</td></tr><tr><td>8x A100 80GB SXM</td><td>A100 SXM</td><td>8</td><td>80</td><td>204</td><td>1,520</td><td>256</td><td>14,000</td></tr><tr><td>8x H100 80GB SXM</td><td>H100 SXM</td><td>8</td><td>80</td><td>168</td><td>1,814</td><td>256</td><td>12,500</td></tr><tr><td>8x H200 141GB SXM</td><td>H200 SXM</td><td>8</td><td>141</td><td>168</td><td>1,600</td><td>256</td><td>1,120</td></tr><tr><td>8x B200 192GB SXM</td><td>B200 SXM</td><td>8</td><td>192</td><td>232</td><td>3,584</td><td>256</td><td>N/A</td></tr></tbody></table>

#### Memory (RAM) configuration

To improve Spot startup times by up to 25%, we recommend launching bids with less RAM configured in the launch specification. This is ideal for light workloads or development use cases that require fast startup but low resource utilization.&#x20;

Use the console or API to launch instances with less RAM.

At any point after launch, RAM can be adjusted from 100GB up to the instance type's default. In order to adjust the RAM for an order, the bid must be paused and resumed, which will restart all instances in the order.

By default, instances are launched with the maximum memory (RAM) allowed for the instance type.&#x20;

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

Note that this feature is only available for Spot instances at this time.


# Reserving compute

Guarantee access to compute for a set duration for critical, preplanned workloads

Reservations let you access dedicated VMs for exactly your desired duration, from 3 hours to 2 weeks, with 1-hour increment flexibility.

All reservations include the ability to get partial credit for unused resources and for returning part of the reservation early. The resulting credits can be applied to future use of the Mithril platform and expire 6 months after being issued.

Prices for reserved instances are determined algorithmically based on availability and demand for the instance type and period you are reserving for.

A reservation applies to a certain GPU type, in a certain region, for a specific time interval (which can either start immediately or in the future). Based on these parameters, Mithril will generate reservation offers. An offer is composed of 3 prices:

* The Reserved Unit Price (in $/hr) is the rate at which the cost of the reservation is calculated (for all reserved capacity, across the entire length of the reservation). This is the maximum amount you might have to pay, if you fully use the reservation. This amount is charged in full when making the reservation.
* The Pause Credit (in $/hr) is the rate at which you accumulate credit for instances left temporarily unused. You don’t need to take any action to earn this credit, other than ensuring that unneeded instances are paused (via the console, the CLI, or the API). Note that paused instances only earn credit if they remain paused for at least one hour. The capacity corresponding to paused instances remains reserved, you can restart these instances at any time. There might be a delay of up to 7 minutes when you restart a paused instance.
* The Return Credit (in $/hr) is the rate at which you accumulate credit for returned capacity (in effect, when you shrink the reservation). You earn credit at this rate based on the number of instances returned, and the remaining duration of the reservation. Successive “return” actions are possible, allowing a reservation size to diminish over time as work gets completed and as you get a more precise understanding of the remaining need.

{% hint style="info" %}
Credits will only be issued upon full collection of the payment for the original reservation. To use your credits, your account must be current and in good standing, including payment of all amounts owed to us, and we reserve the right to revoke your credits or suspend their use if these conditions are not met. Credits may not be purchased, have no cash value, are not redeemable for cash, and are not transferable. If your account is terminated for any reason, you will lose any credits associated with your account. This offer is subject to change.
{% endhint %}

## Creating a reservation in the Mithril web console

From the `Instances` tab, choose, `Create Instances` and select `Reserved` .&#x20;

In the reservation modal:

{% stepper %}
{% step %}

### Select an instance type

Instance type refers to the specific combination of GPU, memory, and connection.&#x20;

Ex: NVIDIA 8x H100 80GB SXM5
{% endstep %}

{% step %}

### Select a region

Instances are currently offered in multiple US regions. Certain instance types are only available in select regions.

Note: Persistent storage must be provisioned in the same region you intend to use it. See [Persistent storage](/compute-and-storage/persistent-storage) to learn more.
{% endstep %}

{% step %}

### Select a quantity of instances to include in your reservation

All instances within a single reservation are interconnected.

Note: The number of instances *is not* always equivalent to the number of GPUs. For example, selecting the 8x H100 instance type, and a quantity of 4 would yield a reservation with 32 total GPUs, 8 on each instance.&#x20;
{% endstep %}

{% step %}

### Set the duration of your reservation

This is the total time your instances will be provisioned, beginning at your specified start time. You can set the duration in one-hour increments from 3 hours up to 2 weeks. For reservations longer than two weeks, please contact your account team or email <support@mithril.ai>.
{% endstep %}

{% step %}

### Set a start time

This is the time that your instances will initialize. Instances are normally accessible within 15-20 minutes of your predetermined start time. If you haven't received an alert from our monitoring system after 15-20 minutes, please contact your account team or email <support@mithril.ai>.
{% endstep %}

{% step %}

### Chose a flexibility level

When creating a new reservation Mithril will generate two options. The “high flexibility” option offers higher credits (Pause Credit and Return Credit), but comes at a higher unit price. This is the more favorable option if you expect high variability in usage. The “low flexibility” option comes at a lower unit price but offers lower credits. This is the more favorable option if you expect to fully use the resources, for the entire duration of the reservation.
{% endstep %}

{% step %}

### (Optional) Attach persistent storage

While each instance type includes ephemeral storage (see [Instance types & specifications](/compute-and-storage/instance-types-and-specifications)), using persistent storage ensures that no critical long-term data is lost in the case that the underlying hardware for one of your instances fails (Mithril will reallocate your reserved instance if this happens, but data saved to ephemeral storage may not be recoverable).

Note: To attach persistent storage, you must provision it in the same region before creating your reservation. See [Persistent storage](/compute-and-storage/persistent-storage) to learn more.
{% endstep %}

{% step %}

### Select SSH keys

SSH keys are used to securely access your instances once they are allocated. \
\
Note: To attach an SSH key, you'll need to generate or add an existing key. See [SSH keys](/compute-and-storage/ssh-keys)to learn more.
{% endstep %}

{% step %}

### (Optional) Add a startup script

The startup script will execute as soon as your instance is allocated to help you automatically set it up for your workloads.
{% endstep %}

{% step %}

### Review & complete your reservation

Once you have fully configured your reservation and have reviewed the details, confirm you reservation. You will be billed for your reservation at the end of your billing period.

{% hint style="warning" %}
After a reservation is created, it cannot be canceled. Please carefully review your order before submitting.
{% endhint %}
{% endstep %}
{% endstepper %}

## Relocation

Reservations are guaranteed resources and are not subjected to preemption (in the same way that [spot bids](/compute-and-storage/spot-bids) are). Nevertheless, reserved instances might occasionally need to be relocated, for example if maintenance is needed on the underlying host. If this happens, the instance will be shut down and restarted on a new host. In order to allow your workload to handle this relocation, it will follow the same process as a spot bid interruption, providing mechanisms to notify of the upcoming relocation and a five minute window to save work as needed.

Refer to the [Handling Spot Interruptions](/compute-and-storage/spot-bids/handling-spot-interruptions) page for more information about the process.

Unlike spot bids interruptions, relocated reservation instances will restart immediately (on the new host) and are not subjected to market price fluctuations.


# Pause Credit

Earn credit for temporarily unused instances

To earn credit for unused instances in your reservation (at the “Pause Credit” rate included in your reservation) all you need to do is pause the instances you’re not using. Note that instances only earn credit if they’re paused for at least one hour.

To pause instances within a reservation, navigate to the “Instances” page in the console and expand the reservation to reveal the instances it contains. Each instance can be paused/unpaused via the “manage” button. Note that restarting a paused instance might incur up to a seven minutes delay if it requires pre-empting another user in the spot market. If no pre-emption is required, the instance will initiate its restart immediately.


# Return Credit

Earn credit for returning parts of a reservation early

To earn credit for shrinking the size of your reservation (at the “Return Credit” rate included in your reservation), navigate to the “Instances” tab of the console and click the “manage” button on the reservation. From there, you can select which instances to return.

Only paused instances can be returned. If an instance is running, pause it first and then return it.

Returning instances is a non-reversible operation. The size of your reservation will be reduced by the number of instances returned and you cannot re-add them to this reservation.


# Spot bids

Pay as you go for preemptible instances.

Spot instances are preemptible instances from Mithril's unreserved capacity, allocated through a blind second-price auction.

You can often leverage spot compute to:

* Decrease the cost of workloads that can tolerate delays or preemptions, such as batch jobs.
* Horizontally scale capacity for less predictable workloads like live inference.
* Run short, critical workloads when reserved capacity is unavailable.

{% hint style="info" %}
Unlike traditional clouds, Mithril always maintains a pool of dedicated spot capacity in each region. This ensures you always have the ability to provision some amount of spot compute on short notice; however, Mithril always recommends making reservations for critical workloads whenever possible to maximize your price predictability and avoid the risk of preemption.
{% endhint %}

## Creating a spot bid

You can request spot instances by creating a **spot bid** specifying an instance type, a region, a required quantity of instances, and a per-instance **limit price**.&#x20;

After submitting your bid, it becomes an **open bid**. The spot auction evaluates all open bids every 2 minutes to determine allocation. Your bid will remain open until it is successful or you terminate it.

Whenever the current **spot price** for your requested instances is lower than your limit price and enough capacity is available, your bid is <mark style="color:green;">`Allocated`</mark>, and your requested instances are provisioned. While your instances are provisioned, you are billed at the current spot price (which will be less than or equal to your limit price). Your instances remain provisioned until you cancel your bid or the spot price exceeds your limit price.&#x20;

For additional details on how spot prices are set, read [Spot auction mechanics](/compute-and-storage/spot-bids/spot-auction-mechanics).

{% hint style="warning" %}
Once you submit a spot bid, the limit price can be altered as well as pausing & resuming. To change parts of your bid, such as the SSH keys or storage, you must cancel your bid and submit a new one.
{% endhint %}

## Accessing running spot instances

Connection details for your running spot instances can be found on the **Instances** tab.&#x20;

{% hint style="warning" %}
SSH keys cannot be added after submitting a bid. Only the SSH keys selected when creating your bid can be used to access your instances.
{% endhint %}

## Preemption

Preemption occurs when the spot price for your requested instances exceeds the limit price you set in your bid. When your bid is preempted, you will receive a 5-minute notice, and the status of your bid and its associated instances will change to <mark style="color:orange;">`Preempting`</mark>. After 5 minutes, your instances will be shut down, and the status of your bid will revert to `Open bid`. Your bid will automatically be allocated again when the market adjusts such that your bid is successful. To prevent your bid from being

When your bid is preempted, your instances are shut down, but the boot disks for your instances are preserved until you terminate your bid. This allows you to implement logic to automatically restart your workload should your bid be allocated again in the future. [This guide](/compute-and-storage/startup-scripts#running-scripts-on-startup-after-reallocation-or-preemption) provides an overview of implementing a `systemd` service to run scripts on subsequent startups after preemption or relocation.

## Pausing & resuming spot bids

In some cases, you may want to pause your workload but do not want to lose your environment & setup on the boot disk. For these situations, you can pause your spot bid using the **•••** menu and selecting "Pause Bid." Your instances associated with the bid will spin-down, preserving the boot disk, and billing will stop. When you want to resume workloads, use the **•••** menu to "Resume Bid" to begin spinning up associated instances if they can be allocated in the spot market.&#x20;

Upon resuming a spot bid, your instances will retain the previous boot disk and have the same configuration of storage disks and SSH keys. If resuming your spot bids causes you to exceed your quota, the action will not be able to complete. We outline the effects of both pausing and preemption on storage for spot instances below:

| Storage Type                           | Behavior in Preemption           | Behavior in Pausing              | Notes                                                                |
| -------------------------------------- | -------------------------------- | -------------------------------- | -------------------------------------------------------------------- |
| **Boot disk**                          | Preserved                        | Preserved                        | OS, environment, and data on boot disk remain intact                 |
| **Ephemeral storage**                  | Lost (wiped when instance stops) | Lost (wiped when instance stops) | Local NVMe or scratch disks tied to instance lifecycle               |
| **Persistent storage**                 | Preserved                        | Preserved                        | Persistent volumes not affected by either state                      |
| **Ability to edit persistent storage** | Not allowed during preemption    | Allowed only when bid is paused  | Persistent storage attachments can be added/edited only while paused |

Pausing spot bids allows you to setup your environment once and save both time and money when you need to resume those workloads. Note that the pausing and resumption of any spot bid is fully determined by the user while preemption occurs based on the market price.

## FAQs & troubleshooting

To learn the nuances of the Mithril spot auction, read [Spot auction mechanics](/compute-and-storage/spot-bids/spot-auction-mechanics).

<details>

<summary>How do I know what limit price to set so that my bid is allocated immediately?</summary>

The **Price Chart** page displays the most recent spot prices for all instance types. These spot prices are determined by the highest *losing* spot bid, meaning that you may need to bid well above this price for your bid to be instantly successful.&#x20;

In the case that you need to provision compute immediately and reserved compute is unavailable, Foundry recommends setting the limit price for your bid at your next best alternative for on-demand compute (this could be the AWS or GCP on-demand price, for example). This ensures that your bid will be allocated unless the spot price exceeds these alternatives for on-demand compute (which has never occured).

Foundry never displays the lowest winning price to ensure a fair auction and to encourage setting truthful limit prices.

</details>

<details>

<summary>Does Mithril always have spot capacity available?</summary>

Yes. Unlike traditional clouds, Mithril always maintains dedicated spot capacity in every region. This ensures that you can always spin up some amount of spot compute on short notice.

</details>

<details>

<summary>My limit price is higher than the current spot price for the instance type I requested, but my bid still isn't allocated.</summary>

This typically occurs when your bid requests multiple instances, and after allocating all bids with higher limit prices, fewer instances remain than the quantity your bid is requesting.&#x20;

For example, if after allocating all bids with a higher limit price, three instances remain, and your bid requests four instances, Foundry will be unable to allocate your bid and will move to allocate the next-highest bid requesting three instances or fewer. In this scenario, the spot price would be set below your bid's limit price, but your bid would not be allocated.

</details>


# Spot auction mechanics

How Mithril allocates spot compute

Mithril allocates spot instances through a blind second-price auction to ensure fair and efficient distribution. This article provides a deep dive into the mechanics of this auction and how it handles allocation in various cases.

## Second-price auction overview

In a second-price auction, all participants submit sealed bids noting the maximum price (known as the **limit price**) they are willing to pay for the item without knowing the value of the other bids. Those who win the auction do not pay their limit price but the limit price of the highest losing bid. This mechanism encourages participants to bid their true valuation for the item because overbidding does not increase the price they pay if they win.

Consider a simple example where there are 3 (identical) spot instances available in a hypothetical `region-a` and 6 bids, each for a single instance:

<table><thead><tr><th width="97">Bid</th><th width="262">Bid limit price ($/instance/hr)</th><th>Price paid ($/instance/hr)</th></tr></thead><tbody><tr><td><strong>A ✅</strong></td><td>$23.00</td><td>$13.00</td></tr><tr><td><strong>B ✅</strong></td><td>$21.00</td><td>$13.00</td></tr><tr><td><strong>C ✅</strong></td><td>$16.00</td><td>$13.00</td></tr><tr><td><strong>D ❌</strong></td><td>$13.00</td><td>--</td></tr><tr><td><strong>E ❌</strong></td><td>$12.00</td><td>--</td></tr><tr><td><strong>F ❌</strong></td><td>$8.00</td><td>--</td></tr></tbody></table>

In this example, bids `A`, `B`, and `C` are allocated, and they each pay $13.00/instance/hr, the limit price of the highest losing bid, as long as their instance remains allocated.&#x20;

It is important to note that in this case, $13.01 becomes the **spot price** for `region-a`, but a new bid (`X`) with a limit price of $13.01 would not be successful:

<table><thead><tr><th width="97">Bid</th><th width="262">Bid limit price ($/instance/hr)</th><th>Price paid ($/instance/hr)</th></tr></thead><tbody><tr><td><strong>A ✅</strong></td><td>$23.00</td><td>$13.01</td></tr><tr><td><strong>B ✅</strong></td><td>$21.00</td><td>$13.01</td></tr><tr><td><strong>C ✅</strong></td><td>$16.00</td><td>$13.01</td></tr><tr><td><strong>X ❌</strong></td><td>$13.01</td><td>--</td></tr><tr><td><strong>D ❌</strong></td><td>$13.00</td><td>--</td></tr><tr><td><strong>E ❌</strong></td><td>$12.00</td><td>--</td></tr><tr><td><strong>F ❌</strong></td><td>$8.00</td><td>--</td></tr></tbody></table>

Although bid `X` is higher than the *previous* spot price of $13.00, it is not higher than the lowest winning bid, `C`, at $16.00. Because of this, bid `X` is not allocated, but it does raise the current spot price to $13.01, since it becomes the highest losing bid.

### Multi-instance allocation logic

To support distributed workloads, a single bid can request multiple instances. **Bids for multiple instances are all-or-nothing**, meaning the bid will not be successful if there aren't enough spot instances remaining to allocate the entire bid. In certain cases, this can mean bids with lower limit prices will be allocated even when higher bids are not. To demonstrate, let's again consider an example where 3 spot instances are available:

<table><thead><tr><th width="97">Bid</th><th width="163"># of instances</th><th width="143">Bid limit price</th><th width="115">Price paid</th><th>Instances remaining</th></tr></thead><tbody><tr><td>--</td><td>--</td><td>--</td><td>--</td><td>3</td></tr><tr><td><strong>A ✅</strong></td><td>2</td><td>$23.00</td><td>$13.00</td><td>1</td></tr><tr><td><strong>B ❌</strong></td><td>2</td><td>$21.00</td><td>--</td><td>1</td></tr><tr><td><strong>C ✅</strong></td><td>1</td><td>$16.00</td><td>$13.00</td><td>0</td></tr><tr><td><strong>D ❌</strong></td><td>1</td><td>$13.00</td><td>--</td><td>0</td></tr><tr><td><strong>E ❌</strong></td><td>1</td><td>$12.00</td><td>--</td><td>0</td></tr><tr><td><strong>F ❌</strong></td><td>1</td><td>$8.00</td><td>--</td><td>0</td></tr></tbody></table>

In this case, bid `B` is unsuccessful because it requests 2 instances, but there is only 1 instance remaining in the spot pool after all higher bids are allocated (bid `A`, in this case). Bid `C` is then allocated because it only requests 1 instance.&#x20;

{% hint style="info" %}
Although bid `B` is unsuccessful, it does not qualify as the "highest losing bid" for the purposes of setting the spot price because there are successful bids below it.
{% endhint %}

### Tied bids

In the case of tied bids (bids at the same limit price), the spot auction preferentially allocates older bids first. The age of a bid is based on the bid's creation time or, if the bid was ever paused, based on when the bid was last resumed.&#x20;

## Preemption & price change scenarios

The Mithril spot auction is fully dynamic, meaning that allocation and prices can change in real time based supply and demand. Concretely, changes are triggered when:

1. Capacity is added or removed from the spot pool (*supply*)
2. Bids are created or canceled (*demand*)

Consider the table below as the initial state of the spot market in a specific region:

<table><thead><tr><th width="97">Bid</th><th width="144"># of instances</th><th width="143">Bid limit price</th><th width="115">Price paid</th><th>Instances remaining</th></tr></thead><tbody><tr><td>--</td><td>--</td><td>--</td><td>--</td><td>3</td></tr><tr><td><strong>A ✅</strong></td><td>1</td><td>$23.00</td><td>$13.00</td><td>2</td></tr><tr><td><strong>B ✅</strong></td><td>1</td><td>$21.00</td><td>$13.00</td><td>1</td></tr><tr><td><strong>C ✅</strong></td><td>1</td><td>$16.00</td><td>$13.00</td><td>0</td></tr><tr><td><strong>D ❌</strong></td><td>1</td><td>$13.00</td><td>--</td><td>0</td></tr><tr><td><strong>E ❌</strong></td><td>1</td><td>$12.00</td><td>--</td><td>0</td></tr><tr><td><strong>F ❌</strong></td><td>1</td><td>$8.00</td><td>--</td><td>0</td></tr></tbody></table>

Each of the sections below introduces a change to the market and examines how it would affect allocation and spot prices.

### Instances added to the spot pool

Two additional instances are added to the spot pool.

<table><thead><tr><th width="97">Bid</th><th width="144"># of instances</th><th width="143">Bid limit price</th><th width="115">Price paid</th><th>Instances remaining</th></tr></thead><tbody><tr><td>--</td><td>--</td><td>--</td><td>--</td><td><mark style="background-color:green;">5</mark></td></tr><tr><td><strong>A ✅</strong></td><td>1</td><td>$23.00</td><td>$8.00</td><td>4</td></tr><tr><td><strong>B ✅</strong></td><td>1</td><td>$21.00</td><td>$8.00</td><td>3</td></tr><tr><td><strong>C ✅</strong></td><td>1</td><td>$16.00</td><td>$8.00</td><td>2</td></tr><tr><td><strong>D ✅</strong></td><td>1</td><td>$13.00</td><td>$8.00</td><td>1</td></tr><tr><td><strong>E ✅</strong></td><td>1</td><td>$12.00</td><td>$8.00</td><td>0</td></tr><tr><td><strong>F ❌</strong></td><td>1</td><td>$8.00</td><td>--</td><td>0</td></tr></tbody></table>

**Outcome(s):**

* Bids `D` and `E` are allocated
* The spot price decreases from $13.00 to $8.00

### Instances removed from the spot pool

One instance is removed from the spot pool. (Capacity reduced from 3 instances to 2)

<table><thead><tr><th width="97">Bid</th><th width="144"># of instances</th><th width="143">Bid limit price</th><th width="115">Price paid</th><th>Instances remaining</th></tr></thead><tbody><tr><td>--</td><td>--</td><td>--</td><td>--</td><td><mark style="background-color:green;">2</mark></td></tr><tr><td><strong>A ✅</strong></td><td>1</td><td>$23.00</td><td>$16.00</td><td>1</td></tr><tr><td><strong>B ✅</strong></td><td>1</td><td>$21.00</td><td>$16.00</td><td>0</td></tr><tr><td><strong>C ❌</strong></td><td>1</td><td>$16.00</td><td>--</td><td>0</td></tr><tr><td><strong>D ❌</strong></td><td>1</td><td>$13.00</td><td>--</td><td>0</td></tr><tr><td><strong>E ❌</strong></td><td>1</td><td>$12.00</td><td>--</td><td>0</td></tr><tr><td><strong>F ❌</strong></td><td>1</td><td>$8.00</td><td>--</td><td>0</td></tr></tbody></table>

**Outcome(s):**

* Bid `C` is preempted (with a 5-minute warning)
* The spot price increases from $13.00 to $16.00

### Bids created

Bids `X` and `Y` are created.

<table><thead><tr><th width="97">Bid</th><th width="144"># of instances</th><th width="143">Bid limit price</th><th width="115">Price paid</th><th>Instances remaining</th></tr></thead><tbody><tr><td>--</td><td>--</td><td>--</td><td>--</td><td>3</td></tr><tr><td><strong>A ✅</strong></td><td>1</td><td>$23.00</td><td>$16.00</td><td>2</td></tr><tr><td><strong>X ✅</strong></td><td>1</td><td>$22.00</td><td>$16.00</td><td>1</td></tr><tr><td><strong>B ✅</strong></td><td>1</td><td>$21.00</td><td>$16.00</td><td>0</td></tr><tr><td><strong>C ❌</strong></td><td>1</td><td>$16.00</td><td>--</td><td>0</td></tr><tr><td><strong>D ❌</strong></td><td>1</td><td>$13.00</td><td>--</td><td>0</td></tr><tr><td><strong>Y ❌</strong></td><td>1</td><td>$12.00</td><td>--</td><td>0</td></tr><tr><td><strong>E ❌</strong></td><td>1</td><td>$12.00</td><td>--</td><td>0</td></tr><tr><td><strong>F ❌</strong></td><td>1</td><td>$8.00</td><td>--</td><td>0</td></tr></tbody></table>

**Outcome(s):**

* Bid `C` is preempted (with a 5-minute warning)
* Bid `X` is allocated
* The spot price increases from $13.00 to $16.00

### Bids canceled

Bids `A` and `C` are canceled.

<table><thead><tr><th width="97">Bid</th><th width="144"># of instances</th><th width="143">Bid limit price</th><th width="115">Price paid</th><th>Instances remaining</th></tr></thead><tbody><tr><td>--</td><td>--</td><td>--</td><td>--</td><td>3</td></tr><tr><td><strong>B ✅</strong></td><td>1</td><td>$21.00</td><td>$8.00</td><td>2</td></tr><tr><td><strong>D ✅</strong></td><td>1</td><td>$13.00</td><td>$8.00</td><td>1</td></tr><tr><td><strong>E ✅</strong></td><td>1</td><td>$12.00</td><td>$8.00</td><td>0</td></tr><tr><td><strong>F ❌</strong></td><td>1</td><td>$8.00</td><td>--</td><td>0</td></tr></tbody></table>

**Outcome(s):**

* Bids `D` and `E` are allocated
* The spot price decreases from $13.00 to $8.00

## FAQs

<details>

<summary>Q: My bid was preempted but the spot price is still below my limit price</summary>

A: This can occur on rare occasions for multi-instance bids when the number of spot instances in the spot pool is reduced, and there are no longer enough instances to fulfill your bid. In this case, because multi-instance bids are all-or-nothing, your bid will be preempted, but bids requesting fewer instances at a lower limit price may then be filled.

</details>

<details>

<summary>Q: What is "Win price"?</summary>

A: "Win price" displayed in the spot auction UI is the current lowest allocated bid. "Spot market" price is the highest losing bid. Bidding above the win price providers higher chance for your bid to be allocated, but **does not guarantee it**, for example due to other market participants bidding up in response to preemption, or due to considerations regarding bid instance size.

</details>


# Handling spot interruptions

Working with a dynamic spot market means that your spot bids may get preempted if your bid is no longer winning. In order to work efficiently with changes in the spot market, we recommend implementing preemption and resumption handlers that will automatically take action during the 5-minute preemption and relocation windows.

### Checking for a preemption

When a spot bid is preempted, the status of all instances within the bid changes to `STATUS_PREEMPTING`.&#x20;

Previously, to check the instance status within the instance, the user had to generate an API key, embed it within an instance, and deploy a service within the instance to poll the instance status API endpoint.

**As of February 2026, users can now simply check the `/opt/mithril/MITHRIL_SIGNAL.yml` file for the instance status.** If the file is not present, the instance is not being preempted, and no instances in the order are being relocated :tada:

If the file is present, check the contents for:

* `instance_status`: The status of the particular instance
  * `STATUS_PREEMPTING` indicates that the instance is being preempted, and will be stopped at the `end_time` provided in the file
  * `STATUS_RELOCATING` indicates that the instance will be relocated at the `end_time` provided in the file. This means that the instance will stop and restart.
* `bid_status`: The status of the instance's bid
  * `Relocating` indicates that one or more of the instances in the order will be relocated at the `end_time` provided in the file.
* `end_time`: The time at which the instance will terminate, or another relocating instance will stop and restart.

{% hint style="info" icon="triangle-exclamation" %}
**Note:** it is possible for the bid to be re-allocated during the 5-minute preemption window if the market price changes. In this case, the Mithril Signal file will be removed.\
\
We recommend saving your work when a preemption occurs without killing the workload, so that your workloads may resume immediately if the bid is reallocated during the preemption window.
{% endhint %}

#### Preemption

In the basic preemption case, the Mithril Signal file in each instance of the preempted bid will be as follows:

```yml
instance_status: STATUS_PREEMPTING
bid_status: Allocated
end_time: 2026-02-12 15:47:08.751581-08:00
```

#### Relocation

You have a 2-instance order called `magnificent-leopard`, of which `magnificent-leopard-1` is detected to have a GPU error. Mithril support will relocate `magnificent-leopard-1`, so the Mithril Signal file on each instance will show:

```yml
## on magnificent-leopard-1
instance_status: STATUS_RELOCATING
bid_status: Relocating
end_time: 2026-02-12 15:47:08.751581-08:00
```

```yml
## on magnificent-leopard-2
instance_status: STATUS_RUNNING
bid_status: Relocating
end_time: 2026-02-12 15:47:08.751581-08:00
```

Note that the instance status for `magnificent-leopard-2` is *not* relocating. The `end_time` in this case refers to the time at which `magnificent-leopard-1` will be relocated.

However, you may still wish to take action on both instances in this case, for example by pausing your workload until the relocating instance resumes.

### Handling preemptions

Here's a snippet of how to check the Mithril Signal file for preemption:

```py
## Preemption check
def is_preempting() -> bool:
    status = ''
    try:
        with open('/opt/mithril/MITHRIL_SIGNAL.yml', 'r') as f:
            status = f.read()
    except FileNotFoundError:
        return False
    return "STATUS_PREEMPTING" in status

## Later, in your training loop, use preempting() to save a checkpoint on demand:
if is_preempting():
    save_checkpoint()
```

### Resuming workloads

If market prices drop and your spot bid wins, instances will be reallocated. We recommend automating the resumption of jobs when instances restart in order to take full advantage of the time an instance is allocated.

To automatically start jobs, we recommend writing a `systemd` service that will execute on restart, and adding it to the startup *script*, which executes only once, when an instance is launched for the first time. The startup *service* will start each time an instance boots up.

Check the following documentation for more information: [Startup scripts](/compute-and-storage/startup-scripts#running-scripts-on-subsequent-startups)


# Startup scripts

Startup scripts perform tasks during the initial startup process of your instances. They can be used to automatically configure your environment and workloads, alleviating manual setup. See [Instance types & specifications](/compute-and-storage/instance-types-and-specifications) for information on what Mithril installs by default on all instances.

{% hint style="warning" %}
Startup scripts only run the *first* time your instance starts up. Your startup script *will not* run again if your instance is relocated or preempted and allocated at a later time. You can use a `systemd` service to [run scripts on boot after relocation or preemption](#running-scripts-on-subsequent-startups). Learn more about relocation and preemption statuses [here](/compute-and-storage/access-and-manage-instances/statuses).
{% endhint %}

## Creating a startup script

You have the option to add a startup script each time you create a new reservation or spot bid. Startup scripts must be added before submitting your reservation or bid; they cannot be added later.

You can add a startup script to your reservation or bid in the Mithril console by attaching a bash or txt file or manually typing a script into the startup script field.

Startup scripts must start with `#!/bin/bash` and are limited to a maximum length of 10,000 characters.

## Accessing start-up script and logs

To access your start-up script  from your instance, run the following command:

```bash
cat /var/lib/foundry/startup_script.sh
```

To access any start-up script logs from your instance, run the following command:

```bash
cat /var/log/foundry/startup_script.log
```

## Running scripts on subsequent startups after relocation, preemption, or resuming a spot bid <a href="#running-scripts-on-subsequent-startups" id="running-scripts-on-subsequent-startups"></a>

The startup script added when creating your reservation or spot bid is only executed the first time your instance starts up. **It will not run again if your instance is relocated, preempted, restarted, or resumed.**

However, because Mithril preserves the boot disk for your spot instances until you fully terminate your spot bid, you can use `systemd` services to implement logic that restarts your workload the next time your spot instances start up after being relocated or preempted. You can use your initial startup script to set up a `systemd` service.

Here is a simple example of a startup script that creates a `hello-world.sh` script and a `systemd` service, `startup.service`, which will run `hello-world.sh` on all subsequent startups:

```bash
#!/bin/bash

# Create the .sh file we want to run on startup
sudo tee -a /usr/local/sbin/hello-world.sh >/dev/null << 'EOF'
#!/bin/bash
echo “Hello World!”
EOF

# Make the .sh file executable
sudo chmod +x /usr/local/sbin/hello-world.sh

# Create a .service file to define a systemd service 
sudo tee -a /etc/systemd/system/startup.service >/dev/null << 'EOF'
[Unit]
Description=My Startup Script

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/hello-world.sh

[Install]
WantedBy=multi-user.target
EOF

# Enable services to run on boot
sudo systemctl enable startup.service

echo "hello-world.sh will run on subsequent startups."
```


# Access & manage instances

See the status of your instances, reservations, and spot bids

You can see the status of all your reservations, spot bids, and individual instances on the **Instances** page.

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

## Accessing instances

All of your instances are accessible using the instance IP address and your selected SSH key:

{% stepper %}
{% step %}

### Prepare your key

Before connecting, make sure you have the correct permissions on your private key file. You can do this with the following command:

```bash
chmod 600 /path/to/your/private/key
```

Replace **/path/to/your/private/key** with the path to your actual private key file.
{% endstep %}

{% step %}

### Connect to the instance

Use the following command to connect to your instance:

```bash
ssh -i /path/to/your/private/key ubuntu@<ip>
```

Again, replace **/path/to/your/private/key** with the path to your actual private key file.
{% endstep %}

{% step %}

### (Optional) Add additional users and keys

Once you are connected, you can add additional users and keys. Here's an example of how you can do this:

```bash
# Create a new user

sudo adduser new_user

# Switch to the new user

sudo su - new_user

# Create .ssh directory for the new user

mkdir ~/.ssh

# Change the directory permissions

chmod 700 ~/.ssh

# Create authorized_keys file

touch ~/.ssh/authorized_keys

# Add the public key to the authorized_keys file

echo "new_user_public_key" >> ~/.ssh/authorized_keys

# Change the file permissions

chmod 600 ~/.ssh/authorized_keys
```

Replace **new\_user** with the username of the new user, and **new\_user\_public\_key** with the new user's public SSH key.
{% endstep %}
{% endstepper %}


# Statuses

### Spot bid

{% hint style="info" %}
Instances will not appear and are not accessible until your spot bid has been <mark style="color:green;">Allocated</mark>.&#x20;
{% endhint %}

| Status                                        | Description                                                                                                           |
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Open bid                                      | Instances will be allocated when your bid wins. Your bid will remain open for allocation until you terminate the bid. |
| <mark style="color:green;">Allocated</mark>   | Instances have been allocated for use while your bid is winning.                                                      |
| <mark style="color:orange;">Preempting</mark> | Your limit price has been outbid. This spot bid will remain open but access to instances will stop in 5 minutes.      |
| <mark style="color:blue;">Paused</mark>       | You have paused your spot bid to spin-down associated instances & preserving boot disk.                               |
| <mark style="color:red;">Terminated</mark>    | Your bid was terminated. Instances will no longer be allocated.                                                       |

### Spot instance

{% hint style="info" %}
We do not charge for the <mark style="color:blue;">Starting</mark> time. Any accumulated charges will be deducted at the end of the billing cycle.
{% endhint %}

| Status                                        | Description                                                                        |
| --------------------------------------------- | ---------------------------------------------------------------------------------- |
| <mark style="color:blue;">Starting</mark>     | Your bid is winning. Please reach out if your wait time is longer than 20 minutes. |
| <mark style="color:green;">Running</mark>     | Your bid is winning. This instance is accessible via SSH.                          |
| <mark style="color:blue;">Relocating</mark>   | This instance will be relocated to a new host in 5 minutes.                        |
| <mark style="color:orange;">Preempting</mark> | Your limit price has been outbid. This instance will stop in 5 minutes.            |
| <mark style="color:orange;">Preempted</mark>  | Your limit price has been outbid. This instances is no longer allocated.           |
| <mark style="color:yellow;">Paused</mark>     | Your spot bid was paused. The instance is not accessible until the bid is resumed. |
| <mark style="color:red;">Terminated</mark>    | Your spot bid was terminated. This instance is no longer allocated.                |

### Reservation

| Status                                             | Description                                                            |
| -------------------------------------------------- | ---------------------------------------------------------------------- |
| Confirmed                                          | Instances will be allocated on your reservation date.                  |
| <mark style="color:green;">Allocated</mark>        | Instances have been allocated until the end of the reservation date    |
| <mark style="color:red;">Expired</mark>            | Your reservation duration expired. Instances are no longer accessible. |
| <mark style="color:red;">Ended</mark>              | Your reservation ended. Instances are no longer accessible.            |
| <mark style="color:orange;">Pending payment</mark> | Update the payment method to allow instances to be allocated.          |

### Reserved instance

| Status                                     | Description                                                                                 |
| ------------------------------------------ | ------------------------------------------------------------------------------------------- |
| Scheduled                                  | This instance will be allocated on your reservation date                                    |
| <mark style="color:blue;">Starting</mark>  | Your reservation is starting. Please reach out if your wait time is longer than 20 minutes. |
| <mark style="color:green;">Running</mark>  | Your reservation is running. This instance is accessible via SSH.                           |
| <mark style="color:red;">Terminated</mark> | Your reservation was terminated. This instance is no longer accessible.                     |


# Compute quotas

How to view and increase your quotas

To ensure relatively predictable pricing and availability, Mithril implements default quotas that limit the total amount of compute a single organization can allocate. If your requirements exceed your current quotas, Mithril can increase them for you.&#x20;

## Reservation quotas

**Reservation quotas are the maximum number of forward-looking reserved instance hours.** For example, if your reservation quota for an 8x A100 instance is 72 instance hours, you can reserve 1 instance for 72 hours or 4 instances for 18 hours (you pick the shape of your compute).&#x20;

The reservation quota only limits your *future* reserved instance hours. So, once you were halfway through your 72-hour reservation of 1 instance, you would have freed up 36 instance hours in your quota.

## Spot instance quotas

**Spot instance quotas are simply the maximum number of concurrent spot instances you can have allocated at a given time.** For example, if your spot quota for 8x A100 instances is 4 instances, you may only be allocated 4 8x A100 instances across all your bids.

## View your current compute quotas

Quotas are set on a per-instance-type basis. You can see your quotas for each instance type under **Instances > Quotas**.&#x20;

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

## Increasing your quotas

To increase your quotas, please contact your Mithril account team or email <support@mithril.ai>.


# Managing open ports

A guide to exposing ports from your Mithril instances

## Manually opening and closing ports

You can use the following to expose ports on your instances, replacing `<port_number>` with the port number you want to forward to your instance's public IP:

```sh
sudo nohup foundrypf <port_number> >/dev/null 2>&1 &
```

This will start a process that maintains the open port. You can omit `nohup` to run it in the foreground.

You can close the port with the following command, replacing `<port_number>` with the port number you want to close:&#x20;

```sh
sudo foundrypf -d <port_number>
```

## Creating a systemd service to expose ports

If you want to ensure the port forwarding is kept running in the background persistently even after a system reboot or in the case that the process fails in the background due to network blips, you can create a systemd service for it.

Open a new service file using a text editor (in this case, nano):

```bash
sudo nano /etc/systemd/system/examplefoundry.service
```

Add the following content to the service file:

```
[Unit]  
Description=Foundry Port Forwarding Service  
After=network.target
Wants=network-online.target

[Service]  
Type=simple  
User=root  
ExecStart=/usr/local/bin/foundrypf <port_number>  
Restart=always  
RestartSec=3

[Install]  
WantedBy=multi-user.target
```

Again, replace `<port_number>` with the port you want to keep forwarded persistently.

```bash
sudo systemctl daemon-reload  
sudo systemctl enable examplefoundry  
sudo systemctl start examplefoundry
```

Now, the `foundrypf` script will run as a service, and the specified port will be forwarded persistently. Adjust the `<port_number>` and service file name if you wish to set up multiple such services for different ports.

Note that lower-number ports are currently not supported on `foundrypf`. We recommend running applications on higher-number ports.


# Ephemeral storage

Each instance comes with its own ephemeral storage (outlined in [Instance types & specifications](/compute-and-storage/instance-types-and-specifications)), usually with NVMe SSD. This storage will only persist while the instance is continuously running. It will be lost during most instance events, e.g. if it is paused, relocated pre-empted, or terminated. Ephemeral storage is also wiped if the underlying host is restarted for any reason (e.g. hardware maintenance). Customer should not rely on ephemeral storage for data other than work-in-progress data as it has the lowest durability of all storage classes.

There is no cost to use the ephemeral storage.

Ephemeral storage is automatically mounted for you (and re-mounted in an empty state after preemptions) at `/mnt/local`.&#x20;


# Persistent storage

A guide to where your data should live on Mithril, and why. If you only take away one thing: keep your source of truth in an object store, and use Mithril storage for the working set your GPUs touch during a run.

{% hint style="info" %}
Mithril does not charge for ingress, egress, or network bandwidth. You pay only for the storage you provision. Pricing is at [mithril.ai/pricing](https://mithril.ai/pricing).
{% endhint %}

While each instance comes with its own ephemeral storage (see [Instance types & specifications](/compute-and-storage/instance-types-and-specifications)), that storage is wiped on preemption or reboot. Persistent storage gives you a fast, colocated working set that survives instance pauses and stops. It's the right place for data your GPUs actively use during a run and is especially valuable when:

* You'd otherwise pay egress costs re-streaming data from a third-party provider on every run.
* Your workloads would be accelerated by colocating data with your GPUs.
* You're running on spot instances and need checkpoints that survive preemption within a run.

Mithril offers two options for persistent storage:

<table data-view="cards"><thead><tr><th></th><th></th><th data-type="content-ref"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>File shares</strong></td><td>Preformatted, shared storage that mounts automatically. Best for most use cases.</td><td><a href="/pages/RdprnL0Yl6B4vLsfAyjc">/pages/RdprnL0Yl6B4vLsfAyjc</a></td><td><a href="/pages/RdprnL0Yl6B4vLsfAyjc">/pages/RdprnL0Yl6B4vLsfAyjc</a></td></tr><tr><td><strong>Block storage</strong></td><td>A raw disk volume with full filesystem control. An advanced, single-instance option.</td><td><a href="/pages/ARzw2YePZXNz7DMDVBC9">/pages/ARzw2YePZXNz7DMDVBC9</a></td><td><a href="/pages/ARzw2YePZXNz7DMDVBC9">/pages/ARzw2YePZXNz7DMDVBC9</a></td></tr></tbody></table>

### The two-tier model

Most ML teams need two different kinds of storage and get the most out of Mithril when they keep them separate.

**Tier 1: your source of truth.** Raw datasets and final checkpoints that need to live indefinitely. This belongs in an **object store** (Cloudflare R2, Amazon S3, Google Cloud Storage, Hugging Face Storage Buckets). It's cheap per gigabyte, durable, and you read from it once at the start of a run rather than continuously during it.

**Tier 2: your working set.** The data your GPUs actually read and write during a run. This belongs on **Mithril persistent storage**; either a file share or block volume colocated with your instances on a fast network. It only needs to hold what one run or project needs, and only for as long as the run or project lasts.

The job of your data pipeline is simple: **pull from the object store when a run starts; write results back when it finishes.** Everything in between happens on Mithril storage.

{% hint style="danger" %}
Mithril persistent storage is not a backup service. File shares and block volumes are not replicated across regions; if a region has an incident, your working set can be unavailable. Keep your durable source of truth in an object store.
{% endhint %}

### Why an object store for source of truth

Object stores are the right home for data that has to outlive individual runs. They're durable, cheap per gigabyte, and decouple your data's lifetime from any single instance or region so your source of truth persists whether or not you have compute running or a run is in flight. Mithril persistent storage is built for the opposite job: fast, colocated access during a run. The two are complementary, which is why the two-tier model pairs them.

Once you've decided your source of truth lives in an object store, the next question is which one and here the economics matter. Mithril doesn't charge for moving data in or out, but your object store provider probably does. Egress from S3, GCS, or Azure Blob typically runs several cents per gigabyte. If you pull a multi-terabyte dataset onto a fresh working set at the start of every run (a natural pattern on ephemeral GPU compute) those charges add up fast.

**Cloudflare R2 and Hugging Face Storage Buckets charge nothing for egress.** Storage cost is comparable to S3, but data leaves for free: to Mithril, to your laptop, to another cloud. If you're choosing an object store from scratch and expect to pull data more than once, R2 is usually the most economical option. If you're already established on S3 or GCS, they work fine; just be aware of the egress bill.

To pull object-store data onto an instance using the Mithril CLI, use cloud bucket mounts (`file_mounts`) in your task YAML. See [Data & storage](/mithril-cli/task-yaml/data-and-storage).

### Choosing between file shares and block storage

#### File shares: the default choice

Use a **file share** when more than one instance needs to read or write the same files: multi-node training with shared checkpoints, a dataset several instances read from, or anything where you'd otherwise copy data to N machines and manage consistency yourself.

* Readable and writable from **multiple instances concurrently**
* **Read-optimized** (you'll typically see higher read than write speeds)
* Auto-mounted at `/mnt/<name>` on instances that select it
* Maximum size 32TB; resize by contacting your account team

This is the right choice for most workloads. See [File shares](/compute-and-storage/persistent-storage/file-shares).

#### Block storage: the advanced choice

Use **block storage** when you want a raw disk and full control over the filesystem on a single instance.

* Readable and writable from **only one instance at a time**. Concurrent read-write mounts will corrupt the filesystem.
* Requires manual setup: format, mount, and add to `fstab` yourself

If you need shared storage, use a file share instead. See [Block storage](https://claude.ai/compute-and-storage/persistent-storage/block-storage.md).

{% hint style="warning" %}
Block volumes cannot be shrunk or expanded after creation. Size them correctly up front. File shares, by contrast, can be resized on request.
{% endhint %}

#### Ephemeral storage: free scratch space

Every instance comes with NVMe SSD ephemeral storage mounted at `/mnt/local`, at no cost. Use it for scratch work, caches, and shuffle buffers. See [Ephemeral storage](/compute-and-storage/ephemeral-storage).

{% hint style="warning" %}
Ephemeral storage at `/mnt/local` is wiped on preemption, relocation, or reboot. Don't keep anything there you need. It is reserved for ephemeral use, so don't mount persistent volumes to that path.
{% endhint %}

### Quick decision guide

| Use case                                                  | Recommended storage option    |
| --------------------------------------------------------- | ----------------------------- |
| Raw datasets and final checkpoints that live indefinitely | Object store (R2 recommended) |
| Shared files across multiple instances or nodes           | File share                    |
| Fast per-instance persistent disk, single writer          | Block storage                 |
| Temporary scratch, caches, shuffle buffers                | Ephemeral (`/mnt/local`)      |

### Region availability

Storage is region-scoped: a volume can only be attached to instances in the same region.

<table><thead><tr><th>Region</th><th width="184.46484375">GPU</th><th align="center">File shares</th><th align="center">Block storage</th></tr></thead><tbody><tr><td>us-central2-a</td><td>H100</td><td align="center">✓</td><td align="center">✓</td></tr><tr><td>us-central2-b</td><td>H200</td><td align="center">✓</td><td align="center">✓</td></tr><tr><td>us-central3-a</td><td>A100</td><td align="center">✗</td><td align="center">✓</td></tr><tr><td>us-central5-a</td><td>B200</td><td align="center">✓</td><td align="center">✓</td></tr></tbody></table>

File shares are not currently available in the A100 region (us-central3-a).

### Attaching storage to existing instances

Storage selected when you create a reservation or spot bid is mounted automatically. To add storage to an instance that's already running, the instance must be in a **Paused** state, and volumes attached this way won't auto-mount — you'll mount them manually.

<details>

<summary>Mounting a file share added to a running instance</summary>

If the instance has already booted when you attach a new file share, mount it in the standard format with:

```bash
FILESHARE_NAME=<insert-name-here>
sudo mkdir /mnt/$FILESHARE_NAME
sudo chmod 777 /mnt/$FILESHARE_NAME
echo "$FILESHARE_NAME /mnt/$FILESHARE_NAME virtiofs defaults,nofail 0 1" | sudo tee -a /etc/fstab
sudo mount -a
```

See [File shares](/compute-and-storage/persistent-storage/file-shares) for full details.

</details>

<details>

<summary>Mounting a block volume added to a running instance</summary>

Block volumes require formatting on first use and manual mounting. The full sequence (finding the device name, formatting, mounting, and persisting across reboots) is documented on the [Block storage](/compute-and-storage/persistent-storage/block-storage) page.

</details>

### Next steps

* [File shares](/compute-and-storage/persistent-storage/file-shares): provisioning, mounting, performance benchmarks
* [Block storage](/compute-and-storage/persistent-storage/block-storage): raw disk setup and filesystem control
* [Data & storage (task YAML)](/mithril-cli/task-yaml/data-and-storage): mounting object-store buckets and volumes in your runs
* [Ephemeral storage](/compute-and-storage/ephemeral-storage): instance-local scratch specs


# File shares

Provisioning file shares for your instances

File shares provide convenient, high-performance file storage for your instances. File shares selected on instance creation are automatically mounted to your instances as a directory under `/mnt`, and are readable and writable from multiple instances concurrently.

{% hint style="info" %}
File shares are read-optimized. You are likely to see higher read speeds in practice.
{% endhint %}

## Provisioning file share storage

To provision file share storage, go to **Storage**, click **+ Create storage** and select **File share** for the type field.

1. Select the region you would like to provision in.
2. Select the size for your disk. Currently, each file share has a **maximum size of 32TB**.

When creating a file share, you must provide a unique **Name** which will be used for the folder where it will be automatically mounted inside your instance. For example, if you named your file share "training-model" it will be automatically mounted on the `/mnt/training-model` folder after your instance is launched.

File share storage is currently available in the following regions:

| Region        | GPUs available |
| ------------- | -------------- |
| us-central2-a | NVIDIA H100    |
| us-central2-b | NVIDIA H200    |
| us-central5-a | NVIDIA B200    |

## Attach storage to new reservations and spot bids

Provisioned storage is available for selection while creating a reservation or spot bid. You can attach as many storage options as needed from the same region. If you select a region that does not have provisioned storage, it will not appear as an option.

## Attaching new file shares to existing instances

You can attach new files shares to existing instances when they are in a Paused state. If the instance has already booted up once when you do this, the new file shares will not automatically be mounted for you. To mount the new file shares in the standard format, you can use the following commands:

```bash
FILESHARE_NAME=<insert-name-here>
sudo mkdir /mnt/$FILESHARE_NAME
sudo chmod 777 /mnt/$FILESHARE_NAME
echo "$FILESHARE_NAME /mnt/$FILESHARE_NAME virtiofs defaults,nofail 0 1" | sudo tee -a /etc/fstab
sudo mount -a
```

## Accessing the file share from your instance

By default, attached file shares are automatically mounted at `/mnt/<FILESHARE_NAME>`. You can list all mounted file shares using this command:

```bash
$ mount | grep virtiofs
```

Please note `/mnt/local` is reserved for ephemeral storage which is wiped out on instance preemption, relocation, or reboot.

## Performance & benchmarks

Actual performance for your file share is likely to vary greatly depending on your workload and instance configuration; however, below are representative benchmarks for a single 8x H100 instance:

<table><thead><tr><th width="205">Sequential Read BW</th><th>Read IOPS (4Kb)</th><th width="197">Sequential Write BW</th><th>Write IOPS (4Kb)</th></tr></thead><tbody><tr><td>5600MB/s</td><td>60k</td><td>2250MB/s</td><td>45k</td></tr></tbody></table>

The numbers above are a snapshot meant for guidance. We are constantly making improvements to optimize performance. You can also run the benchmarks yourself from your instances using the following:

```bash
export TEST_DIR=/mnt/filesharename/
export OUTPUT_DIR=/tmp

# sequential write bw
fio --name=write_throughput --directory=$TEST_DIR --numjobs=8 \
  --size=5G --time_based --runtime=1m --ramp_time=2s --ioengine=libaio \
  --direct=1 --verify=0 --bs=1M --iodepth=1 --rw=write \
  --group_reporting=1 | tee "$OUTPUT_DIR/0-write_throughput.txt"

# randwrite iops
fio --name=write_iops --directory=$TEST_DIR --numjobs=8 --size=5G \
  --time_based --runtime=1m --ramp_time=2s --ioengine=libaio --direct=1 \
  --verify=0 --bs=4K --iodepth=64 --rw=randwrite --group_reporting=1 | tee "$OUTPUT_DIR/1-write_iops.txt"

# sequential read bw
fio --name=read_throughput --directory=$TEST_DIR --numjobs=8 \
  --size=5G --time_based --runtime=1m --ramp_time=2s --ioengine=libaio \
  --direct=1 --verify=0 --bs=1M --iodepth=1 --rw=read \
  --group_reporting=1 | tee "$OUTPUT_DIR/2-read_throughput.txt"

# randread iops
fio --name=read_iops --directory=$TEST_DIR --size=5G --numjobs=8 \
  --time_based --runtime=1m --ramp_time=2s --ioengine=libaio --direct=1 \
  --verify=0 --bs=4K --iodepth=64 --rw=randread --group_reporting=1 | tee "$OUTPUT_DIR/3-read_iops.txt"
```

## Quotas

Each project has a total storage capacity quota that accumulates usage across all regions. Contact your account team via Slack or email <support@mithril.ai> to increase your quota.

## Resizing file share volumes

If you need to resize your file share volume, please contact your account team via slack or email <support@mithril.ai>.


# Block storage

Provision raw disk storage

{% hint style="info" %}
Block storage requires a quota to be added to your account. For access, contact your account team via Slack or email <support@mithril.ai>
{% endhint %}

Block storage gives you the most control over your storage approach by providing a blank disk that can be attached to your instances. Block storage typically requires a more lengthy setup. If you need shared storage across multiple instances, we recommend using [file share storage](/compute-and-storage/persistent-storage/file-shares) instead.

{% hint style="danger" %}
Block storage volumes are **single-writer**. You can only mount a volume read-write from **only one instance at a time**. Mounting the same volume read-write from multiple instances is unsupported and will likely cause filesystem and data corruption.

The only supported multi-instance pattern is mounting the volume **read-only**, with **no concurrent write mounts**. For more details, please contact support.
{% endhint %}

## Provisioning block storage

To provision block storage, go to **Storage**, select **+ Create Storage**, and select **Block**.

1. Select the region you would like to provision your Block storage in.
2. Select the size for your disk. Currently, each block storage disk has a **maximum size of 32TB.**

   NOTE: instances in us-central2-a have 15TB and instances in us-central2-b have 12.5TB of ephemeral storage.

{% hint style="info" %}
Tip: Give your disks different sizes to make it easier to find the disk you're looking for inside your VM.
{% endhint %}

## Attach storage to reservations and spot bids

Provisioned storage is available for selection while creating a reservations or spot bid. You can attach as many storage options as needed from the same region. If you select a region that does not have provisioned storage, it will not appear as an option.

For existing instances, you can attach/detach storage volumes when the instances are in a Paused state. You will need to manually mount the new volumes.

{% hint style="warning" %}
Currently, it's not possible to shrink/expand disk size.
{% endhint %}

## Using the disk from your instance

<details>

<summary>Find the disk device name(s) using lsblk</summary>

List your block devices with lsblk. Your selected disks will start from vdd and extend to however many you added in order alphabetically.

```bash
$ lsblk
```

</details>

<details>

<summary>First time only - format the disks</summary>

If this is the first time using this disk, you will need to format and define a filesystem. In the below command:

* Replace `/mount/dir/path` with the local directory where you want the disk mounted
* Replace `/dev/name` with the disk name selected from the output of `lsblk`

⚠️ Running this command will erase the disk content if previously mounted ⚠️

```bash
sudo mkdir -p /mount/dir/path
sudo mkfs.ext4 /dev/name
```

Repeat this for all disks you are formatting.

</details>

<details>

<summary>Mount the disks</summary>

Finally, mount the disk with the below, replacing `/dev/name` and `/mount/dir/path` with the local directory of where the disk will be mounted and the disk name

```bash
sudo mount -t ext4 /dev/name /mount/dir/path
sudo chown -R $USER:$USER /mount/dir/path
```

Repeat this for all disks you are mounting.

</details>

<details>

<summary>Persist mounted disks across reboots</summary>

1. Get the `UUID` of your disks

```bash
sudo blkid
```

2. Open `/etc/fstab` in your text editor

```bash
sudo vim /etc/fstab
```

3. Add the disk to your `fstab`

```bash
# Example template
UUID=DISK_UUID MOUNT_POINT ext4 OPTIONS <dump> <pass> 
```

It looks something like this. We strongly recommend using the `nofail` option to prevent instance failure in case of disk failure or disk removal.

```bash
UUID=f124a6dc-a10f-4ff4-81cd-6a3990c1aa7d /mnt/disk ext4 defaults,nofail 0 2 
```

4. Save and mount

```bash
sudo mount -a
```

</details>

## Quotas

Each project has a total storage capacity quota that accumulates usage across all regions. Contact your account team via Slack or email <support@mithril.ai> to increase your quota.


# Mithril Compute Clusters

Hosted Kubernetes for your Mithril GPU instances. We run the control plane. You bring the nodes and your `kubectl`.

{% hint style="info" %}
**TL;DR.** Create a cluster in the console, attach a reservation or spot bid in the same region, run `ml k8s update-kubeconfig` locally, and `kubectl apply` your workload. Under five minutes of hands-on time end-to-end.
{% endhint %}

## What you get

A long-lived Kubernetes control plane that Mithril runs and maintains. You spin up your the worker nodes (they're just your reserved or spot GPU instances) and they join the cluster automatically when they boot. Your local `kubectl` talks to the control plane the same way it would talk to any other Kubernetes cluster.

The architecture is three pieces:

| Component                                       | Who manages it                                                      |
| ----------------------------------------------- | ------------------------------------------------------------------- |
| **Control plane** (API server, scheduler, etcd) | Mithril. Long-lived. You don't need to  touch it.                   |
| **Nodes** (GPU instances)                       | You. Created via reservation or spot bid; join the cluster on boot. |
| `kubectl`                                       | You. Standard Kubernetes from your laptop.                          |

Hosted control plane instances come pre-loaded with **Cilium CNI** and the **NVIDIA GPU Operator**, so GPU workloads are schedulable out of the box. You're free to modify the cluster configuration; this isn't a fully managed offering, and Mithril doesn't push updates beyond node lifecycle management.

## Quickstart

### Prerequisites

* A Mithril project with billing configured
* The Mithril CLI installed locally ([installation guide](/mithril-cli/installation))
* `kubectl` installed locally
* An SSH key registered to your Mithril account **before** you create the cluster (see [SSH keys and the CLI](#ssh-keys-and-the-cli) below)

### Step 1: Create the cluster

In the Mithril console:

1. Navigate to **Clusters > Create cluster**
2. Pick a region. Your worker nodes must be in the same region as the control plane or they will not join.
3. Name the cluster. Click **Create**.

Provisioning can take up to 10 minutes. When the cluster appears in the list with status `Available`, note the **Cluster host** IP. That's the public IP your `kubectl` will talk to.

### Step 2: Attach a worker node

You have two paths that both end up looking the same from inside the Kubernetes cluster:

{% tabs %}
{% tab title="Reservation" %}
When creating a reservation, select your cluster in the **Kubernetes cluster** dropdown on the order form. The instance comes up already joined.

Use this for production workloads where you need guaranteed access.
{% endtab %}

{% tab title="Spot" %}
When creating a spot bid, select your cluster in the **Kubernetes cluster** dropdown. The node joins when the bid wins, leaves when it's preempted.

Use this for experiments, batch jobs, or development.
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
The cluster's region must match the instance's region, so double-check before you submit the order.
{% endhint %}

### Step 3: Point `kubectl` at the cluster

From your laptop:

```bash
ml setup
ml k8s update-kubeconfig
```

`ml setup` authenticates the CLI to your Mithril account. `ml k8s update-kubeconfig` fetches the cluster's kubeconfig and merges it into your local `~/.kube/config` under a new context. Your other `kubectl` contexts keep working.

Verify:

```bash
kubectl config current-context  # should show your Mithril cluster
kubectl get nodes               # should list your attached node(s) as Ready
```

### Step 4: Run a GPU pod

Create `hello-gpu.yaml`:

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: hello-gpu
spec:
  containers:
  - name: cuda
    image: nvidia/cuda:12.4.0-base-ubuntu22.04
    command: ["nvidia-smi"]
    resources:
      limits:
        nvidia.com/gpu: 1
  restartPolicy: Never
```

Apply it:

```bash
kubectl apply -f hello-gpu.yaml
kubectl logs hello-gpu
```

You should see the `nvidia-smi` table. That's the full loop of adding a worker node and running a GPU workload on it.

## Persistent storage

Mithril file shares and block volumes are attachable to nodes in your cluster. Select them on the order form (reservation or spot bid) and the volumes are mounted on every node in that order.

* **File shares** (`mithril-file-share`): multi-instance, read/write across nodes used for shared datasets and checkpoints.
* **Block volumes**: single-instance, persistent disk used for per-node scratch space.

For the full decision tree (object store vs. file share vs. block, when to use which), see [Persistent storage overview](/compute-and-storage/persistent-storage).

{% hint style="info" %}
At high pod-creation rates, the storage CSI can hit a `too many concurrent requests` error. It's transient, so stagger pod creation if you're scheduling dozens of pods with persistent volumes at once.
{% endhint %}

To make persistent storage volumes accessible within the k8s cluster use `hostPath` for pod mounting, e.g:

```yaml
volumes:
  - name: data-volume
    hostPath:
      path: /mnt/your-fileshare-name
      type: Directory
```

## SSH keys and the CLI

This is the most common source of friction. `ml k8s update-kubeconfig` is not a pure API call: under the hood it SSHes into the control plane host as the `ubuntu` user to fetch the kubeconfig. If your SSH key isn't authorized on that host, the command fails with `Permission denied (publickey)`.

Three things to verify if you hit this:

1. **The key is registered to your Mithril account.** Console > SSH keys > confirm the public key matches the one you have locally.
2. **The key was registered&#x20;*****before*****&#x20;the cluster was created.** Adding a key to your account after the fact doesn't retroactively authorize it on existing clusters. If you registered the key after creating the cluster, recreate the cluster or contact support.
3. **Your local SSH agent is offering the key.** Run `ssh-add -l`. If your key isn't listed, run `ssh-add ~/.ssh/your-key` to load it. On macOS, the agent can drop keys between sessions; consider adding to `~/.ssh/config`:

```
Host *
   AddKeysToAgent yes
   UseKeychain yes
```

If `ml k8s update-kubeconfig` succeeds with the SSH step but then fails with `Failed to parse local kubeconfig`, your local `~/.kube/config` is empty, missing, or malformed. Create a minimal stub:

```bash
mkdir -p ~/.kube
cat > ~/.kube/config <<'EOF'
apiVersion: v1
kind: Config
clusters: []
contexts: []
users: []
EOF
```

Then re-run `ml k8s update-kubeconfig`.

## Node lifecycle

Mithril manages the join/drain/uncordon lifecycle automatically. You should not run `kubeadm` on a node — it will break the cluster.

| Event                                              | What Mithril does                                                                |
| -------------------------------------------------- | -------------------------------------------------------------------------------- |
| **Node joins** (boot)                              | Automatically joins the cluster, registers with the control plane                |
| **Spot preemption**                                | Sends `kubectl drain` with a 5-minute grace period, then powers off the instance |
| **Reallocation** (spot bid wins again)             | Sends `kubectl uncordon` so the scheduler resumes placing pods                   |
| **Bid termination** (instance permanently deleted) | Removes the node from the cluster                                                |

## FAQ

<details>

<summary>Can I access the cluster from outside Mithril?</summary>

Yes. The control plane has a public IP with SSH (port 22) and the Kubernetes API (port 6443) open by default.

</details>

<details>

<summary>Does MCC support autoscaling?</summary>

You can configure autoscaling for deployments inside Kubernetes (HPA, etc.) and the standard Kubernetes mechanisms work. There's no officially supported mechanism for autoscaling the underlying cluster size today. Add nodes by placing additional reservations or spot bids with the cluster selected.

</details>

<details>

<summary>Is this a fully managed Kubernetes service?</summary>

No. Mithril manages the control plane lifecycle and node join/drain/remove operations. It does not push updates to cluster configuration, manage RBAC, or handle workload-level concerns. Treat MCC as "managed control plane, self-served everything else."

</details>

<details>

<summary>Can I use <code>ml launch</code> against my cluster?</summary>

Yes. In your task YAML, set `infra: kubernetes` and your task runs against the cluster. See [Task YAML > Infra](/mithril-cli/task-yaml/infra) for the full reference.

</details>

<details>

<summary>My node never joined the cluster. What's going on?</summary>

Most likely cause: the cluster's region doesn't match the instance's region. Less common: a custom startup script that interferes with the join process, or a network policy on your side blocking outbound to the control plane.

Check the instance logs and contact support if neither applies.

</details>


# SSH keys

Manage the SSH keys you use with Mithril compute

In order to create and access instances on Mithril, you'll first need to create or add existing SSH keys. **SSH keys in Mithril are scoped to an individual project**. See [Access management](/account-and-billing/access-management) for additional information on how resources are scoped in Mithril.

{% hint style="warning" %}
While it is technically possible for users within a particular Project to share SSH keys, it is best practice to keep SSH keys unique to an individual user.
{% endhint %}

## Creating SSH keys in a project

After confirming that you are in the correct project, select **SSH keys** in the left nav.

Select **Create SSH key**, and choose if you would like Mithril to generate a new key for you or if you would like to add your own. If you would like to set a key to be by default added to every new instance, select the checkbox.

{% hint style="danger" %}
If you choose to generate a key, it will automatically download upon creation. Keep this somewhere safe! You won't be able to download it again, as Mithril never retains private keys.
{% endhint %}

## Removing SSH keys from a project

To remove an SSH key from a project, open the **•••** menu next to the key you want to remove and choose **Delete**.

## Setting required SSH keys

An administrator can set an SSH key (or multiple) to be required for all new instances in a project. This can be done when creating a new key, or to existing keys with the **•••** menu. For security purposes, all keys for an instance will be shown to the user:

* **Console:** When creating a new order, the required key(s) will be pre-selected.
* **API:** When submitting a new order, the required key(s) must be included in the launch specification. Required keys can be found in the `GET ssh-keys` endpoint.


# Overview

The Mithril CLI removes the manual setup typically required to run ML workloads on remote infrastructure. Workloads are defined **declaratively in YAML** — specifying code, compute requirements, and runtime configuration in a single spec. Instead of SSHing into nodes or stitching together launch scripts, researchers submit runs directly from these definitions. The CLI handles packaging, scheduling, and execution **across Mithril and other clouds**, supporting common patterns like model training, offline batch inference, and large-scale evaluation.

#### Defining a basic workload

```yaml
# task.yaml
resources:
  infra: mithril
  accelerators: B200:8

num_nodes: 2

setup: |
  pip install -r requirements.txt

run: |
  MASTER_ADDR=$(echo "$SKYPILOT_NODE_IPS" | head -n1)
  torchrun \
    --nnodes=$SKYPILOT_NUM_NODES \
    --nproc_per_node=$SKYPILOT_NUM_GPUS_PER_NODE \
    --master_addr=$MASTER_ADDR \
    --node_rank=$SKYPILOT_NODE_RANK \
    train.py --distributed
```

#### Running the workload

```bash
ml launch task.yaml
```

#### Provisioning and scheduling

Before execution, the CLI evaluates available capacity and proposes a cluster configuration:

```
> ml launch task.yaml
mithril-client 0.1.0
SkyPilot API server 0.1.0a4
Considered resources (2 nodes):
-------------------------------------------------------------------------------------
 INFRA                     INSTANCE   vCPUs   Mem(GB)   GPUS     COST ($)   CHOSEN
-------------------------------------------------------------------------------------
 Mithril (us-central5-a)   b200.8x    232      192       B200:8   2.25          ✔
-------------------------------------------------------------------------------------
Launching a new cluster 'sky-692d-olivier'. Proceed? [Y/n]:
• Launching... View logs: ml logs --provision sky-69a7-olivier
```

#### Features

* **Attach storage** – Mount persistent volumes or cloud buckets for datasets, checkpoints, and run outputs.
* **Scale from single-node to distributed training** – Provision multi-node GPU clusters with InfiniBand networking automatically configured.
* **Cost protection** – Set maximum price limits to control spend.
* **Idle auto-shutdown** – Instances pause automatically when GPUs are no longer in use.
* **AI-native** – Built with coding agents in mind.
* **Multi-cloud ready** – Launch workloads across Mithril, Nebius, Oracle, GCP, AWS, and 15 other providers.
* **No lock-in** – Workload specs and CLI workflows build on open-source SkyPilot — not proprietary tooling.

#### Built on SkyPilot

The Mithril CLI is built on the open-source [SkyPilot](https://skypilot.co/) framework — adopting its workload definition model, provisioning engine, and multi-cloud integrations.

This means existing SkyPilot workflows run unchanged, and workloads remain portable across all SkyPilot-supported clouds.

Mithril extends this foundation at the capacity layer, integrating auction-based GPU allocation, flexible reservation models, and cost controls directly into the same declarative workflow.


# Installation

#### Install CLI

```bash
# Prereq: install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install the Mithril CLI
uv tool install -U --refresh mithril-client
```

#### First-time setup

```bash
ml setup # interactive onboarding
```

#### Verify setup

```bash
ml setup --check
```

**Non-interactive setup**

You can skip `ml setup` by setting environment variables:

* **API key**: get one at <https://app.mithril.ai/account/api-keys>
* **Project ID**: project `fid` from the projects API:

  ```bash
  curl -H "Authorization: Bearer <API_KEY>" https://api.mithril.ai/v2/projects
  ```

```bash
export MITHRIL_API_KEY=fkey_xxx
export MITHRIL_PROJECT=proj_xxx
```


# Quickstart

Go from local code to running on GPUs in under two minutes.

### Prerequisites

Make sure you've completed [Installation](/mithril-cli/installation) — you'll need a Mithril API key, project and billing configured before continuing.

### 1. Start from your project

Open a terminal in the directory that contains your project code:

```bash
cd /path/to/project
```

### 2. Describe your task in YAML

Create a file called `task.yaml` at the project root. This tells Mithril what hardware you need, how to prepare the environment, and what to run.

{% hint style="info" %}
Tip: Run `ml launch` with no arguments to generate a starter task.yaml and AGENTS.md file that coding agents can use to guide you through the entire workflow.
{% endhint %}

```yaml
# task.yaml

# Sync this directory so your code and data are
# available on the cluster
workdir: .

resources:
  infra: mithril
  accelerators: B200:8
  
# Maximum hourly price you're willing to pay for
# the instance.
# Due to auction-based pricing, you often pay less
# than this cap.
config:
  mithril:
    # Equivalent to $4.00/GPU/hour on an 8x instance.
    limit_price: 32.00

# Runs once when the cluster is first created
# (install deps, download data, etc.)
setup: |
  pip install -r requirements.txt

# Command that executes your code — runs on the
# cluster every time you launch or exec.
run: |
  nvidia-smi
  python train.py
```

> This example shows training, but the same workflow applies to batch inference and evaluation.

That's the entire configuration. `workdir: .` uploads your local files, `setup` runs once to prepare the environment, and `run` specifies the commands that executes your code.

→ [Task YAML](/mithril-cli/task-yaml) — full reference manual.

### 3. Launch

```bash
ml launch task.yaml -c my-cluster
```

This does two things: creates a cluster named `my-cluster` with the GPUs you requested, and submits your task as the first job. Logs will stream directly to your terminal.

### 4. Check cluster status

Once launched, you can check on your cluster at any time:

```bash
ml status
```

### 5. View the job queue and logs

A cluster can run multiple jobs. To see what's queued and stream output:

```bash
ml queue my-cluster        # list all jobs on the cluster
ml logs my-cluster         # stream logs for a job
```

### 6. SSH into the cluster

For interactive debugging or poking around, SSH straight in.&#x20;

```bash
ssh my-cluster
```

### 7. Iterate on your code

Edit your code or `run` commands locally, then push the changes to your existing cluster:

```bash
ml exec my-cluster task.yaml
```

`ml exec` syncs your workdir and executes the run commands without reprovisioning or modifying cluster resources. This creates a tight iteration loop for testing changes.

**When to use which:**

| Scenario                                           | Command                             |
| -------------------------------------------------- | ----------------------------------- |
| Only your code or `run` commands changed           | `ml exec my-cluster task.yaml`      |
| You changed `setup`, `file_mounts`, or `resources` | `ml launch task.yaml -c my-cluster` |

### 8. Tear down when you're done

When you no longer need the cluster:

```bash
ml down my-cluster
```

This terminates your bid, releases compute resources and stops billing. Persistent volumes are not affected — your data remains available.


# Task YAML

Complete reference for SkyPilot-compatible Task YAML.

The Mithril CLI uses the SkyPilot YAML task spec for defining and launching runs.

Because the spec is SkyPilot-compatible, existing SkyPilot tasks run without modification when targeting Mithril infrastructure.

To run on Mithril, specify:

```yaml
resources:
  infra: mithril
```

Mithril extends the spec with a limit price declared in task config that caps what you’ll pay per hour for each instance. Clusters launch only when capacity is available at or below that price, and often run at lower cost.

```yaml
config:
  mithril:
    limit_price: 32.0  # max $/hour/instance
```

If you’ve launched jobs with SkyPilot, the structure below will be familiar.

→ [SkyPilot YAML reference](https://docs.skypilot.co/en/latest/reference/yaml-spec.html)

***

## Spec structure

A task spec packages everything required to run your code on remote GPUs:

* Compute
* Environment setup
* Code sync
* Storage mounts
* Execution commands

Minimal example:

```yaml
resources:
  accelerators: B200:8

run: python train.py
```

## Execution lifecycle

Tasks execute in a fixed order:

```
Provision cluster
→ Sync workdir
→ Run setup (once)
→ Execute run commands
```

Subsequent runs:

* Skip provisioning if the cluster exists
* Skip setup
* Re-sync code
* Re-run commands

This creates a tight iteration loop for testing changes.

***

### Top-level fields

| Field         | Type   | Required | CLI override         | Description                           |
| ------------- | ------ | -------- | -------------------- | ------------------------------------- |
| `name`        | string | No       | `-n, --name`         | Task name (auto-generated if omitted) |
| `resources`   | object | Yes      | See resources        | Compute requirements                  |
| `run`         | string | Yes      | Inline command arg   | Main commands to execute              |
| `setup`       | string | No       | —                    | Setup commands (run once per cluster) |
| `workdir`     | string | No       | `--workdir`          | Local directory to sync               |
| `file_mounts` | object | No       | —                    | Remote storage mounts                 |
| `volumes`     | object | No       | —                    | Mithril volumes to mount              |
| `envs`        | object | No       | `-e KEY=VALUE`       | Environment variables                 |
| `num_nodes`   | int    | No       | `--num-nodes`        | Number of nodes (default: 1)          |
| `config`      | object | No       | `--config KEY=VALUE` | Provider-specific config              |

## Core SkyPilot fields

The following fields come directly from the SkyPilot spec.

### resources

```yaml
resources:
  infra: mithril
  accelerators: B200:8
```

Fields

| Field          | Type   | CLI override | Description                                  |
| -------------- | ------ | ------------ | -------------------------------------------- |
| `infra`        | string | `--infra`    | Infrastructure (`mithril`, `mithril/region`) |
| `accelerators` | string | `--gpus`     | GPU type:count (e.g., `B200:8`)              |

→ [Infra](/mithril-cli/task-yaml/infra) — multi-cloud support, spot bids, reservations, and hosted Kubernetes

### run

Main task commands. Runs every time the task is launched.

```yaml
run: python train.py
```

Multi-line:

```yaml
run: |
  cd /app
  python train.py --epochs 100
  python eval.py
```

### setup

One-time setup commands. Runs once when cluster is provisioned.

```yaml
setup: |
  pip install -r requirements.txt
  apt-get update && apt-get install -y vim
```

### workdir

Sync local directory to cluster.

```yaml
workdir: .
```

Files are synced to `~/sky_workdir/` on the cluster.

### file\_mounts

Mount remote storage (S3, GCS, etc.).

```yaml
file_mounts:
  /data: s3://my-bucket/data
  /models: gs://my-bucket/models
```

→ [File Mounts](https://docs.skypilot.co/en/latest/examples/syncing-code-artifacts.html#uploading-files-outside-of-workdir) for details.

### volumes

Mount Mithril persistent disks

```yaml
volumes:
  /data: my-volume-name
```

### envs

Environment variables available in setup and run.

```yaml
envs:
  WANDB_API_KEY: xxx
  BATCH_SIZE: 32
  DEBUG: "true"
```

### num\_nodes

Multi-node distributed training.

```yaml
num_nodes: 2
```

SkyPilot sets up distributed environment variables automatically.

### config

Provider-specific configuration.

```yaml
config:
  mithril:
    limit_price: 8.0  # max $/hour/instance you'll pay
```

**Default**: $32.00/hour/instance if not specified.

→ [Spot auction mechanics](/compute-and-storage/spot-bids/spot-auction-mechanics) — how the spot auction, pricing, and preemption work

### Complete example

```yaml
name: llm-training

resources:
  infra: mithril
  accelerators: B200:8

config:
  mithril:
    limit_price: 32.0

num_nodes: 4

workdir: .

file_mounts:
  /data: s3://my-bucket/training-data

volumes:
  /checkpoints: my-checkpoints-volume

envs:
  WANDB_PROJECT: my-project
  WANDB_API_KEY: ${WANDB_API_KEY}

setup: |
  pip install -r requirements.txt
  wandb login

run: |
  torchrun \
    --nproc_per_node=8 \
    --nnodes=$SKYPILOT_NUM_NODES \
    train.py \
    --data /data \
    --output /checkpoints
```


# Infra

The `infra` field in your task YAML controls where your code runs — which cloud, which region, and how compute is allocated.

```yaml
resources:
  infra: mithril                 # Mithril (default)
  # infra: mithril/us-central5-a # Mithril in a specific region
  # infra: aws                   # AWS
  # infra: gcp/us-central1       # GCP in a specific region
  # infra: k8s/<context-name>    # Kubernetes cluster
```

**CLI override**: `--infra`

```bash
ml launch task.yaml --infra mithril/us-central5-a
```

### Format

```
cloud[/region[/zone]]
```

| Example                    | Meaning                        |
| -------------------------- | ------------------------------ |
| `mithril`                  | Mithril Cloud, any region      |
| `mithril/us-central5-a`    | Mithril Cloud, specific region |
| `aws`                      | AWS, any region                |
| `aws/us-east-1`            | AWS, specific region           |
| `aws/us-east-1/us-east-1a` | AWS, specific region and zone  |
| `kubernetes`               | Default Kubernetes context     |

If omitted, `infra` defaults to `mithril`.

### Mithril

When `infra: mithril`, your cluster is provisioned on Mithril's GPU cloud through the [spot auction](https://docs.mithril.ai/compute-and-storage/spot-bids). You pay the current spot price (up to your limit price) and your instances may be preempted if the spot price rises above it.

```yaml
resources:
  infra: mithril
  accelerators: B200:8

config:
  mithril:
    limit_price: 32.0  # max $/hour/instance
```

→ [Limit Price](/compute-and-storage/spot-bids/spot-auction-mechanics) — how the spot auction, pricing, and preemption work

#### Spot bids

All Mithril compute via `ml launch` is allocated through a blind second-price auction from Mithril's spot capacity. You set a limit price, and you pay the current spot price (not your limit). Instances can be preempted when the spot price exceeds your limit.

→ [Spot bids](/compute-and-storage/spot-bids) — full details on the spot auction, preemption, and pricing mechanics

#### Reservations

Reservations provide guaranteed capacity at a fixed price for a defined time window — no preemption risk. Reservations are created and managed through the [Mithril console](https://app.mithril.ai/).

Today, you can use reserved instances with `ml launch` by attaching them to a hosted Kubernetes cluster and targeting it with `infra: kubernetes` — see Hosted Kubernetes below.

#### Hosted Kubernetes

Mithril provides hosted Kubernetes clusters with a long-lived control plane. You can run `ml launch` tasks on a Mithril K8s cluster by setting `infra: kubernetes`.

**Prerequisites**

Install the required tools:

```bash
brew install kubectl socat netcat
```

**Setup**

1. **Create a K8s cluster** in the [Mithril console](https://app.mithril.ai/clusters)
2. **Create a spot bid or reservation** in the Mithril console and select your K8s cluster — instances will automatically join the cluster as nodes on startup
3. **Fetch credentials** to your local machine:

```bash
ml k8s update-kubeconfig MY_CLUSTER
```

4. **Launch on Kubernetes**:

```yaml
# task.yaml
resources:
  infra: kubernetes
  accelerators: B200:8

run: python train.py
```

```bash
ml launch task.yaml -c my-cluster
```

Mithril handles node lifecycle automatically — preempted instances are drained with a 5-minute grace period, reallocated instances are uncordoned, and terminated instances are removed from the cluster.

→ [Hosted Kubernetes (Mithril docs)](https://docs.mithril.ai/compute-and-storage/hosted-kubernetes-clusters) — cluster setup, persistent storage, and FAQ → [SkyPilot on Kubernetes](https://docs.skypilot.co/en/latest/reference/kubernetes/index.html) — pod scheduling, multi-cluster, and troubleshooting

### Multi-cloud

Mithril CLI through SkyPilot supports 20+ clouds. If you have credentials configured for other providers, you can target them with `infra`:

| Cloud      | `infra` value |
| ---------- | ------------- |
| Mithril    | `mithril`     |
| AWS        | `aws`         |
| GCP        | `gcp`         |
| Azure      | `azure`       |
| Kubernetes | `kubernetes`  |
| Nebius     | `nebius`      |
| OCI        | `oci`         |

Check which clouds you have credentials for:

```bash
ml sky check
```

→ [SkyPilot Kubernetes docs](https://docs.skypilot.co/en/latest/reference/kubernetes/index.html) — using SkyPilot on Kubernetes clusters


# Data & storage

Three ways to get data onto your cluster and persist results.

| Mechanism          | YAML field    | What it does                       | Lifecycle                     |
| ------------------ | ------------- | ---------------------------------- | ----------------------------- |
| Cloud buckets      | `file_mounts` | Sync data to a path on the cluster | Data lives in your bucket     |
| Persistent volumes | `volumes`     | Mount Mithril network storage      | Survives instance termination |
| Ephemeral volumes  | `volumes`     | Fast local scratch space           | Deleted with cluster          |

Your local code is handled separately by `workdir` — see Syncing your code.

### Cloud buckets

Use `file_mounts` to make data available at a path on the cluster.

```yaml
file_mounts:
  /data: s3://my-bucket/training-data
  /models: gs://my-bucket/pretrained
```

#### Local files

You can also mount local files and directories. They are uploaded to a temporary cloud bucket behind the scenes and synced to the cluster:

```yaml
file_mounts:
  /remote/path: /local/path/to/data
  /remote/config.yaml: ./config.yaml
```

#### Supported sources

| Source                     | Example                               |
| -------------------------- | ------------------------------------- |
| AWS S3                     | `s3://my-bucket/path`                 |
| Google Cloud Storage (GCS) | `gs://my-bucket/path`                 |
| Cloudflare R2              | `r2://my-bucket`                      |
| CoreWeave Object Storage   | `cw://my-bucket`                      |
| OCI Object Storage         | `oci://my-bucket@region`              |
| Local directory            | `/absolute/path` or `./relative/path` |
| Local file                 | `./config.yaml`                       |

For latest list of supported providers → [Cloud Buckets (SkyPilot docs)](https://docs.skypilot.co/en/latest/reference/storage.html)&#x20;

#### Storage modes

Cloud buckets support three access modes:

| Mode              | Reads                     | Writes                                                       | Best for                           |
| ----------------- | ------------------------- | ------------------------------------------------------------ | ---------------------------------- |
| `MOUNT` (default) | Streamed from bucket      | Replicated to bucket and visible to other VMs                | Shared datasets, multi-node access |
| `COPY`            | Pre-fetched to local disk | Local only, not synced back                                  | Fast I/O on data that fits on disk |
| `MOUNT_CACHED`    | Cached locally on access  | Cached locally, uploaded in background before task completes | Checkpoints and large writes       |

```yaml
file_mounts:
  /data:
    source: s3://my-bucket/dataset
    mode: COPY # MOUNT, COPY, or MOUNT_CACHED
```

→ [Cloud Buckets (SkyPilot docs)](https://docs.skypilot.co/en/latest/reference/storage.html) — advanced storage options, bucket creation, CLI management, and YAML reference

### Persistent volumes

Use `volumes` to mount Mithril network storage that survives instance termination, preemption, and restarts. Ideal for training checkpoints and datasets you reuse across runs.

#### Create a volume

```bash
ml sky volumes apply \
  --name my-data \
  --infra mithril/us-central5-a \
  --type mithril-file-share \
  --size 100GB
```

#### Use in task YAML

```yaml
resources:
  infra: mithril/us-central5-a  # must match volume region

volumes:
  /data: my-data
  /checkpoints: my-checkpoints
```

#### Volume interfaces

| Interface  | `--type`             | Use case                                |
| ---------- | -------------------- | --------------------------------------- |
| File (NFS) | `mithril-file-share` | Shared access across multiple instances |
| Block      | `mithril-block`      | Single instance, high throughput        |

> Not all regions support both interfaces. Check the Mithril console for availability.

#### Manage volumes

```bash
ml sky volumes ls               # list volumes
ml sky volumes delete my-volume # delete a volume
```

#### Region matching

Volume and cluster must be in the same region:

```yaml
resources:
  infra: mithril/us-central5-a # ← must match

volumes:
  /data: my-volume # ← created in us-central5-a
```

### Ephemeral storage

Every Mithril instance comes with NVMe SSD ephemeral storage at no extra cost, automatically mounted at `/mnt/local`. No YAML configuration needed — it's available on every instance by default.

| Event            | Ephemeral storage                  |
| ---------------- | ---------------------------------- |
| VM restart       | Retained                           |
| Preemption       | Wiped (re-mounted on reallocation) |
| Termination      | Wiped                              |
| Host maintenance | Wiped                              |

Use `/mnt/local` for scratch work, caches, and shuffle buffers. Don't store anything you need to keep — use persistent volumes or object storage (via cloud buckets) for that.

→ [Ephemeral Storage](https://docs.mithril.ai/compute-and-storage/ephemeral-storage) — instance storage specs and detailed behavior

### Syncing your code

`workdir` syncs a local directory to `~/sky_workdir/` on the cluster:

```yaml
workdir: .
```

Your `run` commands execute from `~/sky_workdir/`, so relative paths work as expected. The workdir is re-synced on every `ml launch` and `ml exec`.

### Choosing the right mechanism

| Scenario                                                             | Use                                      |
| -------------------------------------------------------------------- | ---------------------------------------- |
| Training data                                                        | `file_mounts` with bucket URL            |
| Checkpoints you need across runs                                     | `volumes` (persistent)                   |
| Scratch space for shuffling/caching                                  | `/mnt/local` Node-local NVMe (ephemeral) |
| Your code and configs                                                | `workdir`                                |
| Workload output (final weights, LoRA adapters, logs, eval artifacts) | Object storage                           |

### Complete example

```yaml
name: training-run

resources:
  infra: mithril/us-central5-a
  accelerators: B200:8

workdir: .

file_mounts:
  /datasets: s3://my-bucket/imagenet

volumes:
  /checkpoints: my-checkpoints-volume

run: |
  python train.py \
    --data /datasets \
    --scratch /scratch \
    --output /checkpoints
```


# Detect idle instances

Automatically pause your bid when your instances become idle to prevent unnecessary spend.

[Pausing your spot bid](https://docs.mithril.ai/compute-and-storage/spot-bids#pausing-and-resuming-spot-bids) releases the instances and stops billing but keeps the cluster configuration and boot disk so it can resume later.

#### For a new cluster

Add `autostop` to your task YAML:

```yaml
resources:
  # Pause bid after 10 minutes of inactivity.
  autostop: 10m
```

#### For an existing cluster

Enable autostop:

```bash
ml sky autostop my-cluster -i 10
```

Disable autostop:

```bash
ml sky autostop my-cluster --cancel
```

#### What counts as idle?

A cluster is considered **idle** when:

* No jobs are **pending or running** (check `ml queue`)
* No **active SSH sessions** exist

Once the cluster remains idle for the configured duration, a daemon inside the VM automatically pauses the bid.

### Advanced configuration

#### **Customize idleness criteria**

You can change what counts as "activity" using `wait_for`.

```yaml
resources:
  autostop:
    idle_minutes: 10
    wait_for: jobs_and_ssh
```

| Option                   | Behavior                                                                       |
| ------------------------ | ------------------------------------------------------------------------------ |
| `jobs_and_ssh` (default) | Wait for jobs in pending/running state and SSH sessions to finish              |
| `jobs`                   | Ignore SSH sessions (useful if you keep long-running IDE/SSH connections open) |
| `none`                   | The bid will pause after the configured time regardless of cluster activity.   |

The `none` option is useful for enforcing a **hard time limit**, even if workloads like Jupyter notebooks are still running

#### Run commands before autostop

You can specify commands to run before your bid is paused.

```
resources:
  autostop:
    idle_minutes: 10
    hook: |
      cd /path/to/project
      git add .
      git commit -m "Commit my code"
      git push
    hook_timeout: 300
```

The hook runs **on the cluster** and has access to its filesystem and environment variables.

If the hook exits with a non-zero status, autostop will still proceed, but a warning will be logged.

#### **Hook timeout**

By default, autostop hooks have a 1 hour timeout.

If the hook exceeds this limit, it will be terminated and autostop will continue.

Note that **your bid will not be paused until the hook finishes or times out**, so choose an appropriate `hook_timeout`.

<sub>The autostop functionality is inherited from the SkyPilot</sub>\ <sub>project. This page is largely adapted from the</sub> [<sub>SkyPilot autostop documentation</sub>](https://docs.skypilot.co/en/latest/reference/auto-stop.html)<sub>.</sub>


# Tutorials


# Axolotl

#### Setup

This example is based on <https://github.com/axolotl-ai-cloud/axolotl/tree/main/examples/mistral>.

```bash
git clone git@github.com:axolotl-ai-cloud/axolotl.git
cd axolotl/examples
```

#### Define workload

```yaml
resources:
  accelerators: B200:8
  infra: mithril

workdir: mistral

setup: |
  docker pull winglian/axolotl:main-py3.10-cu118-2.0.1

run: |
  docker run --gpus all \
    -v ~/sky_workdir:/sky_workdir \
    -v /root/.cache:/root/.cache \
    winglian/axolotl:main-py3.10-cu118-2.0.1 \
    huggingface-cli login --token ${HF_TOKEN} 

  docker run --gpus all \
    -v ~/sky_workdir:/sky_workdir \
    -v /root/.cache:/root/.cache \
    winglian/axolotl:main-py3.10-cu118-2.0.1 \
    accelerate launch -m axolotl.cli.train /sky_workdir/qlora.yaml

envs:
  HF_TOKEN: null # Pass with `--secret HF_TOKEN` in CLI
  
```

#### Run workload

{% code overflow="wrap" %}

```bash
HF_TOKEN=xxx ml launch -c axolotl axolotl.yaml --secret HF_TOKEN -y -i30 --down
```

{% endcode %}

* `--cluster axolotl` — Name the cluster axolotl. If a cluster with this name already exists, it will be reused; otherwise a new one is created.
* `--secret HF_TOKEN` Pass HF\_TOKEN as a secret environment variable to the remote cluster. Since no =value is provided, it reads the value from your local environment ($HF\_TOKEN). Secrets behave like --env but are redacted in logs and YAML outputs for security.
* `-i30` or `--idle-minutes-to-autostop 30` — Automatically stop the cluster after 30 minutes of idleness (no running or pending jobs in the cluster's job queue).
* `--down` Autodown — Instead of just stopping the cluster when the autostop timer fires, tear it down entirely (delete the cloud resources). Combined with -i30, this means: after all jobs finish and the cluster has been idle for 30 minutes, destroy the cluster completely.


# CLI reference


# Workloads

The Mithril CLI manages clusters and jobs through [SkyPilot](https://skypilot.co/), an open-source framework for running ML workloads. The commands below — launch, exec, status, logs, queue, start, stop, and down — provide the core workflow: provision GPUs, run tasks, monitor progress, and clean up when you're done.\
For options not covered here, run ml --help for the full option set, or use ml sky for direct access to SkyPilot's CLI.

### Quick reference

| Command       | Purpose                                                         |
| ------------- | --------------------------------------------------------------- |
| **ml launch** | Create cluster and run a task (or start interactive setup).     |
| **ml exec**   | Run a task or command on an existing cluster (or open a shell). |
| **ml status** | List clusters and jobs; optionally show IP or endpoints.        |
| **ml logs**   | Stream or download job logs; stream provision/autostop logs.    |
| **ml queue**  | Show job queue for cluster(s).                                  |
| **ml start**  | Start stopped (or failed) cluster(s).                           |
| **ml stop**   | Stop cluster(s); keep disks for later **ml start**.             |
| **ml down**   | Tear down cluster(s) and delete resources.                      |

For full option lists, run **`ml <command> --help`**.

***

### ml launch

Provision a cluster and run a task. With no arguments, runs an interactive setup. With a task YAML or inline command, launches the cluster and (unless `--detach-run`) streams job logs.

When invoked with no arguments, ml launch starts an interactive onboarding flow:

1. Creates a starter task YAML (task.yaml) with annotated fields for resources, setup, and run.
2. Optionally adds an AGENTS.md to your project so coding agents (Claude, Cursor, etc.) can discover the Mithril CLI docs bundled with the package.
3. Prints a ready-to-use launch command and, if AGENTS.md was written, a prompt for an agent-guided walkthrough.

**Synopsis**

```
ml launch [ENTRYPOINT] [OPTIONS]
```

**Arguments**

| Argument     | Description                                                                                                         |
| ------------ | ------------------------------------------------------------------------------------------------------------------- |
| `ENTRYPOINT` | Optional. Path to a task YAML (`.yaml`/`.yml`) or a single bash command in quotes. Omit to start interactive setup. |

**Options**

| Option                               | Description                                                           |
| ------------------------------------ | --------------------------------------------------------------------- |
| `-c`, `--cluster NAME`               | Cluster name. If the cluster exists, reuses it; otherwise creates it. |
| `--gpus SPEC`                        | GPU type and count (e.g. `A100:4`, `H100:8`).                         |
| `--cpus SPEC`                        | vCPU requirement (e.g. `4`, `4+`).                                    |
| `--memory SPEC`                      | Memory in GB.                                                         |
| `--cloud CLOUD`                      | Cloud provider.                                                       |
| `--region REGION`                    | Region.                                                               |
| `--num-nodes N`                      | Number of nodes.                                                      |
| `-i`, `--idle-minutes-to-autostop N` | Auto-stop cluster after N minutes of idleness.                        |
| `--down`                             | Tear down the cluster after the job finishes.                         |
| `-d`, `--detach-run`                 | Do not stream job logs; return after the job is submitted.            |
| `-r`, `--retry-until-up`             | Retry provisioning until the cluster is up.                           |
| `-y`, `--yes`                        | Skip confirmation prompts.                                            |
| `--dryrun`                           | Print cluster name, task, and resources only; do not launch.          |
| `-n`, `--name NAME`                  | Task name.                                                            |
| `--workdir DIR`                      | Local directory to sync as the task workdir.                          |
| `-e`, `--env KEY=VALUE`              | Set environment variables (repeatable).                               |

**Examples**

```bash
ml launch task.yaml -c mycluster
ml launch --gpus B200:8 -c dev
```

***

### ml exec

Run a task or command on an **existing** cluster without re-provisioning. Use a task YAML or a bash command. For interactive use, open a shell with **`ml exec CLUSTER`** or use **`ml ssh CLUSTER`**.

**Synopsis**

```
ml exec CLUSTER [ENTRYPOINT ...] [OPTIONS]
```

**Arguments**

| Argument     | Description                                                                                   |
| ------------ | --------------------------------------------------------------------------------------------- |
| `CLUSTER`    | Cluster name.                                                                                 |
| `ENTRYPOINT` | Optional. Task YAML path or bash command. Omit to open an interactive shell on the head node. |

**Options**

| Option               | Description                                    |
| -------------------- | ---------------------------------------------- |
| `-d`, `--detach-run` | Submit the job and return; do not stream logs. |

Additional task and resource options (e.g. `--workdir`, `--gpus`, `--env`) are supported; run **`ml exec --help`** for the full list.

**Examples**

```bash
ml exec my-cluster task.yaml
ml exec my-cluster python train.py
```

***

### ml status

List clusters and job information. Updates local SSH config so you can **`ssh CLUSTER`** or use **`ml exec`**. With one cluster, **`--ip`** or **`--endpoints`** can be used to get connection details.

**Synopsis**

```
ml status [CLUSTER ...] [OPTIONS]
```

**Arguments**

| Argument  | Description                                                 |
| --------- | ----------------------------------------------------------- |
| `CLUSTER` | Optional. One or more cluster names. Default: all clusters. |

**Options**

| Option                                           | Description                                                                                     |
| ------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
| `-v`, `--verbose`                                | Show all fields.                                                                                |
| `-r`, `--refresh`                                | Query latest status from the cloud (use when clusters change outside Mithril or with autostop). |
| `--ip`                                           | Show head node IP (only with exactly one cluster).                                              |
| `--endpoints`                                    | Show all exposed endpoints (only with exactly one cluster).                                     |
| `--endpoint PORT`                                | Show URL for the given port (only with exactly one cluster).                                    |
| `--show-managed-jobs` / `--no-show-managed-jobs` | Include in-progress managed jobs (default: show).                                               |
| `--show-services` / `--no-show-services`         | Include Sky Serve services (default: show).                                                     |
| `--show-pools` / `--no-show-pools`               | Include pools (default: show).                                                                  |
| `--all-users`                                    | Include clusters for all users.                                                                 |

**Cluster states**

| State       | Description                                                             |
| ----------- | ----------------------------------------------------------------------- |
| **UP**      | Ready; provisioning and setup completed.                                |
| **STOPPED** | Stopped; use **`ml start`** to restart.                                 |
| **INIT**    | Provisioning or setup in progress, or cluster in an inconsistent state. |

**Examples**

```bash
ml status
ml status my-cluster
ml status --refresh
ml status my-cluster --ip
```

***

### ml logs

Stream or download job logs, or stream provisioning/autostop logs.

**Synopsis**

```
ml logs CLUSTER [JOB_ID ...] [OPTIONS]
```

**Arguments**

| Argument  | Description                                                                                                                |
| --------- | -------------------------------------------------------------------------------------------------------------------------- |
| `CLUSTER` | Cluster name.                                                                                                              |
| `JOB_ID`  | Optional. Job ID(s). If omitted, uses the latest job. For streaming, at most one job; for `--sync-down`, multiple allowed. |

**Options**

| Option                     | Description                                                                                                                 |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `--provision`              | Stream cluster provisioning logs (provision.log).                                                                           |
| `--autostop`               | Stream autostop hook logs.                                                                                                  |
| `-w`, `--worker ID`        | Worker ID for logs (only with `--provision`).                                                                               |
| `-s`, `--sync-down`        | Download job logs to `~/sky_logs` (multiple job IDs allowed).                                                               |
| `--status`                 | Do not show logs; exit with status code: 0 = succeeded, 100 = failed, 101 = not finished, 102 = not found, 103 = cancelled. |
| `--follow` / `--no-follow` | Stream logs continuously (default: follow).                                                                                 |
| `--tail N`                 | Show only the last N lines (0 = all).                                                                                       |

**Examples**

```bash
ml logs my-cluster 1
ml logs my-cluster --provision
ml logs my-cluster --status
ml logs my-cluster -s 1 2 3
```

***

### ml queue

Show the job queue for one or more clusters (pending and running jobs; optionally finished).

**Synopsis**

```
ml queue [CLUSTER ...] [OPTIONS]
```

**Arguments**

| Argument  | Description                                       |
| --------- | ------------------------------------------------- |
| `CLUSTER` | Optional. Cluster name(s). Default: all clusters. |

**Options**

| Option                  | Description                         |
| ----------------------- | ----------------------------------- |
| `-s`, `--skip-finished` | Show only pending and running jobs. |
| `--all-users`           | Show queue for all users.           |

**Examples**

```bash
ml queue
ml queue my-cluster
ml queue my-cluster --skip-finished
```

***

### ml start

Start one or more stopped clusters (or retry provisioning/setup for clusters in INIT). No effect if a cluster is already UP.

**Synopsis**

```
ml start [CLUSTER ...] [OPTIONS]
```

**Arguments**

| Argument  | Description                                                                                  |
| --------- | -------------------------------------------------------------------------------------------- |
| `CLUSTER` | Optional. Cluster name(s). Default: all clusters (or the single cluster if only one exists). |

**Options**

| Option                               | Description                                                                     |
| ------------------------------------ | ------------------------------------------------------------------------------- |
| `-a`, `--all`                        | Start all clusters.                                                             |
| `-y`, `--yes`                        | Skip confirmation.                                                              |
| `-i`, `--idle-minutes-to-autostop N` | Set autostop after N minutes of idleness.                                       |
| `--down`                             | Use autodown (tear down after idleness); requires `--idle-minutes-to-autostop`. |
| `-r`, `--retry-until-up`             | Retry until the cluster is up on availability failures.                         |
| `-f`, `--force`                      | Start even if already UP (e.g. to upgrade SkyPilot runtime).                    |

**Examples**

```bash
ml start my-cluster
ml start cluster1 cluster2
ml start -a
```

***

### ml stop

Stop one or more clusters. Billing for instances stops; attached disks are kept and reattached when you **`ml start`**. Spot clusters cannot be stopped.

**Synopsis**

```
ml stop [CLUSTER ...] [OPTIONS]
```

**Arguments**

| Argument  | Description                                          |
| --------- | ---------------------------------------------------- |
| `CLUSTER` | Optional. Cluster name(s) or glob (e.g. `cluster*`). |

**Options**

| Option                 | Description                                                              |
| ---------------------- | ------------------------------------------------------------------------ |
| `-a`, `--all`          | Stop all clusters.                                                       |
| `--all-users`          | Stop all clusters for all users.                                         |
| `-y`, `--yes`          | Skip confirmation.                                                       |
| `--graceful`           | Wait for MOUNT\_CACHED uploads to complete (cancels current jobs first). |
| `--graceful-timeout N` | Timeout in seconds for `--graceful`.                                     |

**Examples**

```bash
ml stop my-cluster
ml stop cluster1 cluster2
ml stop "cluster*"
ml stop -a
```

***

### ml down

Tear down one or more clusters. All associated resources are deleted and billing stops; data on attached disks is lost.

**Synopsis**

```
ml down [CLUSTER ...] [OPTIONS]
```

**Arguments**

| Argument  | Description                                          |
| --------- | ---------------------------------------------------- |
| `CLUSTER` | Optional. Cluster name(s) or glob (e.g. `cluster*`). |

**Options**

| Option                 | Description                                                                                                                                                            |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-a`, `--all`          | Tear down all clusters.                                                                                                                                                |
| `--all-users`          | Tear down all clusters for all users.                                                                                                                                  |
| `-y`, `--yes`          | Skip confirmation.                                                                                                                                                     |
| `-p`, `--purge`        | (Advanced) Remove cluster(s) from SkyPilot’s table even if cloud teardown failed. Use only when troubleshooting; you are responsible for cleaning up leaked resources. |
| `--graceful`           | Wait for MOUNT\_CACHED uploads before terminating (cancels current jobs first).                                                                                        |
| `--graceful-timeout N` | Timeout in seconds for `--graceful`.                                                                                                                                   |

**Examples**

```bash
ml down my-cluster
ml down cluster1 cluster2
ml down "cluster*"
ml down -a
```


# Infrastructure

{% hint style="info" %}
Most users should start with `ml launch`. It provisions a GPU cluster, runs your task, and handles the full lifecycle — no manual VM management needed. The workload commands (launch, exec, status, stop, down) are the fastest path from code to running on GPUs.
{% endhint %}

Infrastructure commands give you a lower-level interface to the Mithril spot marketplace. Instead of defining a task and letting SkyPilot manage the cluster, you manage instances and Kubernetes clusters directly. Use them when you need to:

* Build and manage Kubernetes node pools with GPU workers
* Maintain persistent VMs with your own orchestration, outside of SkyPilot's task-oriented model

### Quick reference

| Command                        | Purpose                                        |
| ------------------------------ | ---------------------------------------------- |
| **`ml instance create`**       | Submit a spot bid for GPU instances.           |
| **`ml instance list`**         | List instances and bids (active by default).   |
| **`ml instance info`**         | Show details for an instance.                  |
| **`ml instance delete`**       | Cancel a bid and terminate its instances.      |
| **`ml instance list-types`**   | Show available GPU instance types and specs.   |
| **`ml k8s list`**              | List Kubernetes clusters.                      |
| **`ml k8s info`**              | Show details for a Kubernetes cluster.         |
| **`ml k8s ssh`**               | SSH into a cluster's control node.             |
| **`ml k8s update-kubeconfig`** | Fetch credentials and update local kubeconfig. |
| **`ml ssh`**                   | SSH into a Mithril instance by bid name.       |

For full option lists, run `ml <command> --help`.

***

### ml instance create

Submit a spot bid for one or more GPU instances.

```
ml instance create [OPTIONS]
```

All instances are allocated through a blind second-price auction. You set a limit price (`-m`) — the maximum you are willing to pay per hour per instance. The actual price you pay is determined by market demand, not your bid. If demand rises above your limit, the instance is preempted and the bid returns to the marketplace.

#### Options

| Flag                               | Description                                                                            |
| ---------------------------------- | -------------------------------------------------------------------------------------- |
| `-i`, `--instance-type TYPE`       | **Required.** GPU instance type (e.g. `b200`, `8xa100`). See `ml instance list-types`. |
| `-r`, `--region REGION`            | **Required.** Region (e.g. `us-central5-a`).                                           |
| `-m`, `--max-price-per-hour PRICE` | **Required.** Maximum hourly price in USD. Accepts `8.0` or `$8.0`.                    |
| `-n`, `--name NAME`                | Bid name. Auto-generated if omitted.                                                   |
| `-N`, `--num-instances N`          | Number of instances in the bid. Default: 1.                                            |
| `-p`, `--project PROJECT`          | Project name. Skips interactive project selection.                                     |
| `--k8s CLUSTER`                    | Attach instances to a Kubernetes cluster as worker nodes.                              |
| `--wait`                           | Block until all instances reach the running state.                                     |
| `-w`, `--watch`                    | Watch instance progress interactively.                                                 |
| `-d`, `--dry-run`                  | Validate the configuration without submitting the bid.                                 |
| `--json`                           | Output JSON.                                                                           |

#### Examples

```bash
ml instance create -i b200 -r us-central5-a -m 32.0
ml instance create -i 8xa100 -r us-east1 -m 25.0 -n training -N 4
ml instance create -i b200 -r us-central5-a -m 32.0 --k8s my-cluster
ml instance create -i b200 -r us-central5-a -m 32.0 -d   # dry run
```

***

### ml instance list

List instances and spot bids.

```
ml instance list [OPTIONS]
```

By default, shows only active bids (pending through running). Use `--all` to include terminal states.

#### Options

| Flag                  | Description                                           |
| --------------------- | ----------------------------------------------------- |
| `--all`               | Include completed, failed, and cancelled bids.        |
| `-s`, `--state STATE` | Filter to a single state (e.g. `running`, `pending`). |
| `--limit N`           | Maximum number of results.                            |
| `--json`              | Output JSON.                                          |

#### Examples

```bash
ml instance list                    # active bids
ml instance list --all              # all bids
ml instance list --state running    # only running
ml instance list --json             # for scripting
```

***

### ml instance info

Show detailed information about an instance or bid.

```
ml instance info [BID_NAME] [OPTIONS]
```

`BID_NAME` is the bid name or FID. Interactive if omitted.

Output includes status, instance type, region, current and maximum price, creation time, IP addresses (when running), SSH destination, and attached Kubernetes cluster (if any).

#### Options

| Flag     | Description  |
| -------- | ------------ |
| `--json` | Output JSON. |

#### Examples

```bash
ml instance info my-instance
ml instance info my-instance --json
ml instance info # interactive picker
```

***

### ml instance delete

Cancel a bid and terminate its instances.

```
ml instance delete [BID_NAME] [OPTIONS]
```

`BID_NAME` is the bid name or FID. Interactive if omitted. Running instances are terminated immediately; pending bids are cancelled. This cannot be undone.

#### Options

| Flag                           | Description                                             |
| ------------------------------ | ------------------------------------------------------- |
| `-y`, `--yes`                  | Skip the confirmation prompt.                           |
| `--all`                        | Cancel all active bids.                                 |
| `-n`, `--name-pattern PATTERN` | Cancel bids matching a wildcard pattern (e.g. `dev-*`). |

#### Examples

```bash
ml instance delete my-instance
ml instance delete my-instance -y         # skip confirmation
ml instance delete --all                  # cancel everything
ml instance delete -n 'training-*'        # pattern match
```

***

### ml instance list-types

Show available GPU instance types and their specifications.

```
ml instance list-types [OPTIONS]
```

#### Options

| Flag                    | Description                        |
| ----------------------- | ---------------------------------- |
| `-r`, `--region REGION` | Filter to a specific region.       |
| `-v`, `--verbose`       | Include memory and detailed specs. |
| `--json`                | Output JSON.                       |

#### Examples

```bash
ml instance list-types                        # all types
ml instance list-types -r us-central5-a       # filter by region
ml instance list-types -v                     # with specs
```

***

### Instance states

Bids and instances have separate state models. `ml instance list` shows **bid status**; `ml instance info` shows both bid and instance-level detail.

#### Bid states

| State        | Meaning                                                                        |
| ------------ | ------------------------------------------------------------------------------ |
| `Open`       | Bid is active in the marketplace, waiting for or seeking allocation.           |
| `Allocated`  | Resources reserved; instances are provisioning or running.                     |
| `Preempting` | Instances are being preempted. The bid will return to `Open` for reallocation. |
| `Paused`     | Bid is temporarily paused.                                                     |
| `Terminated` | Bid is finished (cancelled by user or completed). Terminal state.              |

All states except `Terminated` are considered active and appear in `ml instance list` by default. Use `--all` to include terminated bids.

#### Instance states

Each instance within a bid progresses through its own lifecycle:

| State          | Meaning                                |
| -------------- | -------------------------------------- |
| `New`          | Instance record created.               |
| `Confirmed`    | Allocation confirmed.                  |
| `Scheduled`    | Scheduled for provisioning.            |
| `Initializing` | VM being initialized.                  |
| `Starting`     | VM booting.                            |
| `Running`      | Instance is up and accessible via SSH. |
| `Relocating`   | Being moved to a different host.       |
| `Preempting`   | Being preempted.                       |
| `Preempted`    | Preemption complete.                   |
| `Paused`       | Temporarily paused.                    |
| `Terminated`   | Permanently terminated.                |
| `Error`        | An error occurred.                     |

Instances in active states (New through Running) appear in ml instance list by default. Instances in terminal states (Terminated, Error) are hidden unless --all is passed.

#### Checking state

```bash
ml instance list                    # bid-level status
ml instance list --state running    # filter by state
ml instance info my-instance        # full detail including instance states
```

***

### ml k8s list

List Kubernetes clusters.

```
ml k8s list [OPTIONS]
```

By default, shows active clusters only.

#### Options

| Flag     | Description                  |
| -------- | ---------------------------- |
| `--all`  | Include terminated clusters. |
| `--json` | Output JSON.                 |

#### Examples

```bash
ml k8s list
ml k8s list --all
ml k8s list --json
```

***

### ml k8s info

Show detailed information about a Kubernetes cluster.

```
ml k8s info [CLUSTER] [OPTIONS]
```

`CLUSTER` is the cluster name or FID. Interactive if omitted.

Output includes cluster status, region, Kubernetes version, control-plane endpoint, node count, and attached instances.

#### Options

| Flag     | Description  |
| -------- | ------------ |
| `--json` | Output JSON. |

#### Examples

```bash
ml k8s info my-cluster
ml k8s info my-cluster --json
ml k8s info                     # interactive picker
```

***

### ml k8s ssh

SSH into the control node of a Kubernetes cluster.

```
ml k8s ssh [CLUSTER] [COMMAND ...] [OPTIONS]
```

`CLUSTER` is the cluster name or FID. Interactive if omitted. Without a command, opens an interactive shell. With a trailing command, executes it on the control node and returns.

#### Options

| Flag                    | Description                                    |
| ----------------------- | ---------------------------------------------- |
| `--show`                | Print the SSH command instead of executing it. |
| `-i`, `--identity PATH` | SSH identity file. Auto-detected if omitted.   |

#### Examples

```bash
ml k8s ssh my-cluster                           # interactive shell
ml k8s ssh my-cluster kubectl get nodes         # remote command
ml k8s ssh my-cluster --show                    # print ssh command
```

***

### ml k8s update-kubeconfig

Fetch cluster credentials and merge them into local kubeconfig.

```
ml k8s update-kubeconfig [CLUSTER] [OPTIONS]
```

`CLUSTER` is the cluster name or FID. Interactive if omitted.

Connects to the control node via SSH, downloads the kubeconfig, backs up the existing `~/.kube/config`, merges the new credentials, and validates with `kubectl cluster-info`.

#### Options

| Flag                    | Description                                        |
| ----------------------- | -------------------------------------------------- |
| `-i`, `--identity PATH` | SSH identity file. Auto-detected if omitted.       |
| `-y`, `--yes`           | Skip the confirmation prompt.                      |
| `--no-backup`           | Skip creating a backup of the existing kubeconfig. |
| `--skip-validation`     | Skip the `kubectl cluster-info` validation step.   |

#### Examples

```bash
ml k8s update-kubeconfig my-cluster
ml k8s update-kubeconfig my-cluster -y --no-backup
ml k8s update-kubeconfig                              # interactive picker
```

After updating:

```bash
kubectl config get-contexts
kubectl get nodes
```

***

### ml ssh

SSH into a Mithril instance by bid name.

```
ml ssh [BID_NAME] [OPTIONS] [-- COMMAND ...]
```

`BID_NAME` is the spot bid name. Interactive if omitted — presents a picker of running instances. By default, waits for the instance to become available and for SSH to be ready before connecting.

This command connects to **Mithril instances** (created via `ml instance create`). To SSH into a **SkyPilot cluster** (created via `ml launch`), use `ssh CLUSTER` directly — SkyPilot configures your SSH config automatically.

#### Options

| Flag           | Description                                                                                                                         |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `--node INDEX` | Node index for multi-instance bids. Defaults to 0 for interactive sessions; commands without `--node` run on all nodes in parallel. |
| `--show`       | Print the SSH command instead of executing it.                                                                                      |
| `--no-wait`    | Fail immediately if the instance is not running (do not wait for it to become available).                                           |

#### Examples

```bash
ml ssh my-instance                            # interactive shell
ml ssh my-instance nvidia-smi                 # run command on all nodes
ml ssh my-instance --node 0 nvidia-smi        # run on specific node
ml ssh my-instance --show                     # print ssh command
ml ssh                                        # interactive picker
```

***


# Flow (experimental)

Looking for Flow CLI?

A few months ago, we introduced Flow as an experimental CLI and SDK for Mithril to help us improve the developer experience. We incorporated those learnings into the Mithril CLI.


# API overview and quickstart

Mithril's Compute API

Mithril currently supports managing Spot Instances, Reservations, Storage Volumes, and SSH Keys via API.

### Prerequisites

1. Create an API key in the [Mithril](https://app.mlfoundry.com/account/apikeys) console. Remember to keep this key safe.
2. Note down your API key - it will look like `fkey_...`

### Authentication

All API requests require authentication using your API key in the Authorization header:

```python
key = "fkey_your_key_here" 
headers = {
    "Authorization": f"Bearer {key}"
}
```

### Common Operations

#### 1. List Your Projects

First, get a list of projects you have access to:

```python
import requests

response = requests.get(
    "https://api.mithril.ai/v2/projects",
    headers=headers
)
projects = response.json()
```

#### 2.  Creating a Storage Volume

Create a persistent storage volume for your instances:

```python
volume_data = {
    "name": "my-storage",  # Must be lowercase alphanumeric with hyphens
    "project": "proj_...",  # Your project FID
    "disk_interface": "Block",  # "Block" or "File"
    "region": "us-central1-a",
    "size_gb": 100
}

response = requests.post(
    "https://api.mithril.ai/v2/volumes",
    headers=headers,
    data=volume_data
)
volume = response.json()
```

#### 3.  Add or generate SSH key

```python
# Use your existing public key
ssh_key_data = {
    "project": "proj_...",  # Your project FID
    "name": "my-ssh-key",
    "public_key": "ssh-rsa AAAA..." # Your public key content
}

response = requests.post(
    "https://api.mithril.ai/v2/ssh-keys",
    headers=headers,
    data=ssh_key_data
)

# OR generate a new private key
ssh_key_data = {
    "project": "proj_...",  # Your project FID
    "name": "my-ssh-key"
}

response = requests.post(
    "https://api.mithril.ai/v2/ssh-keys",
    headers=headers,
    data=ssh_key_data
)
ssh_key = response.json()["private_key"]
```

#### 4. Creating a Spot Bid

Place a bid for Spot instances:

```python
bid_data = {
    "project": "proj_...",  # Your project FID
    "region": "us-central1-a", # Check /v2/spot/availability
    "instance_type": "it_5ECSoHQjLBzrp5YM",  # Check /v2/spot/availability
    "limit_price": "$15.50",  # Maximum price per hour you're willing to pay
    "instance_quantity": 1,
    "name": "my-training-job",
    "launch_specification": {
        "volumes": ["vol_..."],  # Your volume FID
        "ssh_keys": ["ssh_..."],  # Your SSH key FID
        "startup_script": "#!/bin/bash\necho 'Hello World'"
    }
}

response = requests.post(
    "https://api.mithril.ai/v2/spot/bids",
    headers=headers,
    json=bid_data
)
bid = response.json()
```

#### 5. Monitor Your Instances

Track the status of your instances:

```python
response = requests.get(
    "https://api.mithril.ai/v2/instances",
    headers=headers,
    params={"project": "proj_..."}  # Your project FID
)
instances = response.json()["data"]
```

### Tips

* Use the `/v2/spot/availability` endpoint to check current Spot capacity and pricing
* You'll need to configure billing on the Mithril Console before you can place bids with the API

For more detailed information about specific endpoints and their parameters, refer to the [full API documentation.](/compute-api/compute-api-reference)


# Compute API reference


# API Keys

## Get Api Keys

> Get all API keys registered to the user

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"ApiKeyModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"expires_at":{"type":"string","format":"datetime","title":"Expires At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"snippet":{"type":"string","title":"Snippet"}},"type":"object","required":["fid","name","created_at","expires_at","snippet"],"title":"ApiKeyModel"}}},"paths":{"/v2/api-keys":{"get":{"tags":["API Keys"],"summary":"Get Api Keys","description":"Get all API keys registered to the user","operationId":"get_api_keys_v2_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApiKeyModel"},"type":"array","title":"Response Get Api Keys V2 Api Keys Get"}}}},"401":{"description":"Invalid credentials"}}}}}}
```

## Create Api Key

> Create a new API key

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"CreateApiKeyRequest":{"properties":{"name":{"type":"string","title":"Name"},"expires_at":{"type":"string","format":"datetime","title":"Expires At"}},"type":"object","required":["name","expires_at"],"title":"CreateApiKeyRequest"},"CreateApiKeyResponse":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"expires_at":{"type":"string","format":"datetime","title":"Expires At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"snippet":{"type":"string","title":"Snippet"},"secret":{"type":"string","title":"Secret"}},"type":"object","required":["fid","name","created_at","expires_at","snippet","secret"],"title":"CreateApiKeyResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/api-keys":{"post":{"tags":["API Keys"],"summary":"Create Api Key","description":"Create a new API key","operationId":"create_api_key_v2_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyResponse"}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"Invalid credentials"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Revoke Api Key

> Revoke an API key

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/api-keys/{key_fid}":{"delete":{"tags":["API Keys"],"summary":"Revoke Api Key","description":"Revoke an API key","operationId":"revoke_api_key_v2_api_keys__key_fid__delete","parameters":[{"name":"key_fid","in":"path","required":true,"schema":{"type":"string","title":"Key Fid"}}],"responses":{"204":{"description":"Successful Response"},"400":{"description":"Invalid request"},"401":{"description":"Invalid credentials"},"404":{"description":"API key not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Profile

## Get Me

> Get the current user's profile

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"MeResponse":{"properties":{"id":{"type":"string","title":"Id"},"fid":{"type":"string","title":"Fid"},"email":{"type":"string","format":"email","title":"Email"},"user_name":{"type":"string","nullable":true},"organization_id":{"type":"string","title":"Organization Id"},"organization_role":{"type":"string","nullable":true}},"type":"object","required":["id","fid","email","organization_id"],"title":"MeResponse"}}},"paths":{"/v2/me":{"get":{"tags":["profile"],"summary":"Get Me","description":"Get the current user's profile","operationId":"get_me_v2_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}}}}}}}
```

## Get My Teammates

> Get teammates visible to the current user.\
> \
> Returns teammates from the user's organization, filtered by shared project\
> membership (unless the user is an org admin, in which case all org members\
> are visible). Can be used by a client to map user FIDs to user profiles.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"TeammateResponse":{"properties":{"id":{"type":"string","title":"Id"},"fid":{"type":"string","title":"Fid"},"user_name":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"organization_role":{"type":"string","nullable":true},"project_ids":{"items":{"type":"string"},"type":"array","title":"Project Ids"},"deactivated_at":{"type":"string","format":"datetime","nullable":true}},"type":"object","required":["id","fid","project_ids"],"title":"TeammateResponse"}}},"paths":{"/v2/me/teammates":{"get":{"tags":["profile"],"summary":"Get My Teammates","description":"Get teammates visible to the current user.\n\nReturns teammates from the user's organization, filtered by shared project\nmembership (unless the user is an org admin, in which case all org members\nare visible). Can be used by a client to map user FIDs to user profiles.","operationId":"get_my_teammates_v2_me_teammates_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/TeammateResponse"},"type":"array","title":"Response Get My Teammates V2 Me Teammates Get"}}}}}}}}}
```


# SSH Keys

## Get Ssh Keys

> Get all SSH keys for a project

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"NewSshKeyModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"public_key":{"type":"string","title":"Public Key"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"required":{"type":"boolean","title":"Required"}},"type":"object","required":["fid","name","project","public_key","created_at","required"],"title":"NewSshKeyModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/ssh-keys":{"get":{"tags":["SSH Keys"],"summary":"Get Ssh Keys","description":"Get all SSH keys for a project","operationId":"get_ssh_keys_v2_ssh_keys_get","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NewSshKeyModel"},"title":"Response Get Ssh Keys V2 Ssh Keys Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Create Ssh Key

> Create a new SSH key. If public\_key is not provided, this endpoint will generate\
> a new RSA key pair and return both the private and public keys.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"CreateSshKeyRequest":{"properties":{"project":{"type":"string","title":"Project"},"name":{"type":"string","title":"Name"},"public_key":{"type":"string","nullable":true},"required":{"type":"boolean","title":"Required","default":false}},"type":"object","required":["project","name"],"title":"CreateSshKeyRequest"},"CreatedSshKeyModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"public_key":{"type":"string","title":"Public Key"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"required":{"type":"boolean","title":"Required"},"private_key":{"type":"string","nullable":true}},"type":"object","required":["fid","name","project","public_key","created_at","required"],"title":"CreatedSshKeyModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/ssh-keys":{"post":{"tags":["SSH Keys"],"summary":"Create Ssh Key","description":"Create a new SSH key. If public_key is not provided, this endpoint will generate\na new RSA key pair and return both the private and public keys.","operationId":"create_ssh_key_v2_ssh_keys_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSshKeyRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedSshKeyModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Delete Ssh Key

> Delete an SSH key. Note that SSH keys used in active bids/reservations cannot\
> be deleted.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/ssh-keys/{ssh_key_fid}":{"delete":{"tags":["SSH Keys"],"summary":"Delete Ssh Key","description":"Delete an SSH key. Note that SSH keys used in active bids/reservations cannot\nbe deleted.","operationId":"delete_ssh_key_v2_ssh_keys__ssh_key_fid__delete","parameters":[{"name":"ssh_key_fid","in":"path","required":true,"schema":{"type":"string","title":"Ssh Key Fid"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Update Ssh Key

> Update an SSH key to set it as required. Only admins can set a key as required.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"UpdateSshKeyRequest":{"properties":{"required":{"type":"boolean","title":"Required"}},"type":"object","required":["required"],"title":"UpdateSshKeyRequest"},"NewSshKeyModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"public_key":{"type":"string","title":"Public Key"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"required":{"type":"boolean","title":"Required"}},"type":"object","required":["fid","name","project","public_key","created_at","required"],"title":"NewSshKeyModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/ssh-keys/{ssh_key_fid}":{"patch":{"tags":["SSH Keys"],"summary":"Update Ssh Key","description":"Update an SSH key to set it as required. Only admins can set a key as required.","operationId":"update_ssh_key_v2_ssh_keys__ssh_key_fid__patch","parameters":[{"name":"ssh_key_fid","in":"path","required":true,"schema":{"type":"string","title":"Ssh Key Fid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSshKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewSshKeyModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Spot

## Get Bids

> Get all Spot bids for a project, or all user's projects if not specified

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"SortDirection":{"type":"string","enum":["asc","desc"]},"GetBidsResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/BidModel"},"type":"array","title":"Data"},"next_cursor":{"type":"string","nullable":true}},"type":"object","required":["data"],"title":"GetBidsResponse"},"BidModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_by":{"type":"string","title":"Created By"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"limit_price":{"type":"string","title":"Limit Price"},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"status":{"type":"string","enum":["Open","Allocated","Preempting","Terminated","Paused"],"title":"Status"}},"type":"object","required":["fid","name","project","created_by","created_at","limit_price","instance_quantity","instance_type","instances","launch_specification","status"],"title":"BidModel"},"LaunchSpecificationModel":{"properties":{"volumes":{"items":{"type":"string"},"type":"array","title":"Volumes","description":"List of volume FIDs"},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys","description":"List of SSH key FIDs"},"startup_script":{"type":"string","nullable":true},"kubernetes_cluster":{"type":"string","nullable":true},"image_version":{"type":"string","nullable":true},"memory_gb":{"type":"integer","nullable":true}},"type":"object","required":["volumes","ssh_keys"],"title":"LaunchSpecificationModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/spot/bids":{"get":{"tags":["spot"],"summary":"Get Bids","description":"Get all Spot bids for a project, or all user's projects if not specified","operationId":"get_bids_v2_spot_bids_get","parameters":[{"name":"next_cursor","in":"query","required":false,"schema":{"nullable":true}},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["created_at","status"],"type":"string","nullable":true}},{"name":"sort_dir","in":"query","required":false,"schema":{"$ref":"#/components/schemas/SortDirection","nullable":true}},{"name":"project","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"instance_type","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"region","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"status","in":"query","required":false,"schema":{"enum":["Open","Allocated","Preempting","Terminated","Paused"],"type":"string","nullable":true}},{"name":"name","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"nullable":true}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBidsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Create Bid

> Place a new Spot bid

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"CreateBidRequest":{"properties":{"project":{"type":"string","title":"Project"},"region":{"type":"string","title":"Region"},"instance_type":{"type":"string","title":"Instance Type"},"limit_price":{"type":"string","title":"Limit Price"},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"name":{"type":"string","title":"Name"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"notification_email":{"type":"string","nullable":true}},"type":"object","required":["project","region","instance_type","limit_price","instance_quantity","name","launch_specification"],"title":"CreateBidRequest"},"LaunchSpecificationModel":{"properties":{"volumes":{"items":{"type":"string"},"type":"array","title":"Volumes","description":"List of volume FIDs"},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys","description":"List of SSH key FIDs"},"startup_script":{"type":"string","nullable":true},"kubernetes_cluster":{"type":"string","nullable":true},"image_version":{"type":"string","nullable":true},"memory_gb":{"type":"integer","nullable":true}},"type":"object","required":["volumes","ssh_keys"],"title":"LaunchSpecificationModel"},"BidModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_by":{"type":"string","title":"Created By"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"limit_price":{"type":"string","title":"Limit Price"},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"status":{"type":"string","enum":["Open","Allocated","Preempting","Terminated","Paused"],"title":"Status"}},"type":"object","required":["fid","name","project","created_by","created_at","limit_price","instance_quantity","instance_type","instances","launch_specification","status"],"title":"BidModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/spot/bids":{"post":{"tags":["spot"],"summary":"Create Bid","description":"Place a new Spot bid","operationId":"create_bid_v2_spot_bids_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBidRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BidModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Bid

> Get a single Spot bid by FID

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"BidModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_by":{"type":"string","title":"Created By"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"limit_price":{"type":"string","title":"Limit Price"},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"status":{"type":"string","enum":["Open","Allocated","Preempting","Terminated","Paused"],"title":"Status"}},"type":"object","required":["fid","name","project","created_by","created_at","limit_price","instance_quantity","instance_type","instances","launch_specification","status"],"title":"BidModel"},"LaunchSpecificationModel":{"properties":{"volumes":{"items":{"type":"string"},"type":"array","title":"Volumes","description":"List of volume FIDs"},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys","description":"List of SSH key FIDs"},"startup_script":{"type":"string","nullable":true},"kubernetes_cluster":{"type":"string","nullable":true},"image_version":{"type":"string","nullable":true},"memory_gb":{"type":"integer","nullable":true}},"type":"object","required":["volumes","ssh_keys"],"title":"LaunchSpecificationModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/spot/bids/{bid_fid}":{"get":{"tags":["spot"],"summary":"Get Bid","description":"Get a single Spot bid by FID","operationId":"get_bid_v2_spot_bids__bid_fid__get","parameters":[{"name":"bid_fid","in":"path","required":true,"schema":{"type":"string","title":"Bid Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BidModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Cancel Bid

> Cancel a Spot bid

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/spot/bids/{bid_fid}":{"delete":{"tags":["spot"],"summary":"Cancel Bid","description":"Cancel a Spot bid","operationId":"cancel_bid_v2_spot_bids__bid_fid__delete","parameters":[{"name":"bid_fid","in":"path","required":true,"schema":{"type":"string","title":"Bid Fid"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Update Bid

> Update the limit price of a Spot bid

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"UpdateBidRequest":{"properties":{"limit_price":{"type":"string","nullable":true},"paused":{"type":"boolean","nullable":true},"volumes":{"items":{"type":"string"},"type":"array","nullable":true},"memory_gb":{"type":"integer","nullable":true}},"type":"object","title":"UpdateBidRequest"},"BidModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_by":{"type":"string","title":"Created By"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"limit_price":{"type":"string","title":"Limit Price"},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"status":{"type":"string","enum":["Open","Allocated","Preempting","Terminated","Paused"],"title":"Status"}},"type":"object","required":["fid","name","project","created_by","created_at","limit_price","instance_quantity","instance_type","instances","launch_specification","status"],"title":"BidModel"},"LaunchSpecificationModel":{"properties":{"volumes":{"items":{"type":"string"},"type":"array","title":"Volumes","description":"List of volume FIDs"},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys","description":"List of SSH key FIDs"},"startup_script":{"type":"string","nullable":true},"kubernetes_cluster":{"type":"string","nullable":true},"image_version":{"type":"string","nullable":true},"memory_gb":{"type":"integer","nullable":true}},"type":"object","required":["volumes","ssh_keys"],"title":"LaunchSpecificationModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/spot/bids/{bid_fid}":{"patch":{"tags":["spot"],"summary":"Update Bid","description":"Update the limit price of a Spot bid","operationId":"update_bid_v2_spot_bids__bid_fid__patch","parameters":[{"name":"bid_fid","in":"path","required":true,"schema":{"type":"string","title":"Bid Fid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBidRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BidModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Bid Status

> Get detailed status of a Spot bid.\
> \
> Returns a detailed status that includes instance-level status information.\
> The status can be one of: Open, Allocated, Preempting, Terminated,\
> Paused, Relocating.\
> \
> "Relocating" indicates that part of the order is being relocated.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"BidStatusResponse":{"properties":{"bid_fid":{"type":"string","title":"Bid Fid"},"status":{"type":"string","enum":["Open","Allocated","Preempting","Terminated","Paused","Relocating"],"title":"Status"}},"type":"object","required":["bid_fid","status"],"title":"BidStatusResponse","description":"Response model for the detailed bid status endpoint."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/spot/bids/{bid_fid}/status":{"get":{"tags":["spot"],"summary":"Get Bid Status","description":"Get detailed status of a Spot bid.\n\nReturns a detailed status that includes instance-level status information.\nThe status can be one of: Open, Allocated, Preempting, Terminated,\nPaused, Relocating.\n\n\"Relocating\" indicates that part of the order is being relocated.","operationId":"get_bid_status_v2_spot_bids__bid_fid__status_get","parameters":[{"name":"bid_fid","in":"path","required":true,"schema":{"type":"string","title":"Bid Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BidStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Bid History

> Get the history of events for a Spot bid.\
> \
> Returns a list of historical events including:\
> \- placing the bid\
> \- pausing the bid\
> \- resuming the bid\
> \- terminating the bid\
> \- changes to the limit price

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"BidHistoryResponse":{"properties":{"bid_fid":{"type":"string","title":"Bid Fid"},"events":{"items":{"$ref":"#/components/schemas/BidHistoryEventModel"},"type":"array","title":"Events","description":"List of historical events for this bid, ordered by timestamp"}},"type":"object","required":["bid_fid","events"],"title":"BidHistoryResponse","description":"Response model for bid history."},"BidHistoryEventModel":{"properties":{"timestamp":{"type":"string","format":"datetime","title":"Timestamp","description":"When the event occurred"},"event_type":{"type":"string","enum":["Placed","Paused","Resumed","Terminated","Allocated","Preempted","Limit Price Changed","Memory Adjusted","Volumes Attached","Volumes Removed"],"title":"Event Type"},"limit_price":{"type":"string","nullable":true},"user_id":{"type":"string","nullable":true},"memory_gb":{"type":"integer","nullable":true},"persistent_disk_change":{"$ref":"#/components/schemas/PersistentDiskChange","nullable":true}},"type":"object","required":["timestamp","event_type"],"title":"BidHistoryEventModel","description":"A single event in the history of a spot bid."},"PersistentDiskChange":{"properties":{"attached":{"type":"string","nullable":true},"removed":{"type":"string","nullable":true}},"type":"object","title":"PersistentDiskChange"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/spot/bids/{bid_fid}/history":{"get":{"tags":["spot"],"summary":"Get Bid History","description":"Get the history of events for a Spot bid.\n\nReturns a list of historical events including:\n- placing the bid\n- pausing the bid\n- resuming the bid\n- terminating the bid\n- changes to the limit price","operationId":"get_bid_history_v2_spot_bids__bid_fid__history_get","parameters":[{"name":"bid_fid","in":"path","required":true,"schema":{"type":"string","title":"Bid Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BidHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Auctions

> Get the Spot availability across all regions.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"AuctionModel":{"properties":{"fid":{"type":"string","title":"Fid"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","title":"Region"},"capacity":{"type":"integer","title":"Capacity"},"last_instance_price":{"type":"string","title":"Last Instance Price"},"lowest_allocated_price":{"type":"string","nullable":true},"adjustable_memory":{"type":"boolean","title":"Adjustable Memory"},"default_image_version":{"type":"string","nullable":true}},"type":"object","required":["fid","instance_type","region","capacity","last_instance_price","adjustable_memory"],"title":"AuctionModel"}}},"paths":{"/v2/spot/availability":{"get":{"tags":["spot"],"summary":"Get Auctions","description":"Get the Spot availability across all regions.","operationId":"get_auctions_v2_spot_availability_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AuctionModel"},"type":"array","title":"Response Get Auctions V2 Spot Availability Get"}}}}}}}}}
```


# Lifecycle Scripts

## List Lifecycle Scripts

> Get all lifecycle scripts visible to user in a project

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"SortDirection":{"type":"string","enum":["asc","desc"]},"ListLifecycleScriptsResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/LifecycleScriptModel"},"type":"array","title":"Data"},"next_cursor":{"type":"string","nullable":true}},"type":"object","required":["data"],"title":"ListLifecycleScriptsResponse"},"LifecycleScriptModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"content_url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Content Url"},"project":{"type":"string","title":"Project"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"created_by":{"type":"string","title":"Created By"},"last_modified_at":{"type":"string","format":"datetime","title":"Last Modified At"},"last_modified_by":{"type":"string","title":"Last Modified By"},"scope":{"$ref":"#/components/schemas/LifecycleScriptScope"}},"type":"object","required":["fid","name","description","content_url","project","created_at","created_by","last_modified_at","last_modified_by","scope"],"title":"LifecycleScriptModel"},"LifecycleScriptScope":{"type":"string","enum":["PROJECT","ORGANIZATION","PLATFORM"]},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/lifecycle-scripts":{"get":{"tags":["lifecycle scripts"],"summary":"List Lifecycle Scripts","description":"Get all lifecycle scripts visible to user in a project","operationId":"list_lifecycle_scripts_v2_lifecycle_scripts_get","parameters":[{"name":"next_cursor","in":"query","required":false,"schema":{"nullable":true}},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["created_at","last_modified_at"],"type":"string","nullable":true}},{"name":"sort_dir","in":"query","required":false,"schema":{"$ref":"#/components/schemas/SortDirection","nullable":true}},{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"nullable":true}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLifecycleScriptsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Create Lifecycle Script

> Create a new lifecycle script

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"CreateLifecycleScriptRequest":{"properties":{"project":{"type":"string","title":"Project"},"name":{"type":"string","minLength":1,"title":"Name"},"content":{"type":"string","minLength":1,"title":"Content"},"description":{"type":"string","nullable":true},"scope":{"$ref":"#/components/schemas/PublicLifecycleScriptScope","default":"PROJECT"}},"type":"object","required":["project","name","content"],"title":"CreateLifecycleScriptRequest"},"PublicLifecycleScriptScope":{"type":"string","enum":["PROJECT","ORGANIZATION"]},"LifecycleScriptModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"content_url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Content Url"},"project":{"type":"string","title":"Project"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"created_by":{"type":"string","title":"Created By"},"last_modified_at":{"type":"string","format":"datetime","title":"Last Modified At"},"last_modified_by":{"type":"string","title":"Last Modified By"},"scope":{"$ref":"#/components/schemas/LifecycleScriptScope"}},"type":"object","required":["fid","name","description","content_url","project","created_at","created_by","last_modified_at","last_modified_by","scope"],"title":"LifecycleScriptModel"},"LifecycleScriptScope":{"type":"string","enum":["PROJECT","ORGANIZATION","PLATFORM"]},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/lifecycle-scripts":{"post":{"tags":["lifecycle scripts"],"summary":"Create Lifecycle Script","description":"Create a new lifecycle script","operationId":"create_lifecycle_script_v2_lifecycle_scripts_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLifecycleScriptRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleScriptModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## GET /v2/lifecycle-scripts/{ls\_fid}/content

> Get Lifecycle Script Content

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/lifecycle-scripts/{ls_fid}/content":{"get":{"tags":["lifecycle scripts"],"summary":"Get Lifecycle Script Content","operationId":"get_lifecycle_script_content_v2_lifecycle_scripts__ls_fid__content_get","parameters":[{"name":"ls_fid","in":"path","required":true,"schema":{"type":"string","title":"Ls Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## DELETE /v2/lifecycle-scripts/{ls\_fid}

> Delete Lifecycle Script

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/lifecycle-scripts/{ls_fid}":{"delete":{"tags":["lifecycle scripts"],"summary":"Delete Lifecycle Script","operationId":"delete_lifecycle_script_v2_lifecycle_scripts__ls_fid__delete","parameters":[{"name":"ls_fid","in":"path","required":true,"schema":{"type":"string","title":"Ls Fid"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## PATCH /v2/lifecycle-scripts/{ls\_fid}

> Update Lifecycle Script

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"UpdateLifecycleScriptRequest":{"properties":{"name":{"type":"string","minLength":1,"nullable":true},"description":{"type":"string","nullable":true},"scope":{"$ref":"#/components/schemas/PublicLifecycleScriptScope","nullable":true}},"type":"object","title":"UpdateLifecycleScriptRequest"},"PublicLifecycleScriptScope":{"type":"string","enum":["PROJECT","ORGANIZATION"]},"LifecycleScriptModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"content_url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Content Url"},"project":{"type":"string","title":"Project"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"created_by":{"type":"string","title":"Created By"},"last_modified_at":{"type":"string","format":"datetime","title":"Last Modified At"},"last_modified_by":{"type":"string","title":"Last Modified By"},"scope":{"$ref":"#/components/schemas/LifecycleScriptScope"}},"type":"object","required":["fid","name","description","content_url","project","created_at","created_by","last_modified_at","last_modified_by","scope"],"title":"LifecycleScriptModel"},"LifecycleScriptScope":{"type":"string","enum":["PROJECT","ORGANIZATION","PLATFORM"]},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/lifecycle-scripts/{ls_fid}":{"patch":{"tags":["lifecycle scripts"],"summary":"Update Lifecycle Script","operationId":"update_lifecycle_script_v2_lifecycle_scripts__ls_fid__patch","parameters":[{"name":"ls_fid","in":"path","required":true,"schema":{"type":"string","title":"Ls Fid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLifecycleScriptRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleScriptModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Reservations

## Get Reservation Instance Types

> Get instance types available for reservation.\
> \
> Returns the subset of public instance types that are currently\
> eligible for reservation. Instance types can be disabled for\
> reservation via the Unleash reservation-disabled-instance-types\
> feature flag.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"InstanceTypeModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"num_cpus":{"type":"integer","title":"Num Cpus"},"cpu_type":{"type":"string","title":"Cpu Type"},"ram_gb":{"type":"integer","title":"Ram Gb"},"num_gpus":{"type":"integer","title":"Num Gpus"},"gpu_type":{"type":"string","title":"Gpu Type"},"gpu_memory_gb":{"type":"integer","title":"Gpu Memory Gb"},"gpu_socket":{"type":"string","title":"Gpu Socket"},"local_storage_gb":{"type":"integer","title":"Local Storage Gb"},"network_type":{"type":"string","nullable":true},"ib_count":{"type":"integer","title":"Ib Count"},"bridge_count":{"type":"integer","title":"Bridge Count"},"hourly_price":{"type":"number","title":"Hourly Price"}},"type":"object","required":["fid","name","num_cpus","cpu_type","ram_gb","num_gpus","gpu_type","gpu_memory_gb","gpu_socket","local_storage_gb","ib_count","bridge_count","hourly_price"],"title":"InstanceTypeModel"}}},"paths":{"/v2/reservation/instance-types":{"get":{"tags":["reservations","instance types"],"summary":"Get Reservation Instance Types","description":"Get instance types available for reservation.\n\nReturns the subset of public instance types that are currently\neligible for reservation. Instance types can be disabled for\nreservation via the Unleash reservation-disabled-instance-types\nfeature flag.","operationId":"get_reservation_instance_types_v2_reservation_instance_types_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/InstanceTypeModel"},"type":"array","title":"Response Get Reservation Instance Types V2 Reservation Instance Types Get"}}}}}}}}}
```

## Get Reservation Quote

> Get pricing offers for a reservation.\
> \
> Reservation offers are dynamic and the price may change slightly since\
> the time it was generated. You can include an optional "max\_unit\_price"\
> (which you can set at the quoted price or slightly above it) to ensure\
> your reservation request fails if the new price is above that max.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"ReservationQuoteResponse":{"properties":{"offers":{"items":{"$ref":"#/components/schemas/ReservationOffer"},"type":"array","title":"Offers"}},"type":"object","required":["offers"],"title":"ReservationQuoteResponse","description":"Response with all pricing offers available when creating a new reservation."},"ReservationOffer":{"properties":{"key":{"type":"string","title":"Key"},"display_name":{"type":"string","title":"Display Name"},"unit_price":{"type":"string","title":"Unit Price"},"return_buyback_price":{"type":"string","title":"Return Buyback Price"},"pause_buyback_price":{"type":"string","title":"Pause Buyback Price"},"total_price":{"type":"string","title":"Total Price"},"total_etbp_value":{"type":"string","title":"Total Etbp Value"},"total_fubp_value":{"type":"string","title":"Total Fubp Value"},"option_premium":{"type":"string","title":"Option Premium"}},"type":"object","required":["key","display_name","unit_price","return_buyback_price","pause_buyback_price","total_price","total_etbp_value","total_fubp_value","option_premium"],"title":"ReservationOffer","description":"A single pricing offer within a quote response."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation/quote":{"get":{"tags":["reservations"],"summary":"Get Reservation Quote","description":"Get pricing offers for a reservation.\n\nReservation offers are dynamic and the price may change slightly since\nthe time it was generated. You can include an optional \"max_unit_price\"\n(which you can set at the quoted price or slightly above it) to ensure\nyour reservation request fails if the new price is above that max.","operationId":"get_reservation_quote_v2_reservation_quote_get","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}},{"name":"instance_type","in":"query","required":true,"schema":{"type":"string","title":"Instance Type"}},{"name":"region","in":"query","required":true,"schema":{"type":"string","title":"Region"}},{"name":"start_time","in":"query","required":true,"schema":{"type":"string","format":"datetime","title":"Start Time"}},{"name":"end_time","in":"query","required":true,"schema":{"type":"string","format":"datetime","title":"End Time"}},{"name":"quantity","in":"query","required":true,"schema":{"type":"integer","minimum":1,"title":"Quantity"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationQuoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Availability

> Get availability information for reservations.\
> \
> This endpoint supports three different modes for querying availability:\
> \
> \## Mode: latest\_end\_time (default)\
> Get the latest possible end time for a reservation given a start time and\
> quantity.\
> \
> \*\*Required parameters:\*\*\
> \- \`start\_time\`: Desired start time for the reservation\
> \- \`quantity\`: Number of instances needed\
> \- \`project\`: Project FID\
> \- \`instance\_type\`: Instance type FID\
> \- \`region\`: Region name\
> \
> \*\*Returns:\*\* Latest possible end time and availability status\
> \
> \*\*Example:\*\*\
> \`\`\`\
> GET /reservation/availability?\
> &#x20;   start\_time=2024-01-01T00:00:00Z&\
> &#x20;   quantity=4&\
> &#x20;   project=proj\_01h8x2k9m3n4p5q6r7s8t9u0v&\
> &#x20;   instance\_type=it\_01h8x2k9m3n4p5q6r7s8t9u0v&\
> &#x20;   region=us-central1-a\
> \`\`\`\
> \
> \## Mode: slots\
> Get all available slots in a time range.\
> \
> \*\*Required parameters:\*\*\
> \- \`earliest\_start\_time\`: Start of the time range to search\
> \- \`latest\_end\_time\`: End of the time range to search\
> \- \`project\`: Project FID\
> \- \`instance\_type\`: Instance type FID\
> \- \`region\`: Region name\
> \
> \*\*Returns:\*\* List of available time slots with quantities\
> \
> \*\*Example:\*\*\
> \`\`\`\
> GET /reservation/availability?\
> &#x20;   mode=slots&\
> &#x20;   earliest\_start\_time=2024-01-01T00:00:00Z&\
> &#x20;   latest\_end\_time=2024-01-02T00:00:00Z&\
> &#x20;   project=proj\_01h8x2k9m3n4p5q6r7s8t9u0v&\
> &#x20;   instance\_type=it\_01h8x2k9m3n4p5q6r7s8t9u0v&\
> &#x20;   region=us-central1-a\
> \`\`\`\
> \
> \## Mode: check\
> Check if a specific time slot is available for reservation.\
> \
> \*\*Required parameters:\*\*\
> \- \`start\_time\`: Start of the desired time slot\
> \- \`end\_time\`: End of the desired time slot\
> \- \`quantity\`: Number of instances needed\
> \- \`project\`: Project FID\
> \- \`instance\_type\`: Instance type FID\
> \- \`region\`: Region name\
> \
> \*\*Returns:\*\* Boolean indicating if the slot is available\
> \
> \*\*Example:\*\*\
> \`\`\`\
> GET /reservation/availability?\
> &#x20;   mode=check&\
> &#x20;   start\_time=2024-01-01T00:00:00Z&\
> &#x20;   end\_time=2024-01-01T12:00:00Z&\
> &#x20;   quantity=4&\
> &#x20;   project=proj\_01h8x2k9m3n4p5q6r7s8t9u0v&\
> &#x20;   instance\_type=it\_01h8x2k9m3n4p5q6r7s8t9u0v&\
> &#x20;   region=us-central1-a\
> \`\`\`\
> \
> \## Common Parameters\
> All modes require these parameters:\
> \- \`project\`: Project FID\
> \- \`instance\_type\`: Instance type FID\
> \- \`region\`: Region name\
> \
> \## Authentication\
> Requires authentication and user must be a member of the specified project.

````json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"AvailabilitySlotModel":{"properties":{"start_time":{"type":"string","format":"datetime","title":"Start Time"},"end_time":{"type":"string","format":"datetime","title":"End Time"},"quantity":{"type":"integer","title":"Quantity"}},"type":"object","required":["start_time","end_time","quantity"],"title":"AvailabilitySlotModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation/availability":{"get":{"tags":["reservations"],"summary":"Get Availability","description":"Get availability information for reservations.\n\nThis endpoint supports three different modes for querying availability:\n\n## Mode: latest_end_time (default)\nGet the latest possible end time for a reservation given a start time and\nquantity.\n\n**Required parameters:**\n- `start_time`: Desired start time for the reservation\n- `quantity`: Number of instances needed\n- `project`: Project FID\n- `instance_type`: Instance type FID\n- `region`: Region name\n\n**Returns:** Latest possible end time and availability status\n\n**Example:**\n```\nGET /reservation/availability?\n    start_time=2024-01-01T00:00:00Z&\n    quantity=4&\n    project=proj_01h8x2k9m3n4p5q6r7s8t9u0v&\n    instance_type=it_01h8x2k9m3n4p5q6r7s8t9u0v&\n    region=us-central1-a\n```\n\n## Mode: slots\nGet all available slots in a time range.\n\n**Required parameters:**\n- `earliest_start_time`: Start of the time range to search\n- `latest_end_time`: End of the time range to search\n- `project`: Project FID\n- `instance_type`: Instance type FID\n- `region`: Region name\n\n**Returns:** List of available time slots with quantities\n\n**Example:**\n```\nGET /reservation/availability?\n    mode=slots&\n    earliest_start_time=2024-01-01T00:00:00Z&\n    latest_end_time=2024-01-02T00:00:00Z&\n    project=proj_01h8x2k9m3n4p5q6r7s8t9u0v&\n    instance_type=it_01h8x2k9m3n4p5q6r7s8t9u0v&\n    region=us-central1-a\n```\n\n## Mode: check\nCheck if a specific time slot is available for reservation.\n\n**Required parameters:**\n- `start_time`: Start of the desired time slot\n- `end_time`: End of the desired time slot\n- `quantity`: Number of instances needed\n- `project`: Project FID\n- `instance_type`: Instance type FID\n- `region`: Region name\n\n**Returns:** Boolean indicating if the slot is available\n\n**Example:**\n```\nGET /reservation/availability?\n    mode=check&\n    start_time=2024-01-01T00:00:00Z&\n    end_time=2024-01-01T12:00:00Z&\n    quantity=4&\n    project=proj_01h8x2k9m3n4p5q6r7s8t9u0v&\n    instance_type=it_01h8x2k9m3n4p5q6r7s8t9u0v&\n    region=us-central1-a\n```\n\n## Common Parameters\nAll modes require these parameters:\n- `project`: Project FID\n- `instance_type`: Instance type FID\n- `region`: Region name\n\n## Authentication\nRequires authentication and user must be a member of the specified project.","operationId":"get_availability_v2_reservation_availability_get","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}},{"name":"instance_type","in":"query","required":true,"schema":{"type":"string","title":"Instance Type"}},{"name":"region","in":"query","required":true,"schema":{"type":"string","title":"Region"}},{"name":"mode","in":"query","required":false,"schema":{"enum":["slots","latest_end_time","check"],"type":"string","default":"latest_end_time","title":"Mode"}},{"name":"earliest_start_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}},{"name":"latest_end_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}},{"name":"start_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}},{"name":"end_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}},{"name":"quantity","in":"query","required":false,"schema":{"type":"integer","exclusiveMinimum":0,"nullable":true}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AvailabilitySlotModel"}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
````

## Get Reservations

> Get all reservations for a project

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"SortDirection":{"type":"string","enum":["asc","desc"]},"GetReservationsResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ReservationModel"},"type":"array","title":"Data"},"next_cursor":{"type":"string","nullable":true}},"type":"object","required":["data"],"title":"GetReservationsResponse"},"ReservationModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_by":{"type":"string","title":"Created By"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"status":{"type":"string","enum":["Pending","Active","Paused","Canceled","Ended"],"title":"Status"},"start_time":{"type":"string","format":"datetime","title":"Start Time"},"end_time":{"type":"string","format":"datetime","title":"End Time"},"total_price":{"type":"string","title":"Total Price"},"unit_price":{"type":"string","title":"Unit Price"}},"type":"object","required":["fid","name","project","created_by","created_at","instance_quantity","instance_type","instances","launch_specification","status","start_time","end_time","total_price","unit_price"],"title":"ReservationModel"},"LaunchSpecificationModel":{"properties":{"volumes":{"items":{"type":"string"},"type":"array","title":"Volumes","description":"List of volume FIDs"},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys","description":"List of SSH key FIDs"},"startup_script":{"type":"string","nullable":true},"kubernetes_cluster":{"type":"string","nullable":true},"image_version":{"type":"string","nullable":true},"memory_gb":{"type":"integer","nullable":true}},"type":"object","required":["volumes","ssh_keys"],"title":"LaunchSpecificationModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation":{"get":{"tags":["reservations"],"summary":"Get Reservations","description":"Get all reservations for a project","operationId":"get_reservations_v2_reservation_get","parameters":[{"name":"next_cursor","in":"query","required":false,"schema":{"nullable":true}},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["created_at","status"],"type":"string","nullable":true}},{"name":"sort_dir","in":"query","required":false,"schema":{"$ref":"#/components/schemas/SortDirection","nullable":true}},{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}},{"name":"instance_type","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"region","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"status","in":"query","required":false,"schema":{"enum":["Pending","Active","Paused","Canceled","Ended"],"type":"string","nullable":true}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"nullable":true}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetReservationsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Create Reservation

> Create a new reservation.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"CreateReservationRequest":{"properties":{"project":{"type":"string","title":"Project"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","title":"Region"},"start_time":{"type":"string","format":"datetime","title":"Start Time"},"end_time":{"type":"string","format":"datetime","title":"End Time"},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"name":{"type":"string","title":"Name"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"price_specification":{"$ref":"#/components/schemas/PriceSpecification","nullable":true},"notification_email":{"type":"string","nullable":true}},"type":"object","required":["project","instance_type","region","start_time","end_time","instance_quantity","name","launch_specification"],"title":"CreateReservationRequest"},"LaunchSpecificationModel":{"properties":{"volumes":{"items":{"type":"string"},"type":"array","title":"Volumes","description":"List of volume FIDs"},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys","description":"List of SSH key FIDs"},"startup_script":{"type":"string","nullable":true},"kubernetes_cluster":{"type":"string","nullable":true},"image_version":{"type":"string","nullable":true},"memory_gb":{"type":"integer","nullable":true}},"type":"object","required":["volumes","ssh_keys"],"title":"LaunchSpecificationModel"},"PriceSpecification":{"properties":{"offer_key":{"type":"string","title":"Offer Key","default":"standard"},"max_unit_price":{"type":"integer","minimum":0,"nullable":true}},"type":"object","title":"PriceSpecification","description":"Optional pricing specification for flexible reservations.\n\nIf omitted, the reservation defaults to the 'standard' offer.\nIf provided, the system applies the specified offer's pricing."},"ReservationModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_by":{"type":"string","title":"Created By"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"status":{"type":"string","enum":["Pending","Active","Paused","Canceled","Ended"],"title":"Status"},"start_time":{"type":"string","format":"datetime","title":"Start Time"},"end_time":{"type":"string","format":"datetime","title":"End Time"},"total_price":{"type":"string","title":"Total Price"},"unit_price":{"type":"string","title":"Unit Price"}},"type":"object","required":["fid","name","project","created_by","created_at","instance_quantity","instance_type","instances","launch_specification","status","start_time","end_time","total_price","unit_price"],"title":"ReservationModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation":{"post":{"tags":["reservations"],"summary":"Create Reservation","description":"Create a new reservation.","operationId":"create_reservation_v2_reservation_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReservationRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Extension Availability

> Get extension availability for a reservation

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"ExtensionAvailabilityResponse":{"properties":{"latest_extension_time":{"type":"string","format":"datetime","title":"Latest Extension Time"},"available":{"type":"boolean","title":"Available"}},"type":"object","required":["latest_extension_time","available"],"title":"ExtensionAvailabilityResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation/{reservation_fid}/extension-availability":{"get":{"tags":["reservations"],"summary":"Get Extension Availability","description":"Get extension availability for a reservation","operationId":"get_extension_availability_v2_reservation__reservation_fid__extension_availability_get","parameters":[{"name":"reservation_fid","in":"path","required":true,"schema":{"type":"string","title":"Reservation Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionAvailabilityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Extend Reservation

> Extend a reservation to the requested time.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"ExtendReservationRequest":{"properties":{"end_time":{"type":"string","format":"datetime","title":"End Time"},"price_specification":{"$ref":"#/components/schemas/PriceSpecification","nullable":true}},"type":"object","required":["end_time"],"title":"ExtendReservationRequest"},"PriceSpecification":{"properties":{"offer_key":{"type":"string","title":"Offer Key","default":"standard"},"max_unit_price":{"type":"integer","minimum":0,"nullable":true}},"type":"object","title":"PriceSpecification","description":"Optional pricing specification for flexible reservations.\n\nIf omitted, the reservation defaults to the 'standard' offer.\nIf provided, the system applies the specified offer's pricing."},"ReservationModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_by":{"type":"string","title":"Created By"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"status":{"type":"string","enum":["Pending","Active","Paused","Canceled","Ended"],"title":"Status"},"start_time":{"type":"string","format":"datetime","title":"Start Time"},"end_time":{"type":"string","format":"datetime","title":"End Time"},"total_price":{"type":"string","title":"Total Price"},"unit_price":{"type":"string","title":"Unit Price"}},"type":"object","required":["fid","name","project","created_by","created_at","instance_quantity","instance_type","instances","launch_specification","status","start_time","end_time","total_price","unit_price"],"title":"ReservationModel"},"LaunchSpecificationModel":{"properties":{"volumes":{"items":{"type":"string"},"type":"array","title":"Volumes","description":"List of volume FIDs"},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys","description":"List of SSH key FIDs"},"startup_script":{"type":"string","nullable":true},"kubernetes_cluster":{"type":"string","nullable":true},"image_version":{"type":"string","nullable":true},"memory_gb":{"type":"integer","nullable":true}},"type":"object","required":["volumes","ssh_keys"],"title":"LaunchSpecificationModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation/{reservation_fid}/extend":{"post":{"tags":["reservations"],"summary":"Extend Reservation","description":"Extend a reservation to the requested time.","operationId":"extend_reservation_v2_reservation__reservation_fid__extend_post","parameters":[{"name":"reservation_fid","in":"path","required":true,"schema":{"type":"string","title":"Reservation Fid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtendReservationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Update Reservation

> Update a reservation's pause/resume status and/or volumes

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"UpdateReservationRequest":{"properties":{"paused":{"type":"boolean","nullable":true},"volumes":{"items":{"type":"string"},"type":"array","nullable":true}},"type":"object","title":"UpdateReservationRequest"},"ReservationModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_by":{"type":"string","title":"Created By"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"instance_quantity":{"type":"integer","title":"Instance Quantity"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"launch_specification":{"$ref":"#/components/schemas/LaunchSpecificationModel"},"status":{"type":"string","enum":["Pending","Active","Paused","Canceled","Ended"],"title":"Status"},"start_time":{"type":"string","format":"datetime","title":"Start Time"},"end_time":{"type":"string","format":"datetime","title":"End Time"},"total_price":{"type":"string","title":"Total Price"},"unit_price":{"type":"string","title":"Unit Price"}},"type":"object","required":["fid","name","project","created_by","created_at","instance_quantity","instance_type","instances","launch_specification","status","start_time","end_time","total_price","unit_price"],"title":"ReservationModel"},"LaunchSpecificationModel":{"properties":{"volumes":{"items":{"type":"string"},"type":"array","title":"Volumes","description":"List of volume FIDs"},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys","description":"List of SSH key FIDs"},"startup_script":{"type":"string","nullable":true},"kubernetes_cluster":{"type":"string","nullable":true},"image_version":{"type":"string","nullable":true},"memory_gb":{"type":"integer","nullable":true}},"type":"object","required":["volumes","ssh_keys"],"title":"LaunchSpecificationModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation/{reservation_fid}":{"patch":{"tags":["reservations"],"summary":"Update Reservation","description":"Update a reservation's pause/resume status and/or volumes","operationId":"update_reservation_v2_reservation__reservation_fid__patch","parameters":[{"name":"reservation_fid","in":"path","required":true,"schema":{"type":"string","title":"Reservation Fid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReservationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Terminate Instance

> Remove and permanently delete instances from this reservation.\
> \
> You will receive a credit based on your early termination buyback price\
> associated with this reservation and the time remaining in the\
> reservation.\
> \
> This endpoint does a best effort to termiante all instances, but it can\
> fail to do so for some instances. If you receive a 207, then please see\
> the response for details.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"TerminateInstanceRequest":{"properties":{"instances":{"items":{"type":"string"},"type":"array","minItems":1,"uniqueItems":true,"title":"Instances"},"reduce_capacity":{"type":"boolean","const":true,"title":"Reduce Capacity"}},"type":"object","required":["instances","reduce_capacity"],"title":"TerminateInstanceRequest"},"TerminateInstanceResponsePartialSuccess":{"properties":{"terminated_instances":{"items":{"type":"string"},"type":"array","uniqueItems":true,"title":"Terminated Instances"}},"type":"object","required":["terminated_instances"],"title":"TerminateInstanceResponsePartialSuccess"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation/{reservation_fid}/terminate-instances":{"post":{"tags":["reservations"],"summary":"Terminate Instance","description":"Remove and permanently delete instances from this reservation.\n\nYou will receive a credit based on your early termination buyback price\nassociated with this reservation and the time remaining in the\nreservation.\n\nThis endpoint does a best effort to termiante all instances, but it can\nfail to do so for some instances. If you receive a 207, then please see\nthe response for details.","operationId":"terminate_instance_v2_reservation__reservation_fid__terminate_instances_post","parameters":[{"name":"reservation_fid","in":"path","required":true,"schema":{"type":"string","title":"Reservation Fid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerminateInstanceRequest"}}}},"responses":{"200":{"description":"Successfully terminated all instances.","content":{"application/json":{"schema":{}}}},"207":{"description":"Failed to terminate some instances. See response for details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerminateInstanceResponsePartialSuccess"}}}},"400":{"description":"The reservation was already ended."},"404":{"description":"Either the reservation or one of the instances could not be found."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"502":{"description":"No instance was able to be stopped due to an internal error."}}}}}}
```

## Get Reservation History

> Get the activity history for a reservation.\
> \
> Returns a chronological list of order-level status changes (Placed, Active,\
> Paused, Resumed, Canceled, Ended) interleaved with aggregated instance-level\
> status events (instances running, stopped, error) bucketed into 60-second\
> windows so burst transitions appear as a single entry.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"ReservationHistoryResponse":{"properties":{"reservation_fid":{"type":"string","title":"Reservation Fid"},"events":{"items":{"$ref":"#/components/schemas/ReservationHistoryEventModel"},"type":"array","title":"Events","description":"List of historical events for this reservation, ordered by time"}},"type":"object","required":["reservation_fid","events"],"title":"ReservationHistoryResponse","description":"Response model for reservation history."},"ReservationHistoryEventModel":{"properties":{"timestamp":{"type":"string","format":"datetime","title":"Timestamp","description":"When the event occurred"},"event_type":{"type":"string","enum":["Placed","Active","Paused","Resumed","Canceled","Ended","Terms Set","Terms Changed"],"title":"Event Type"},"user_id":{"type":"string","nullable":true},"unit_price_cents":{"type":"integer","nullable":true},"pause_credit_cents":{"type":"integer","nullable":true},"return_credit_cents":{"type":"integer","nullable":true}},"type":"object","required":["timestamp","event_type"],"title":"ReservationHistoryEventModel","description":"A single event in the history of a reservation."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation/{reservation_fid}/history":{"get":{"tags":["reservations"],"summary":"Get Reservation History","description":"Get the activity history for a reservation.\n\nReturns a chronological list of order-level status changes (Placed, Active,\nPaused, Resumed, Canceled, Ended) interleaved with aggregated instance-level\nstatus events (instances running, stopped, error) bucketed into 60-second\nwindows so burst transitions appear as a single entry.","operationId":"get_reservation_history_v2_reservation__reservation_fid__history_get","parameters":[{"name":"reservation_fid","in":"path","required":true,"schema":{"type":"string","title":"Reservation Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Reservation Usage

> Get usage breakdown for a flex reservation.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"ReservationUsageResponse":{"properties":{"reservation":{"$ref":"#/components/schemas/ReservationInfoModel"},"summary":{"$ref":"#/components/schemas/UsageSummaryModel"},"grants":{"items":{"$ref":"#/components/schemas/GrantUsageModel"},"type":"array","title":"Grants"},"pricing_events":{"items":{"$ref":"#/components/schemas/PricingEventModel"},"type":"array","title":"Pricing Events"},"reservation_events":{"items":{"$ref":"#/components/schemas/ReservationLevelEventModel"},"type":"array","title":"Reservation Events"}},"type":"object","required":["reservation","summary","grants","pricing_events","reservation_events"],"title":"ReservationUsageResponse"},"ReservationInfoModel":{"properties":{"fid":{"type":"string","title":"Fid"},"order_name":{"type":"string","title":"Order Name"},"start_date":{"type":"string","format":"datetime","title":"Start Date"},"end_date":{"type":"string","format":"datetime","title":"End Date"},"status":{"type":"string","enum":["Open","Allocated","Preempting","Terminated","Paused"]},"committed_cost_cents":{"type":"integer","title":"Committed Cost Cents"}},"type":"object","required":["fid","order_name","start_date","end_date","status","committed_cost_cents"],"title":"ReservationInfoModel"},"UsageSummaryModel":{"properties":{"committed_cost_cents":{"type":"integer","title":"Committed Cost Cents"},"flex_use_credits_cents":{"type":"integer","title":"Flex Use Credits Cents"},"early_termination_credits_cents":{"type":"integer","title":"Early Termination Credits Cents"},"net_cost_cents":{"type":"integer","title":"Net Cost Cents"},"reserved_instance_hours":{"type":"string","format":"duration","title":"Reserved Instance Hours"},"active_instance_hours":{"type":"string","format":"duration","title":"Active Instance Hours"},"idle_instance_hours":{"type":"string","format":"duration","title":"Idle Instance Hours"},"as_of":{"type":"string","format":"datetime","title":"As Of"}},"type":"object","required":["committed_cost_cents","flex_use_credits_cents","early_termination_credits_cents","net_cost_cents","reserved_instance_hours","active_instance_hours","idle_instance_hours","as_of"],"title":"UsageSummaryModel"},"GrantUsageModel":{"properties":{"fid":{"type":"string","title":"Fid"},"starts_at":{"type":"string","format":"datetime","title":"Starts At"},"ends_at":{"type":"string","format":"datetime","title":"Ends At"},"quantity":{"type":"integer","title":"Quantity"},"unit_price":{"type":"integer","title":"Unit Price"},"price_credit":{"type":"integer","title":"Price Credit"},"return_credit":{"type":"integer","title":"Return Credit"}},"type":"object","required":["fid","starts_at","ends_at","quantity","unit_price","price_credit","return_credit"],"title":"GrantUsageModel"},"PricingEventModel":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"occurred_at":{"type":"string","format":"datetime","title":"Occurred At"},"instance_fid":{"type":"string","title":"Instance Fid"},"instance_name":{"type":"string","title":"Instance Name"},"instance_status":{"type":"string","enum":["STATUS_NEW","STATUS_CONFIRMED","STATUS_INITIALIZING","STATUS_STARTING","STATUS_RUNNING","STATUS_STOPPING","STATUS_TERMINATED","STATUS_RELOCATING","STATUS_PREEMPTING","STATUS_PREEMPTED","STATUS_REPLACED","STATUS_PAUSED","STATUS_ERROR"],"title":"Instance Status"}},"type":"object","required":["id","occurred_at","instance_fid","instance_name","instance_status"],"title":"PricingEventModel"},"ReservationLevelEventModel":{"properties":{"occurred_at":{"type":"string","format":"datetime","title":"Occurred At"},"event_type":{"type":"string","enum":["Started","Paused","Extended"],"title":"Event Type"},"reservation_name":{"type":"string","title":"Reservation Name"}},"type":"object","required":["occurred_at","event_type","reservation_name"],"title":"ReservationLevelEventModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/reservation/{reservation_fid}/usage":{"get":{"tags":["reservations"],"summary":"Get Reservation Usage","description":"Get usage breakdown for a flex reservation.","operationId":"get_reservation_usage_v2_reservation__reservation_fid__usage_get","parameters":[{"name":"reservation_fid","in":"path","required":true,"schema":{"type":"string","title":"Reservation Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationUsageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Volumes

## Get Volumes

> Retrieves all storage volumes for a specific project.\
> \
> Args:\
> &#x20;   user\_info: Authenticated user information.\
> &#x20;   project: Identifier of the project to list volumes for.\
> &#x20;   region: Optional region filter.\
> &#x20;   include\_deleted: When True, includes soft-deleted volumes in the\
> &#x20;       response. Deleted volumes have a non-null \`\`deleted\_at\`\` field.\
> &#x20;       Defaults to False.\
> \
> Returns:\
> &#x20;   list\[VolumeModel]: A list of volume models belonging to the project.\
> \
> Raises:\
> &#x20;   HTTPException: If project is missing or user is not authorized.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"VolumeModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"region":{"type":"string","title":"Region"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deleted_at":{"type":"string","format":"datetime","nullable":true},"capacity_gb":{"type":"integer","title":"Capacity Gb"},"project":{"type":"string","title":"Project"},"interface":{"type":"string","enum":["Block","File"],"title":"Interface"},"bids":{"items":{"type":"string"},"type":"array","title":"Bids"},"reservations":{"items":{"type":"string"},"type":"array","title":"Reservations"},"attachments":{"additionalProperties":{"type":"string"},"type":"object","title":"Attachments"}},"type":"object","required":["fid","name","region","created_at","deleted_at","capacity_gb","project","interface","bids","reservations","attachments"],"title":"VolumeModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/volumes":{"get":{"tags":["volumes"],"summary":"Get Volumes","description":"Retrieves all storage volumes for a specific project.\n\nArgs:\n    user_info: Authenticated user information.\n    project: Identifier of the project to list volumes for.\n    region: Optional region filter.\n    include_deleted: When True, includes soft-deleted volumes in the\n        response. Deleted volumes have a non-null ``deleted_at`` field.\n        Defaults to False.\n\nReturns:\n    list[VolumeModel]: A list of volume models belonging to the project.\n\nRaises:\n    HTTPException: If project is missing or user is not authorized.","operationId":"get_volumes_v2_volumes_get","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}},{"name":"region","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"include_deleted","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Deleted"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VolumeModel"},"title":"Response Get Volumes V2 Volumes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Create Volume

> Creates a new storage volume.\
> \
> Args:\
> &#x20;   user\_info: Authenticated user information.\
> &#x20;   body: Request body containing volume creation details (size, region, etc).\
> \
> Returns:\
> &#x20;   VolumeModel: The created volume model.\
> \
> Raises:\
> &#x20;   HTTPException: If user unauthorized or creation fails.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"CreateVolumeRequest":{"properties":{"name":{"type":"string","maxLength":64,"pattern":"^[a-z]([-a-z0-9]*[a-z0-9])?$","title":"Name"},"project":{"type":"string","title":"Project"},"disk_interface":{"type":"string","enum":["Block","File"],"title":"Disk Interface"},"region":{"type":"string","title":"Region"},"size_gb":{"title":"Size Gb","gt":{"_unit":"b","_value":0},"lt":{"_unit":"pib","_value":2}}},"type":"object","required":["name","project","disk_interface","region","size_gb"],"title":"CreateVolumeRequest","description":"Request model for creating a new storage volume."},"VolumeModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"region":{"type":"string","title":"Region"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deleted_at":{"type":"string","format":"datetime","nullable":true},"capacity_gb":{"type":"integer","title":"Capacity Gb"},"project":{"type":"string","title":"Project"},"interface":{"type":"string","enum":["Block","File"],"title":"Interface"},"bids":{"items":{"type":"string"},"type":"array","title":"Bids"},"reservations":{"items":{"type":"string"},"type":"array","title":"Reservations"},"attachments":{"additionalProperties":{"type":"string"},"type":"object","title":"Attachments"}},"type":"object","required":["fid","name","region","created_at","deleted_at","capacity_gb","project","interface","bids","reservations","attachments"],"title":"VolumeModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/volumes":{"post":{"tags":["volumes"],"summary":"Create Volume","description":"Creates a new storage volume.\n\nArgs:\n    user_info: Authenticated user information.\n    body: Request body containing volume creation details (size, region, etc).\n\nReturns:\n    VolumeModel: The created volume model.\n\nRaises:\n    HTTPException: If user unauthorized or creation fails.","operationId":"create_volume_v2_volumes_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVolumeRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VolumeModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Delete Volume

> Deletes a storage volume.\
> \
> Permanently removes a volume. The volume must not be currently in use/attached.\
> \
> Args:\
> &#x20;   user\_info: Authenticated user information.\
> &#x20;   volume\_fid: Identifier of the volume to delete.\
> \
> Raises:\
> &#x20;   HTTPException: If volume not found, user unauthorized, or volume is in use.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/volumes/{volume_fid}":{"delete":{"tags":["volumes"],"summary":"Delete Volume","description":"Deletes a storage volume.\n\nPermanently removes a volume. The volume must not be currently in use/attached.\n\nArgs:\n    user_info: Authenticated user information.\n    volume_fid: Identifier of the volume to delete.\n\nRaises:\n    HTTPException: If volume not found, user unauthorized, or volume is in use.","operationId":"delete_volume_v2_volumes__volume_fid__delete","parameters":[{"name":"volume_fid","in":"path","required":true,"schema":{"type":"string","title":"Volume Fid"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Update Volume

> Updates a storage volume's mutable properties (e.g., name).\
> \
> Args:\
> &#x20;   user\_info: Authenticated user information.\
> &#x20;   volume\_fid: Identifier of the volume to update.\
> &#x20;   body: Request body containing updated fields.\
> \
> Returns:\
> &#x20;   VolumeModel: The updated volume model.\
> \
> Raises:\
> &#x20;   HTTPException: If volume not found or user unauthorized.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"UpdateVolumeRequest":{"properties":{"name":{"type":"string","maxLength":64,"pattern":"^[a-z]([-a-z0-9]*[a-z0-9])?$","title":"Name"}},"type":"object","required":["name"],"title":"UpdateVolumeRequest","description":"Request model for updating an existing storage volume.\n\nAttributes:\n    name: New name for the volume. Must follow naming conventions."},"VolumeModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"region":{"type":"string","title":"Region"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"deleted_at":{"type":"string","format":"datetime","nullable":true},"capacity_gb":{"type":"integer","title":"Capacity Gb"},"project":{"type":"string","title":"Project"},"interface":{"type":"string","enum":["Block","File"],"title":"Interface"},"bids":{"items":{"type":"string"},"type":"array","title":"Bids"},"reservations":{"items":{"type":"string"},"type":"array","title":"Reservations"},"attachments":{"additionalProperties":{"type":"string"},"type":"object","title":"Attachments"}},"type":"object","required":["fid","name","region","created_at","deleted_at","capacity_gb","project","interface","bids","reservations","attachments"],"title":"VolumeModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/volumes/{volume_fid}":{"patch":{"tags":["volumes"],"summary":"Update Volume","description":"Updates a storage volume's mutable properties (e.g., name).\n\nArgs:\n    user_info: Authenticated user information.\n    volume_fid: Identifier of the volume to update.\n    body: Request body containing updated fields.\n\nReturns:\n    VolumeModel: The updated volume model.\n\nRaises:\n    HTTPException: If volume not found or user unauthorized.","operationId":"update_volume_v2_volumes__volume_fid__patch","parameters":[{"name":"volume_fid","in":"path","required":true,"schema":{"type":"string","title":"Volume Fid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVolumeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VolumeModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Pricing

## Get Current Prices V2

> Get current pricing information for an instance type.\
> \
> Returns the current spot price, reserved price, and minimum price for a given\
> instance type, optionally filtered by region.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"CurrentPricesResponse":{"properties":{"spot_price_cents":{"type":"integer","nullable":true},"reserved_price_cents":{"type":"integer","nullable":true},"minimum_price_cents":{"type":"integer","nullable":true},"lowest_allocated_bid_cents":{"type":"integer","nullable":true},"dynamic_win_price_cents":{"type":"integer","nullable":true},"available_capacity":{"type":"integer","nullable":true},"total_capacity":{"type":"integer","nullable":true}},"type":"object","title":"CurrentPricesResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/pricing/current":{"get":{"tags":["pricing"],"summary":"Get Current Prices V2","description":"Get current pricing information for an instance type.\n\nReturns the current spot price, reserved price, and minimum price for a given\ninstance type, optionally filtered by region.","operationId":"get_current_prices_v2_v2_pricing_current_get","parameters":[{"name":"instance_type","in":"query","required":true,"schema":{"type":"string","title":"Instance Type"}},{"name":"region","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"instance_quantity","in":"query","required":false,"schema":{"type":"integer","maximum":256,"minimum":1,"default":1,"title":"Instance Quantity"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentPricesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Historical Prices V2

> Get historical pricing information for instance types.\
> \
> Returns historical spot and reserved prices over time for instance types,\
> optionally filtered by specific instance type and region.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"HistoricalPricesResponseModel":{"properties":{"series":{"items":{"$ref":"#/components/schemas/HistoricalPriceSeriesModel"},"type":"array","title":"Series"},"complete":{"type":"boolean","title":"Complete","default":true}},"type":"object","required":["series"],"title":"HistoricalPricesResponseModel","description":"Response model for historical pricing data."},"HistoricalPriceSeriesModel":{"properties":{"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","title":"Region"},"timestamps":{"items":{"type":"string","format":"datetime"},"type":"array","title":"Timestamps"},"spot_prices":{"items":{"type":"string"},"type":"array","title":"Spot Prices"},"reserved_prices":{"items":{"type":"string"},"type":"array","title":"Reserved Prices"},"region_disabled":{"type":"boolean","title":"Region Disabled","default":false}},"type":"object","required":["instance_type","region","timestamps","spot_prices","reserved_prices"],"title":"HistoricalPriceSeriesModel","description":"A single time-series of prices for one instance type in one region."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/pricing/history":{"get":{"tags":["pricing"],"summary":"Get Historical Prices V2","description":"Get historical pricing information for instance types.\n\nReturns historical spot and reserved prices over time for instance types,\noptionally filtered by specific instance type and region.","operationId":"get_historical_prices_v2_v2_pricing_history_get","parameters":[{"name":"instance_types","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"region","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"num_samples","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":-1,"default":100,"title":"Num Samples"}},{"name":"start_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}},{"name":"end_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoricalPricesResponseModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Cpu

## Get Cpu Instance Types

> Lists CPU-only instance types.\
> \
> GET /v2/instance-types only returns instance types with a row in the\
> auctions table, which CPU-only types deliberately don't have (adding\
> one would make them spot-biddable). This is the discovery endpoint for\
> the instance\_type FID POST /v2/cpu/instances requires.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"InstanceTypeModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"num_cpus":{"type":"integer","title":"Num Cpus"},"cpu_type":{"type":"string","title":"Cpu Type"},"ram_gb":{"type":"integer","title":"Ram Gb"},"num_gpus":{"type":"integer","title":"Num Gpus"},"gpu_type":{"type":"string","title":"Gpu Type"},"gpu_memory_gb":{"type":"integer","title":"Gpu Memory Gb"},"gpu_socket":{"type":"string","title":"Gpu Socket"},"local_storage_gb":{"type":"integer","title":"Local Storage Gb"},"network_type":{"type":"string","nullable":true},"ib_count":{"type":"integer","title":"Ib Count"},"bridge_count":{"type":"integer","title":"Bridge Count"},"hourly_price":{"type":"number","title":"Hourly Price"}},"type":"object","required":["fid","name","num_cpus","cpu_type","ram_gb","num_gpus","gpu_type","gpu_memory_gb","gpu_socket","local_storage_gb","ib_count","bridge_count","hourly_price"],"title":"InstanceTypeModel"}}},"paths":{"/v2/cpu/instance-types":{"get":{"tags":["cpu"],"summary":"Get Cpu Instance Types","description":"Lists CPU-only instance types.\n\nGET /v2/instance-types only returns instance types with a row in the\nauctions table, which CPU-only types deliberately don't have (adding\none would make them spot-biddable). This is the discovery endpoint for\nthe instance_type FID POST /v2/cpu/instances requires.","operationId":"get_cpu_instance_types_v2_cpu_instance_types_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/InstanceTypeModel"},"type":"array","title":"Response Get Cpu Instance Types V2 Cpu Instance Types Get"}}}}}}}}}
```

## Get Cpu Regions

> Lists regions where CPU VMs are available (CPU\_VMS\_ENABLED on).\
> \
> Discovery endpoint for the region POST /v2/cpu/instances requires - the\
> console offers only these, so a user never picks a region the create\
> would reject. Empty when no cluster is opted in.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"RegionDTO":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"block_storage_enabled":{"type":"boolean","title":"Block Storage Enabled"},"fileshare_storage_enabled":{"type":"boolean","title":"Fileshare Storage Enabled"},"k8s_enabled":{"type":"boolean","title":"K8S Enabled"},"max_volume_size_tb":{"type":"integer","title":"Max Volume Size Tb","default":32},"max_volume_name_length":{"type":"integer","title":"Max Volume Name Length","default":64}},"type":"object","required":["id","name","block_storage_enabled","fileshare_storage_enabled","k8s_enabled"],"title":"RegionDTO"}}},"paths":{"/v2/cpu/regions":{"get":{"tags":["cpu"],"summary":"Get Cpu Regions","description":"Lists regions where CPU VMs are available (CPU_VMS_ENABLED on).\n\nDiscovery endpoint for the region POST /v2/cpu/instances requires - the\nconsole offers only these, so a user never picks a region the create\nwould reject. Empty when no cluster is opted in.","operationId":"get_cpu_regions_v2_cpu_regions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/RegionDTO"},"type":"array","title":"Response Get Cpu Regions V2 Cpu Regions Get"}}}}}}}}}
```

## Create Cpu Instance

> Creates and instantly launches a self-serve CPU-only instance.\
> \
> Unlike GPU reservations/spot bids, this is synchronous: the instance is\
> launched in the same request, with no bid price and no auction\
> involvement.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"CreateCpuInstanceRequest":{"properties":{"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","title":"Region"},"volumes":{"items":{"type":"string"},"type":"array","title":"Volumes","default":[]},"ssh_keys":{"items":{"type":"string"},"type":"array","nullable":true},"image_version":{"type":"string","nullable":true}},"additionalProperties":false,"type":"object","required":["name","project","instance_type","region"],"title":"CreateCpuInstanceRequest"},"InstanceModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"created_by":{"type":"string","title":"Created By"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"bid":{"type":"string","nullable":true},"reservation":{"type":"string","nullable":true},"ssh_destination":{"type":"string","nullable":true},"private_ip":{"type":"string","nullable":true},"status":{"type":"string","enum":["STATUS_NEW","STATUS_CONFIRMED","STATUS_INITIALIZING","STATUS_STARTING","STATUS_RUNNING","STATUS_STOPPING","STATUS_TERMINATED","STATUS_RELOCATING","STATUS_PREEMPTING","STATUS_PREEMPTED","STATUS_REPLACED","STATUS_PAUSED","STATUS_ERROR"],"title":"Status"}},"type":"object","required":["fid","name","project","created_at","created_by","instance_type","status"],"title":"InstanceModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/cpu/instances":{"post":{"tags":["cpu"],"summary":"Create Cpu Instance","description":"Creates and instantly launches a self-serve CPU-only instance.\n\nUnlike GPU reservations/spot bids, this is synchronous: the instance is\nlaunched in the same request, with no bid price and no auction\ninvolvement.","operationId":"create_cpu_instance_v2_cpu_instances_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCpuInstanceRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Terminate Cpu Instance

> Terminates a CPU-only instance.\
> \
> Stops the underlying VM, closes the backing order/allocation, and\
> soft-deletes the managed customer cluster.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/cpu/instances/{instance_fid}":{"delete":{"tags":["cpu"],"summary":"Terminate Cpu Instance","description":"Terminates a CPU-only instance.\n\nStops the underlying VM, closes the backing order/allocation, and\nsoft-deletes the managed customer cluster.","operationId":"terminate_cpu_instance_v2_cpu_instances__instance_fid__delete","parameters":[{"name":"instance_fid","in":"path","required":true,"schema":{"type":"string","title":"Instance Fid"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Kubernetes Clusters

## Get Kubernetes Clusters

> Get all Kubernetes clusters for a project

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"KubernetesClusterModel":{"properties":{"fid":{"type":"string","title":"Fid"},"project":{"type":"string","title":"Project"},"name":{"type":"string","title":"Name"},"region":{"type":"string","title":"Region"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"kube_host":{"type":"string","nullable":true},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys"},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"join_command":{"type":"string","nullable":true},"status":{"type":"string","enum":["Pending","Available","Terminated"],"title":"Status"},"deleted_at":{"type":"string","format":"datetime","nullable":true},"k8s_version":{"type":"string","title":"K8S Version"},"user_fid":{"type":"string","nullable":true}},"type":"object","required":["fid","project","name","region","created_at","ssh_keys","instances","status","k8s_version"],"title":"KubernetesClusterModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/kubernetes/clusters":{"get":{"tags":["kubernetes clusters"],"summary":"Get Kubernetes Clusters","description":"Get all Kubernetes clusters for a project","operationId":"get_kubernetes_clusters_v2_kubernetes_clusters_get","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/KubernetesClusterModel"},"title":"Response Get Kubernetes Clusters V2 Kubernetes Clusters Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Create Kubernetes Cluster

> Create a new Kubernetes cluster

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"CreateKubernetesClusterRequest":{"properties":{"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"region":{"type":"string","title":"Region"},"ssh_keys":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Ssh Keys"},"instance_type":{"type":"string","title":"Instance Type"},"k8s_version":{"type":"string","enum":["1.34","1.29"],"title":"K8S Version","default":"1.34"},"image_version":{"type":"string","nullable":true}},"type":"object","required":["name","project","region","ssh_keys","instance_type"],"title":"CreateKubernetesClusterRequest"},"KubernetesClusterModel":{"properties":{"fid":{"type":"string","title":"Fid"},"project":{"type":"string","title":"Project"},"name":{"type":"string","title":"Name"},"region":{"type":"string","title":"Region"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"kube_host":{"type":"string","nullable":true},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys"},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"join_command":{"type":"string","nullable":true},"status":{"type":"string","enum":["Pending","Available","Terminated"],"title":"Status"},"deleted_at":{"type":"string","format":"datetime","nullable":true},"k8s_version":{"type":"string","title":"K8S Version"},"user_fid":{"type":"string","nullable":true}},"type":"object","required":["fid","project","name","region","created_at","ssh_keys","instances","status","k8s_version"],"title":"KubernetesClusterModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/kubernetes/clusters":{"post":{"tags":["kubernetes clusters"],"summary":"Create Kubernetes Cluster","description":"Create a new Kubernetes cluster","operationId":"create_kubernetes_cluster_v2_kubernetes_clusters_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateKubernetesClusterRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KubernetesClusterModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Kubernetes Cluster

> Get a specific Kubernetes cluster

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"KubernetesClusterModel":{"properties":{"fid":{"type":"string","title":"Fid"},"project":{"type":"string","title":"Project"},"name":{"type":"string","title":"Name"},"region":{"type":"string","title":"Region"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"kube_host":{"type":"string","nullable":true},"ssh_keys":{"items":{"type":"string"},"type":"array","title":"Ssh Keys"},"instances":{"items":{"type":"string"},"type":"array","title":"Instances"},"join_command":{"type":"string","nullable":true},"status":{"type":"string","enum":["Pending","Available","Terminated"],"title":"Status"},"deleted_at":{"type":"string","format":"datetime","nullable":true},"k8s_version":{"type":"string","title":"K8S Version"},"user_fid":{"type":"string","nullable":true}},"type":"object","required":["fid","project","name","region","created_at","ssh_keys","instances","status","k8s_version"],"title":"KubernetesClusterModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/kubernetes/clusters/{cluster_fid}":{"get":{"tags":["kubernetes clusters"],"summary":"Get Kubernetes Cluster","description":"Get a specific Kubernetes cluster","operationId":"get_kubernetes_cluster_v2_kubernetes_clusters__cluster_fid__get","parameters":[{"name":"cluster_fid","in":"path","required":true,"schema":{"type":"string","title":"Cluster Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KubernetesClusterModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Delete Kubernetes Cluster

> Delete a Kubernetes cluster

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/kubernetes/clusters/{cluster_fid}":{"delete":{"tags":["kubernetes clusters"],"summary":"Delete Kubernetes Cluster","description":"Delete a Kubernetes cluster","operationId":"delete_kubernetes_cluster_v2_kubernetes_clusters__cluster_fid__delete","parameters":[{"name":"cluster_fid","in":"path","required":true,"schema":{"type":"string","title":"Cluster Fid"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Instances

## Get Instances

> Get all instances for a project

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"SortDirection":{"type":"string","enum":["asc","desc"]},"GetInstancesResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/InstanceModel"},"type":"array","title":"Data"},"next_cursor":{"type":"string","nullable":true}},"type":"object","required":["data"],"title":"GetInstancesResponse"},"InstanceModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"project":{"type":"string","title":"Project"},"created_at":{"type":"string","format":"datetime","title":"Created At"},"created_by":{"type":"string","title":"Created By"},"instance_type":{"type":"string","title":"Instance Type"},"region":{"type":"string","nullable":true},"bid":{"type":"string","nullable":true},"reservation":{"type":"string","nullable":true},"ssh_destination":{"type":"string","nullable":true},"private_ip":{"type":"string","nullable":true},"status":{"type":"string","enum":["STATUS_NEW","STATUS_CONFIRMED","STATUS_INITIALIZING","STATUS_STARTING","STATUS_RUNNING","STATUS_STOPPING","STATUS_TERMINATED","STATUS_RELOCATING","STATUS_PREEMPTING","STATUS_PREEMPTED","STATUS_REPLACED","STATUS_PAUSED","STATUS_ERROR"],"title":"Status"}},"type":"object","required":["fid","name","project","created_at","created_by","instance_type","status"],"title":"InstanceModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/instances":{"get":{"tags":["instances","instances"],"summary":"Get Instances","description":"Get all instances for a project","operationId":"get_instances_v2_instances_get","parameters":[{"name":"next_cursor","in":"query","required":false,"schema":{"nullable":true}},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["created_at","instance_status","instance_type_fid"],"type":"string","nullable":true}},{"name":"sort_dir","in":"query","required":false,"schema":{"$ref":"#/components/schemas/SortDirection","nullable":true}},{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}},{"name":"instance_type","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"region","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"status_in","in":"query","required":false,"schema":{"type":"array","items":{"enum":["STATUS_NEW","STATUS_CONFIRMED","STATUS_INITIALIZING","STATUS_STARTING","STATUS_RUNNING","STATUS_STOPPING","STATUS_TERMINATED","STATUS_RELOCATING","STATUS_PREEMPTING","STATUS_PREEMPTED","STATUS_REPLACED","STATUS_PAUSED","STATUS_ERROR"],"type":"string"},"description":"Comma-separated list of instance statuses","nullable":true}},{"name":"order_type_in","in":"query","required":false,"schema":{"type":"array","items":{"enum":["Bid","Reservation"],"type":"string"},"description":"Comma-separated list of order types","nullable":true}},{"name":"bid_fid_in","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"description":"Comma-separated list of bid FIDs","nullable":true}},{"name":"reservation_fid_in","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"description":"Comma-separated list of reservation FIDs","nullable":true}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"nullable":true}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetInstancesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Put Instance Status

> Trigger a status change for a set of instances.\
> \
> This endpoint supports batch start and pause requests for instances. The\
> request accepts a set of instance FIDs and a target action\
> (\`STATUS\_RUNNING\` or \`STATUS\_PAUSED\`).\
> \
> The response always includes an entry for every requested instance, keyed by\
> instance FID, with that instance's current status after processing.\
> \- When an instance is successfully starting, its status is \`STATUS\_CONFIRMED\`.\
> \- When an instance is successfully stopping, its status is \`STATUS\_STOPPING\`.\
> \- If an instance cannot be stopped, its prior status is returned unchanged.\
> \
> Paused instances which are associated with a reservation will accrue a\
> credit based on the flexible usage buyback price on that reservation.\
> \
> Notes:\
> \- Only reserved instances are supported at this time.\
> \- This API is asynchronous. You can check the status of the instance with the\
> &#x20; Get Status api.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"PatchInstanceStatusRequest":{"properties":{"instances":{"items":{"type":"string"},"type":"array","uniqueItems":true,"title":"Instances"},"status":{"type":"string","enum":["STATUS_RUNNING","STATUS_PAUSED"],"title":"Status"}},"type":"object","required":["instances","status"],"title":"PatchInstanceStatusRequest"},"PatchInstanceStatusResponse":{"properties":{"instances":{"additionalProperties":{"type":"string","enum":["STATUS_NEW","STATUS_CONFIRMED","STATUS_INITIALIZING","STATUS_STARTING","STATUS_RUNNING","STATUS_STOPPING","STATUS_TERMINATED","STATUS_RELOCATING","STATUS_PREEMPTING","STATUS_PREEMPTED","STATUS_REPLACED","STATUS_PAUSED","STATUS_ERROR"]},"propertyNames":{},"type":"object","title":"Instances"}},"type":"object","required":["instances"],"title":"PatchInstanceStatusResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/instances":{"patch":{"tags":["instances","instances"],"summary":"Put Instance Status","description":"Trigger a status change for a set of instances.\n\nThis endpoint supports batch start and pause requests for instances. The\nrequest accepts a set of instance FIDs and a target action\n(`STATUS_RUNNING` or `STATUS_PAUSED`).\n\nThe response always includes an entry for every requested instance, keyed by\ninstance FID, with that instance's current status after processing.\n- When an instance is successfully starting, its status is `STATUS_CONFIRMED`.\n- When an instance is successfully stopping, its status is `STATUS_STOPPING`.\n- If an instance cannot be stopped, its prior status is returned unchanged.\n\nPaused instances which are associated with a reservation will accrue a\ncredit based on the flexible usage buyback price on that reservation.\n\nNotes:\n- Only reserved instances are supported at this time.\n- This API is asynchronous. You can check the status of the instance with the\n  Get Status api.","operationId":"put_instance_status_v2_instances_patch","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchInstanceStatusRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchInstanceStatusResponse"}}}},"404":{"description":"One of the provided instances did not exist."},"409":{"description":"One or more of the instances is not yet ready for this operation."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"501":{"description":"Spot bids are not yet supported."}}}}}}
```

## Get Instance Status

> Get the status of a specific instance by its ID.\
> Supports authentication via mithril key or API key.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"InstanceStatusResponse":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"status":{"type":"string","enum":["STATUS_NEW","STATUS_CONFIRMED","STATUS_INITIALIZING","STATUS_STARTING","STATUS_RUNNING","STATUS_STOPPING","STATUS_TERMINATED","STATUS_RELOCATING","STATUS_PREEMPTING","STATUS_PREEMPTED","STATUS_REPLACED","STATUS_PAUSED","STATUS_ERROR"],"title":"Status"},"bid":{"type":"string","nullable":true},"reservation":{"type":"string","nullable":true},"end_time":{"type":"string","format":"datetime","nullable":true}},"type":"object","required":["fid","name","status"],"title":"InstanceStatusResponse","description":"Response model for instance status endpoint."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/instances/{instance_fid}/status":{"get":{"tags":["instances","instances"],"summary":"Get Instance Status","description":"Get the status of a specific instance by its ID.\nSupports authentication via mithril key or API key.","operationId":"get_instance_status_v2_instances__instance_fid__status_get","parameters":[{"name":"instance_fid","in":"path","required":true,"schema":{"type":"string","title":"Instance Fid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Refresh Instance Boot Disk

> Refresh (delete and recreate) the boot disk of a reserved instance.\
> \
> The instance must already be stopped: stop it first via the pause API\
> (\`PATCH /instances\` with \`STATUS\_PAUSED\`), then call this endpoint, then\
> start it again. A running instance is declined; this endpoint never\
> stops the instance itself. When \`image\_version\` is omitted the current\
> boot image is reused.\
> \
> Notes:\
> \- Only reserved (non-spot) instances are supported at this time.\
> \- This is being rolled out across all our regions.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"RefreshBootDiskRequest":{"properties":{"image_version":{"type":"string","nullable":true}},"type":"object","title":"RefreshBootDiskRequest","description":"Request body for the refresh-boot-disk endpoint.\n\nThe body is optional; when ``image_version`` is omitted the instance's\ncurrent boot image is reused."},"RefreshBootDiskResponse":{"properties":{"fid":{"type":"string","title":"Fid"},"image_version":{"type":"string","nullable":true},"status":{"type":"string","const":"REFRESHED","title":"Status"}},"type":"object","required":["fid","image_version","status"],"title":"RefreshBootDiskResponse","description":"Response model for the refresh-boot-disk endpoint."}}},"paths":{"/v2/instances/{instance_fid}/refresh-boot-disk":{"post":{"tags":["instances","instances"],"summary":"Refresh Instance Boot Disk","description":"Refresh (delete and recreate) the boot disk of a reserved instance.\n\nThe instance must already be stopped: stop it first via the pause API\n(`PATCH /instances` with `STATUS_PAUSED`), then call this endpoint, then\nstart it again. A running instance is declined; this endpoint never\nstops the instance itself. When `image_version` is omitted the current\nboot image is reused.\n\nNotes:\n- Only reserved (non-spot) instances are supported at this time.\n- This is being rolled out across all our regions.","operationId":"refresh_instance_boot_disk_v2_instances__instance_fid__refresh_boot_disk_post","parameters":[{"name":"instance_fid","in":"path","required":true,"schema":{"type":"string","title":"Instance Fid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshBootDiskRequest","nullable":true}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshBootDiskResponse"}}}},"404":{"description":"The instance does not exist."},"409":{"description":"The instance has no underlying VM to refresh."},"422":{"description":"The instance is still running, or the requested image version is invalid for the instance's region. The body carries a `reason` of INSTANCE_RUNNING or INVALID_IMAGE_VERSION."},"501":{"description":"Boot disk refresh is not supported for this instance yet (spot instances, or not yet available in this instance's region)."}}}}}}
```

## Get Instance Status History

> Get the history of a specific instance by its ID,\
> or of all instances in a bid or reservation.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"InstanceStatusHistoryResponse":{"properties":{"instances":{"items":{"$ref":"#/components/schemas/InstanceStatusHistory"},"type":"array","title":"Instances"},"next_cursor":{"type":"string","nullable":true}},"type":"object","required":["instances"],"title":"InstanceStatusHistoryResponse","description":"Response model for instance status history endpoint."},"InstanceStatusHistory":{"properties":{"instance_fid":{"type":"string","title":"Instance Fid"},"events":{"items":{"$ref":"#/components/schemas/InstanceStatusEvent"},"type":"array","title":"Events"},"bid_fid":{"type":"string","nullable":true},"reservation_fid":{"type":"string","nullable":true}},"type":"object","required":["instance_fid","events"],"title":"InstanceStatusHistory","description":"The history of an instance's status."},"InstanceStatusEvent":{"properties":{"timestamp":{"type":"string","format":"datetime","title":"Timestamp"},"status":{"type":"string","enum":["STATUS_NEW","STATUS_CONFIRMED","STATUS_INITIALIZING","STATUS_STARTING","STATUS_RUNNING","STATUS_STOPPING","STATUS_TERMINATED","STATUS_RELOCATING","STATUS_PREEMPTING","STATUS_PREEMPTED","STATUS_REPLACED","STATUS_PAUSED","STATUS_ERROR"],"title":"Status"}},"type":"object","required":["timestamp","status"],"title":"InstanceStatusEvent","description":"An event in the history of an instance's status."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/instances/status/history":{"get":{"tags":["instances","instances"],"summary":"Get Instance Status History","description":"Get the history of a specific instance by its ID,\nor of all instances in a bid or reservation.","operationId":"get_instance_status_history_v2_instances_status_history_get","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}},{"name":"instance_fid","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"bid_fid","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"reservation_fid","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"nullable":true}},{"name":"start_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}},{"name":"end_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}},{"name":"next_cursor","in":"query","required":false,"schema":{"type":"string","nullable":true}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceStatusHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Get Instance Pricing History

> Get the pricing history of a specific instance by its ID,\
> or of all instances in a bid or reservation.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"InstancePricingHistoryResponse":{"properties":{"instances":{"items":{"$ref":"#/components/schemas/InstancePricingHistory"},"type":"array","title":"Instances"},"next_cursor":{"type":"string","nullable":true}},"type":"object","required":["instances"],"title":"InstancePricingHistoryResponse","description":"Response model for instance pricing history endpoint."},"InstancePricingHistory":{"properties":{"instance_fid":{"type":"string","title":"Instance Fid"},"events":{"items":{"$ref":"#/components/schemas/InstancePricingEvent"},"type":"array","title":"Events"},"bid_fid":{"type":"string","nullable":true},"reservation_fid":{"type":"string","nullable":true}},"type":"object","required":["instance_fid","events"],"title":"InstancePricingHistory","description":"The history of an instance's pricing."},"InstancePricingEvent":{"properties":{"price_cents":{"type":"integer","title":"Price Cents"},"start_time":{"type":"string","format":"datetime","title":"Start Time"},"end_time":{"type":"string","format":"datetime","nullable":true}},"type":"object","required":["price_cents","start_time","end_time"],"title":"InstancePricingEvent","description":"A price period in the history of an instance."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/instances/pricing/history":{"get":{"tags":["instances","instances"],"summary":"Get Instance Pricing History","description":"Get the pricing history of a specific instance by its ID,\nor of all instances in a bid or reservation.","operationId":"get_instance_pricing_history_v2_instances_pricing_history_get","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}},{"name":"instance_fid","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"bid_fid","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"reservation_fid","in":"query","required":false,"schema":{"type":"string","nullable":true}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"nullable":true}},{"name":"start_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}},{"name":"end_time","in":"query","required":false,"schema":{"type":"string","format":"datetime","nullable":true}},{"name":"next_cursor","in":"query","required":false,"schema":{"type":"string","nullable":true}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstancePricingHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Instance Types

## Get Instance Types

> Get all instance types.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"InstanceTypeModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"num_cpus":{"type":"integer","title":"Num Cpus"},"cpu_type":{"type":"string","title":"Cpu Type"},"ram_gb":{"type":"integer","title":"Ram Gb"},"num_gpus":{"type":"integer","title":"Num Gpus"},"gpu_type":{"type":"string","title":"Gpu Type"},"gpu_memory_gb":{"type":"integer","title":"Gpu Memory Gb"},"gpu_socket":{"type":"string","title":"Gpu Socket"},"local_storage_gb":{"type":"integer","title":"Local Storage Gb"},"network_type":{"type":"string","nullable":true},"ib_count":{"type":"integer","title":"Ib Count"},"bridge_count":{"type":"integer","title":"Bridge Count"},"hourly_price":{"type":"number","title":"Hourly Price"}},"type":"object","required":["fid","name","num_cpus","cpu_type","ram_gb","num_gpus","gpu_type","gpu_memory_gb","gpu_socket","local_storage_gb","ib_count","bridge_count","hourly_price"],"title":"InstanceTypeModel"}}},"paths":{"/v2/instance-types":{"get":{"tags":["instance types"],"summary":"Get Instance Types","description":"Get all instance types.","operationId":"get_instance_types_v2_instance_types_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/InstanceTypeModel"},"type":"array","title":"Response Get Instance Types V2 Instance Types Get"}}}}}}}}}
```


# Projects

## Get Projects

> Get all projects a user has access to

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"ProjectModel":{"properties":{"fid":{"type":"string","title":"Fid"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","format":"datetime","title":"Created At"}},"type":"object","required":["fid","name","created_at"],"title":"ProjectModel"}}},"paths":{"/v2/projects":{"get":{"tags":["projects"],"summary":"Get Projects","description":"Get all projects a user has access to","operationId":"get_projects_v2_projects_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ProjectModel"},"type":"array","title":"Response Get Projects V2 Projects Get"}}}}}}}}}
```


# Image Versions

## Get Image Versions

> Get all available image versions;\
> the stable image version is the default unless otherwise specified.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"ImageVersionModel":{"properties":{"image_version_fid":{"type":"string","title":"Image Version Fid"},"image_version_name":{"type":"string","title":"Image Version Name"},"os":{"type":"string","title":"Os"},"kernel":{"type":"string","title":"Kernel"},"stable":{"type":"boolean","title":"Stable"},"supported_regions":{"items":{"type":"string"},"type":"array","title":"Supported Regions"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"nvidia_driver":{"type":"string","nullable":true},"cuda":{"type":"string","nullable":true},"cuda_toolkit":{"type":"string","nullable":true},"nvidia_container_toolkit":{"type":"string","nullable":true},"packages":{"type":"string","nullable":true}},"type":"object","required":["image_version_fid","image_version_name","os","kernel","stable","supported_regions"],"title":"ImageVersionModel"}}},"paths":{"/v2/image-versions":{"get":{"tags":["image versions"],"summary":"Get Image Versions","description":"Get all available image versions;\nthe stable image version is the default unless otherwise specified.","operationId":"get_image_versions_v2_image_versions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ImageVersionModel"},"type":"array","title":"Response Get Image Versions V2 Image Versions Get"}}}}}}}}}
```

## Get Mcc Image Versions

> Get MCC (CPU) image versions available for a region.\
> These are CPU-only images used for Kubernetes cluster control planes.

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"ImageVersionModel":{"properties":{"image_version_fid":{"type":"string","title":"Image Version Fid"},"image_version_name":{"type":"string","title":"Image Version Name"},"os":{"type":"string","title":"Os"},"kernel":{"type":"string","title":"Kernel"},"stable":{"type":"boolean","title":"Stable"},"supported_regions":{"items":{"type":"string"},"type":"array","title":"Supported Regions"},"deactivated_at":{"type":"string","format":"datetime","nullable":true},"nvidia_driver":{"type":"string","nullable":true},"cuda":{"type":"string","nullable":true},"cuda_toolkit":{"type":"string","nullable":true},"nvidia_container_toolkit":{"type":"string","nullable":true},"packages":{"type":"string","nullable":true}},"type":"object","required":["image_version_fid","image_version_name","os","kernel","stable","supported_regions"],"title":"ImageVersionModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/mcc-image-versions":{"get":{"tags":["image versions"],"summary":"Get Mcc Image Versions","description":"Get MCC (CPU) image versions available for a region.\nThese are CPU-only images used for Kubernetes cluster control planes.","operationId":"get_mcc_image_versions_v2_mcc_image_versions_get","parameters":[{"name":"region","in":"query","required":true,"schema":{"type":"string","title":"Region"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ImageVersionModel"},"title":"Response Get Mcc Image Versions V2 Mcc Image Versions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Quotas

## Get Quotas

> Get all quotas for a project in unified format

```json
{"openapi":"3.1.0","info":{"title":"Mithril","version":"1.0.0"},"servers":[{"url":"https://api.mithril.ai"}],"security":[{"MithrilAPIKey":[]}],"components":{"securitySchemes":{"MithrilAPIKey":{"type":"http","scheme":"bearer","bearerFormat":"fkey_<key>"}},"schemas":{"QuotaModel":{"properties":{"fid":{"type":"string","title":"Fid","description":"Unique identifier for the quota"},"project":{"type":"string","title":"Project","description":"Project FID this quota belongs to"},"instance_type":{"type":"string","nullable":true},"product_type":{"type":"string","title":"Product Type","description":"Type of product (e.g., 'Spot', 'Reservations', 'Storage')"},"total_quantity":{"type":"integer","minimum":0,"title":"Total Quantity","description":"Total quota quantity used"},"used_quantity":{"type":"integer","minimum":0,"title":"Used Quantity","description":"Total quota quantity used"},"units":{"type":"string","title":"Units","description":"Units for the quota (e.g., 'instances', 'GB')"},"name":{"type":"string","title":"Name","description":"Human-readable display name for the quota"}},"type":"object","required":["fid","project","product_type","total_quantity","used_quantity","units","name"],"title":"QuotaModel","description":"Unified quota model for all quota types (instances, storage, Kubernetes)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/v2/quotas":{"get":{"tags":["quotas"],"summary":"Get Quotas","description":"Get all quotas for a project in unified format","operationId":"get_quotas_v2_quotas_get","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string","title":"Project"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QuotaModel"},"title":"Response Get Quotas V2 Quotas Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Porting IAM roles & permissions from AWS or GCP

If you have existing IAM roles and permissions configured in AWS or GCP, you can port them to Foundry. Foundry works with customers to facilitate this directly since the process requires some bespoke work and intermediary systems.

{% hint style="success" %}
**If you would like to work with us on porting your IAM configuration, contact your account team via Slack or email <support@mlfoundry.com>.**
{% endhint %}

A high-level overview of the process:

1. **Getting permission data from AWS or GCP**: We'll need to access the user's IAM roles, policies, and permissions from their AWS or GCP accounts.\
   For AWS, we can use the AWS SDK or CLI to access IAM information. We'll need to use API calls like list\_roles, get\_role, list\_policies, get\_policy, and get\_policy\_version to collect IAM roles and policies. We may need the user's access key and secret key to authenticate to their account.\
   For GCP, we can use the Google Cloud SDK or the REST API to access IAM information. We'll use API methods like projects.getIamPolicy, roles.list, and permissions.queryTestablePermissions to collect roles and permissions. We may need the user's OAuth 2.0 credentials or service account key for authentication.
2. **Mapping AWS/GCP permissions to our application**: Once we have the IAM information, we leverage a mapping system that translates the AWS/GCP roles and permissions into corresponding roles and permissions within our application.
3. **Applying the mapped permissions**: Finally, we'll apply the mapped permissions and roles to the user's account in our application. We'll ensure that the ported IAM roles and permissions appropriately control the user's access and actions in our application.

Porting IAM roles and permissions across different platforms may not be perfect, as each platform's access control model is slightly different. We will work with you to thoroughly test and validate the permissions in our application to ensure they're working as expected.


# Access management

Mithril employs a straightforward structure for permissions to streamline management and establish clear boundaries of authority and access. While Mithril has a default nomenclature for entities and relationships, we also allow the flexibility for organizations to port existing IAM structures from AWS or GCP.&#x20;

This article details the structure of entities within Mithril.

## Entities in Mithril

There are four core entity types in Mithril:

1. Organizations
2. Projects
3. Users
4. Resources (instances, storage, keys, etc)

### Relationships between entities

* **Users** belong to an **organization**
* **Projects** belong to an **organization**
* **Compute & storage resources** belong to a single **project**
* **Users** have access to selected **projects** within their **organization**.&#x20;
* Users with access to a **project** have access to all **resources** within that **project**.

## Managing users

Administrators can new users to their organization or deactivate existing users. An user can be either an Administrator or a Member:

1. Administrators
   * Can invite new members to the organization.
   * Can modify any team member's role in the organization.
   * Have the authority to view and modify billing details, settle invoices, and initiate new projects.
   * Can add or remove team members from projects.
   * Have access to all projects within the organization.
2. Members
   * Member permissions depend on the projects they are granted access to by an administrator.
   * Within the projects they're affiliated with, members possess complete operational capabilities, such as creating, starting, stopping, and terminating instances.

### User role considerations

By design, granular access control over specific resources *within* a project is not possible. In the case that certain users should not have access to certain resources, privileged resources should be split into separate projects.

### Deactivating a user considerations

While deactivating a user is easy in Settings, note that your deactivated users may still have access to instances if they retain the SSH key. We recommend rolling SSH keys to ensure best practices with deactivated users.

## Managing projects

Projects are a workspace within an organization for users to create and access compute or storage resources. Compute and storage within a project can only be accessed if your user has access to it. Most organizations use projects to:

* Organize resources by team (e.g., Product team, Infra team)
* Organize resources by cost bucket / code (e.g., R\&D vs COGS)
* Separate production, staging, and dev environments
* Sandbox interns or contractors to limit access to sensitive environments

Projects can be renamed in the Settings modal.


# Billing

Learn how Mithril calculates your bill and charges you.

## Introduction

This overview explains how billing works for both Pay-As-You-Go (PAYG) and invoice models for our compute products. All customers who sign-up after August 3rd, 2025 will be enrolled in the PAYG model by default.

All compute and storage spend is added to your balance and billed according to the PAYG or invoice models. Billing is at the organization level — spend from all projects & users accrue to the balance.&#x20;

{% hint style="info" %}
All organizations must have a valid payment method on file to use Mithril Compute. All payment methods may have temporary authorization charges placed for verification.
{% endhint %}

### Pay-as-you-go (PAYG)

Under the PAYG model, you are automatically charged at the end of the calendar month, *and* when your balance surpasses your spend threshold. By default your spend threshold is set at $100 — when your balance in a month exceeds that threshold, we automatically charge the default payment method on file.

Mithril will automatically raise your spend threshold over time based on your usage and history of successful payments. If you’d like to increase it sooner, just contact us at <support@mithril.ai>.

{% columns %}
{% column %}
**Example 1: No spend threshold met**

Suppose your total spend on compute and inference in a calendar month is $90. At the end of the calendar month, you will automatically be charged $90 to cover your balance and be sent a detailed receipt. Since no spend threshold was met, there were no intermediate payments.
{% endcolumn %}

{% column %}
**Example 2: Spend threshold met twice**

Suppose on Day 7 of a month you surpass $100 of spend. Mithril will automatically charge your default payment method then. On Day 25, you surpass an additional $100 of spend ($200 cumulative for the month) — you will be automatically charged again. At the end of the month, you will be charged for any outstanding spend and receive a detailed receipt with your month's spend and intermediate payments.
{% endcolumn %}
{% endcolumns %}

{% hint style="warning" %}
Please ensure your preferred payment method is set as default in your billing configuration in Stripe. If your default method is a card, you will be charged a 2.9% card fee to cover processing fees.
{% endhint %}

### Invoice

For customers who meet invoicing requirements, invoices can be paid with ACH or wire transfer.  Invoices must be paid within 7 days following receipt of invoice (Net 7) and will be sent at the end of the calendar month or as otherwise specified by Mithril in writing. To convert from PAYG to invoicing, please contact <support@mithril.ai> for eligibility. Starting December 1, 2025, please note that invoices under $5,000 will be autocharged to your default payment method on file.

## Compute Billing

### Spot

Spot spend is calculated based on the actual running hours of spot compute multiplied by the market price. The market price dynamically changes based on the [Spot auction mechanics](/compute-and-storage/spot-bids/spot-auction-mechanics). We calculate at a millisecond level to ensure market price changes and your spot instance usage is captured; spend is added to your balance in realtime. We do not start charge for your instance to start — i.e., billing begins when the instance is Running — and we do not charge when your instance is paused or pre-empted.

### Reservations

Reservation spend is calculated based on the total duration of the reservation (or extension) multiplied by the reservation price. The entire cost of a reservation is added to your balance when you confirm or extend a reservation. Reservation prices are provided in the API or console as you create/extend one, or by a member of the Mithril team for long term reservations.

### Storage

Storage spend is calculated based on the disks you have provisioned at $0.08/GB/month. For example, if you create 3 disks, each 3TB, the monthly cost would be `3 disks x 3072 GB x $0.08/GB = $737.28`. This amount will be added to your balance at the end of the calendar month. If the disk is provisioned for a portion of a month, it will be prorated accordingly. You will be billed regardless of the actual usage of the disk

## Credits

You can view the remaining credits on your account under **Settings > Credits.** Credits are automatically applied to your balance.&#x20;

## Late payments

Late payments may bear interest at the rate of 1.5% per month (or the highest rate permitted by law, if less) from the payment due date until paid in full. Customer will be responsible for all reasonable expenses (including attorneys' fees) incurred by Mithil in collecting such delinquent amounts. Further, in the event of any late payment for the services, Mithril may suspend services.

## Common questions

<details>

<summary>How do I view my balance?</summary>

We are providing the ability for adminstrators to view their balance soon. Spot spend can be viewed in Instances > Spot bids by order, and Reservation spend can be viewed in Instances > Reservations. If you have any questions on your balance, reach out to <support@mithril.ai>

</details>

<details>

<summary>I am unable to use Compute due to a payment / billing error.</summary>

A valid payment method *and* billing address must be on file to spin up compute. Please ensure you have both in the Stripe Billing portal.

</details>

<details>

<summary>I'm being charged too many times in a month!</summary>

We would be happy to increase your spend thresholds — please reach out to <support@mithril.ai> to do so.

</details>


# Mithril Referral Program

Give Mithril credits, get Mithril credits 🎁 \*

Refer organizations that would benefit from early access to Mithril, and once they are accepted, they will receive $500 in credits. Once an organization you refer spends at least $2,500 on Mithril, you will also receive $500 in credits as a thank-you!

## How it works

1. Have your referral request access to Mithril by submitting our [waitlist form](http://mlfoundry.com/waitlist) and adding your organization's name in the “How did you hear about Mithril?” field.
2. Once accepted off the waitlist, your referral will receive an invitation from Mithril to create an account, which will be pre-provisioned with $500 in credits.
3. Once the referred organization spends at least $2,500, your organization will receive $500 in credits.

Thank you for your support - we can't wait to continue building with you!

{% hint style="info" %}
*\*The referral program is subject to terms and conditions. Credits expire 3 months after issuance. The program does not apply to* Mithril *Institute partners.*
{% endhint %}

<br>


# Billing FAQ


# Mithril's approach to security

Safeguarding your data is paramount for us. We've embraced a security-first approach from day zero, ensuring that data protection is integrated into every aspect of our platform from the ground up rather than retrofitted. Mithril uses security best-practices to ensure you are on a trusted platform. You can view a complete list of our security measures in our [Trust Center](https://trust.mlfoundry.com/).

Some highlights about Mithril's approach to security:

* All compute available through Mithril is hosted in Tier 3 and 4 datacenters with SOC 2 Type II or ISO 27001 compliance that have passed our security requirements. All datacenters enforce strict access controls, biometric measures, and personnel authorization.
* Mithril is SOC 2 Type II certified in availability, security, and confidentiality.
* We ensure that only you have access to the SSH keys for your instances.


# Reporting security concerns

If you have any security concerns (e.g, vulnerability, potential breach), please email <security@mithril.ai>. A member of the Core Security Team will reach out ASAP.


# Legal


# Terms of Service

Mithril's Terms of Service can be found at [mithril.ai/terms-of-service](https://mithril.ai/terms-of-service).


# Privacy Policy

Mithril's Privacy Policy can be found at [mithril.ai/privacy](https://mithril.ai/privacy).


# Acceptable Use Policy

This Acceptable Use Policy (“**Policy**”) is part of the agreement between you and Foundry Technologies, Inc. (“**Mithril**”) under which you access the platform-as-a-service solution and other services offered by Mithril (“**Mithril Services**”) and any related compute resources made available by a compute provider via the Mithril Services (“**Compute Resources**”).

You may not use, or facilitate or allow others to use, the Mithril Services or the Compute Resources:

* In any manner that violates any applicable law, rule or regulation (including those specific to artificial intelligence or machine learning);
* To threaten, incite, promote, or encourage violence, terrorism, or other serious harm;
* For harm or abuse of a minor, including content or activity that promotes child sexual exploitation or abuse;
* For cryptocurrency mining, including proof-of-work and proof-of-stake protocols;
* To harass, harm, or encourage the harm of individuals or specific groups;
* To violate the rights or privacy of others;
* To violate the security, integrity, or availability of the Mithril Services or the Compute Resources or any of their respective users, networks, computers, or communications systems;
* To replicate a person’s voice or likeness without their consent or other lawful basis, including unauthorized impersonation and non-consensual sexual imagery;
* To generate or distribute viruses, worms, Trojan horses, or other destructive or deceptive items;
* To generate or distribute unsolicited mass email or other spam;
* To make consequential decisions, including those impacting a person’s fundamental rights, health, or safety, without first evaluating the potential risks of your use case and implementing appropriate human oversight, testing, and other use safeguards to mitigate such risks; or
* In connection with any activity that poses a significant risk of death, personal injury, or financial, physical, property or environmental damage, including without limitation in the operation of nuclear facilities, aircraft navigation or communication systems, air traffic control, life support or weapons systems.


# Data Processing Agreement

**DATA PROCESSING ADDENDUM**

This Data Processing Addendum (the “**DPA**”) made available by Foundry Technologies, Inc. (“**Mithril**”) is entered into between Customer and Processor, as defined below. Capitalized terms not defined in context in this DPA will have the meanings set forth in the attached Appendix 1.

For purposes of this DPA: (a) “**Customer**” means the customer of Mithril that uses the Platform to purchase the right to use compute resources made available by a Compute Provider for the processing of Customer Material; (b) “**Compute Provider**” means the applicable provider of such compute resource, which provider may be a third party or Mithril; and (c) “**Processor**” means, alternatively, (i) the Compute Provider (if a third party) or (ii) Mithril (as the Platform provider and, where applicable, as the Compute Provider).

For clarity, this DPA serves as a direct and separate agreement between (1) Customer and Mithril (as Platform provider, and where applicable, as Compute Provider), and (2) Customer and any third-party Compute Provider. The term “Processor” refers to the relevant party in the alternative (i.e., Mithril or the third-party Compute Provider) rather than jointly and is designed to enable the Customer to utilize a single DPA for these separate engagements. Mithril will not be liable for the acts or omissions of any third-party Compute Provider and the third-party Compute Provider will not be liable for the acts or omissions of Mithril.

1. **Data Processing and Protection**.
   1. Scope. This DPA applies when Personal Data is processed by Processor.
   2. Use Limitations. Processor will not: (a) Process the Personal Data for any purpose other than as a Processor on behalf of Customer for the specific purpose of performing the Services for Customer in accordance with this DPA; (b) Process the Personal Data for a commercial purpose other than as necessary to provide the Services to Customer; (c) “sell” or “share” (each as defined by Data Protection Law) any Personal Data; (d) Process the Personal Data outside of the direct business relationship between Processor and Customer; or (e) combine Personal Data with any other personal data or information it collects (directly or via any third party) other than as expressly permitted under Data Protection Law for Processors.
   3. Instructions. Processor will Process Personal Data only: (a) as authorized or permitted under the Services Agreement and this DPA and pursuant to any other reasonable and documented instructions provided by Customer and agreed to by Processor in writing; and (b) as required by Data Protection Law, provided that Processor will inform Customer (unless prohibited by such Data Protection Law) of the applicable legal requirement before Processing pursuant to such Data Protection Law.
   4. Compliance. In connection with its Processing of any Personal Data, Processor will comply with all obligations applicable to it in its role as a processor (or service provider) under Data Protection Law and provide the same level of privacy protection as is required by Data Protection Law. Processor will promptly notify Customer if Processor determines it can no longer meet its obligations under this DPA. Customer reserves the right, upon notice to Processor, to take reasonable and appropriate steps to stop and remediate unauthorized use of Personal Data.
   5. Confidentiality. Processor will ensure that persons authorized by Processor to Process any Personal Data are subject to appropriate confidentiality obligations.
   6. Security. Processor will implement and maintain security measures in accordance with generally accepted industry standards designed to protect Personal Data against Personal Data Breach and that meet or exceed requirements under Data Protection Law.
   7. Return or Disposal. Customer elects that Processor will delete all Personal Data after the end of the provision of the Services, unless Data Protection Law requires the storage of such Personal Data by Processor.
2. **Assistance**.
   1. Data Subject’s Rights Assistance. Taking into account the nature of Processor’s Processing of Personal Data, Customer acknowledges that the controls made available via Mithril’s Platform offer Customer the ability to fulfill Customer’s obligation to respond to requests for exercising data subject's rights under Data Protection Law (“**Data Subject Requests**”). Customer acknowledges that no other assistance is required by Processor help Customer fulfill its Data Subject Requests.
   2. Other Compliance Assistance. Taking into account the nature of Processing and the information available to Processor, Processor will provide assistance to Customer to facilitate Customer’s compliance with requirements under Data Protection Law, including any requirements related to data security, data protection assessments, and consultations with supervisory authorities, by providing the information identified in Section 3 below.
   3. Personal Data Breach Notice and Assistance. Processor will notify Customer without undue delay after becoming aware of a Personal Data Breach. Taking into account the nature of the Processing and the information available to Processor, Processor will provide reasonable assistance to Customer as may be necessary for Customer to satisfy any of its notification obligations imposed under Data Protection Law in connection with any Personal Data Breach.
3. **Audits**.

Processor will procure independent audits by a nationally recognized third-party auditor, on an annual or more frequent basis, to assess Processor’s adherence to the following standards and requirements: SSAE 18 Service Organization Control (SOC) 2 reports or certifications or other documentation evidencing compliance with such alternative standards as are substantially equivalent. Customer may choose to audit Processor by requesting a copy of such results. Upon Customer’s request, Processor will provide Customer a copy of any such audit results. Processor will use commercially reasonable efforts to remediate any material deficiencies identified by those audits. Customer will treat such results as the confidential information of Processor and not disclose them to any third party unless required by law.

4. **Subprocessors**.

Customer provides Processor with general authorization to use subprocessors to Process Personal Data in connection with the provision of the Services to Customer (each, a “**Subprocessor**”). Processor will only add or remove a Subprocessor after providing Customer with reasonable prior notice and an opportunity to object within 10 days. Processor will enter into a written contract with each Subprocessor imposing data protection obligations upon any Subprocessor that are no less protective than those included in this DPA. Processor will remain liable for any acts or omissions of its Subprocessors.

5. **Data Transfers**.

Processor may Process the Personal Data in regions specified via the Platform by Customer, or, if none, then in regions where Processor conducts its Services. Subject to Section 6, any Personal Data subject to the GDPR, UK GDPR, or the Swiss Federal Act on Data Protection (“**FADP**”) that is transferred to Processor in a third country not deemed adequate will be conducted pursuant to Module 2 or Module 3, depending on Customer’s role, of the standard contractual clauses for the transfer of Personal Data to processors in third countries according to Decision (EU) 2021/914 of the EU Commission of 4 June 2021 (the “**Standard Contractual Clauses**”) (the text of which is available at: <https://eur-lex.europa.eu/eli/dec_impl/2021/914/oj?uri=CELEX:32021D0914>).

The Standard Contractual Clauses will be deemed executed by Processor and Customer and the following terms will apply:

1. If there is any conflict between this DPA or the Services Agreement and the Standard Contractual Clauses, the Standard Contractual Clauses will prevail;
   2\. Customer will be referred to as the “Data Exporter” and Processor will be referred to as the “Data Importer” in the Standard Contractual Clauses;
   3\. Details in Attachment 1 of this DPA will be used to complete Annex I and III of the Standard Contractual Clauses;
   4\. Details in Section 1.5 will be used to complete Annex II of the Standard Contractual Clauses;
   5\. For the purposes of the Standard Contractual Clauses:
   1. The Parties agree to retain Clause 7;
   2. The Parties select option 2 in Clause 9 and agree on 10 days as the notice period for additions or replacements of new Subprocessors;
   3. The optional language in Class 11(a) is omitted;
   4. Clause 13(a) reads as follows “The data exporter’s competent supervisory authority to be determined in accordance with the GDPR”;
   5. The parties select option 2 of Clause 17; and
   6. For Clause 18(b), the Parties select the courts of country of the data exporter’s competent supervisory authority to be determined in accordance with the GDPR.
   7. In addition to the Standard Contractual Clauses, the Parties agree that any Personal Data subject to the UK GDPR that is transferred to Processor will be subject to the International Data Transfer Addendum to the EU Commission Standard Contractual Clauses Version B1.0, in force 21 March 2022 (the “UK Addendum”) (the text of which is available at: <https://ico.org.uk/media/for-organisations/documents/4019483/international-data-transfer-addendum.pdf>). The UK Addendum will be deemed executed by the Parties as of the effective date of this DPA, and the information in this DPA will be used to fill out the relevant sections of the UK Addendum.
   8. The parties agree to complete the Standard Contractual Clauses as follows for Personal Data subject to the FADP that is transferred to Processor: (i) the Parties agree to abide by the GDPR standard in relation to all Processing of Personal Data that is governed by the FADP; (ii) the term ‘Member State’ in the Standard Contractual Clauses will not be interpreted to exclude data subjects who habitually reside in Switzerland from initiating legal proceedings in Switzerland in accordance with Clause 18(c) of the Standard Contractual Clauses; and (iii) references to the ‘GDPR’ and ‘Member State’ in the Standard Contractual Clauses will be understood as references to the FADP and Switzerland, respectively.
2. **Liability**.

Except for liability arising from a party’s gross negligence or willful misconduct or any other matter for which liability cannot be excluded or limited under applicable law: (a) Processor will not have any liability arising out of or relating to the DPA for indirect, special, incidental, or consequential damages; and (b) Processor’s aggregate liability arising out of or relating to the DPA will not exceed the amounts paid by Customer for the applicable Services for the 12 months preceding the date on which the first claim giving rise to the liability arose.

**Attachment 1**\
**Definitions; Description of Processing; Subprocessors**

1. **Definitions**.

For purposes of this DPA, the following terms will have the meaning:

1. “**Customer Material**” means (a) any material, including data, files, software, text or audio, that is submitted by or on behalf of Customer through the Platform for processing on Compute Provider resources, and (b) any computational results generated by any such material while hosted on those resources.
   2\. “**Data Protection Law**” means any and all privacy, security, and data protection laws and regulations that apply to the Personal Data Processed by Processor under the Services Agreement, in each case as amended.
   3\. “**Platform**” means Mithril’s platform-as-a-service solution designed to allow the purchase and use of Compute Provider resource capacity.
   4\. “**GDPR**” means (a) the Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016 on the protection of natural persons with regard to the processing of personal data and on the free movement of such data, and repealing Directive 95/46/EC (General Data Protection Regulation), and (b) such law as incorporated into United Kingdom law by the Data Protection Act 2018 and amended by the Data Protection, Privacy and Electronic Communications (Amendments, etc.) (EU Exit) Regulations 2019 (“**UK GDPR**”) (each as amended, superseded, or replaced).
   5\. “**Personal Data**” means any of the Customer Material that is deemed “personal data” or “personal information” (or other analogous variations of such terms) under Data Protection Law.
   6\. “**Personal Data Breach**” means a breach of security leading to the accidental or unlawful destruction, loss, alteration, unauthorised disclosure of, or access to, Personal Data transmitted, stored or otherwise processed.
   7\. “**Process**” or “**Processing**” means any operation or set of operations which is performed on Personal Data or on sets of Personal Data, whether or not by automated means, such as collection, recording, organization, structuring, storage, adaptation or alteration, retrieval, consultation, use, disclosure by transmission, dissemination or otherwise making available, alignment or combination, restriction, erasure or destruction.
   8\. “**Services**” means the applicable services of the Processor, as further described in Section 2 below.
   9\. “**Services Agreement**” means the applicable agreement Customer enters into to use Mithril’s services.
2. **Description of Processing**
   1. Subject-Matter and Duration of Processing: Processor Processes Personal Data for the subject-matter specified under the Services Agreement and until the Services Agreement terminates or expires, unless otherwise agreed upon by the parties in writing.
   2. Nature and Purpose of Processing: Mithril Processes Personal Data as the provider of the Platform for the purpose of providing those Services to Customer, as further described in the Services Agreement. The Compute Provider makes compute resources available for Customer to Process Personal Data.
   3. Types of Personal Data: Customer is in control of and determines the types of the Personal Data it submits for Processing.
   4. Categories of Data Subjects: Customer is in control of and determines the types of the Personal Data it submits for Processing, including the types of data subject to whom that data relates. The data subjects could include Customer’s customers, employees, suppliers or end users.
   5. Frequency of Transfer: One-time or ongoing basis, as determined by Customer
   6. Retention Period: The duration of Processing is determined by Customer.
   7. Competent Supervisory Authority: The data exporter’s competent supervisory authority to be determined in accordance with the GDPR, except that: (a) the Swiss Federal Data Protection and Information Commission will act as the competent supervisory authority for transferred Personal Data subject to the FADP; and (b) the Information Commissioner’s Office will be the competent supervisory authority for transferred Personal Data subject to the UK GDPR.


