> This page is for NVIDIA NIM for Batched Molecular Dynamics, version 1.0.0.
> For other versions, use one of these documentation indexes:
> - 1.1.0 (Latest) (default): https://docs.nvidia.com/nim/alchemi/alchemi-bmd/1.1.0/llms.txt
> - 1.0.0: https://docs.nvidia.com/nim/alchemi/alchemi-bmd/1.0.0/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nim/alchemi/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nim/alchemi/_mcp/server.

# Process Request

POST /v1/infer
Content-Type: application/json

Run molecular dynamics simulation using MLIP models.

Reference: https://docs.nvidia.com/nim/alchemi/alchemi-bmd/api-reference/process-request-v-1-infer-post

## Request

### Body (application/json)

This endpoint expects a BMDRequest.

- `atoms` (BMDAtomicData, required) — Initial atomic structure for MD simulation.
- `config` (MDConfig, optional, nullable) — MD simulation configuration. Uses defaults if not provided.
- `info` (string, optional, nullable) — Optional metadata to echo back in response.

## Response

### 200

Successful Response

- `trajectory` (list of BMDSnapshot, optional, nullable) — List of trajectory snapshots from the MD simulation.
- `config` (MDConfig, optional, nullable) — MD configuration with updated istep and md_time reflecting final state.
- `status` (string, optional, default: Success) — Status message or error description.
- `info` (string, optional, nullable) — Echoed metadata from request.

## Errors

### 422 Unprocessable Entity Error

Validation Error

- `detail` (list of ValidationError, optional)

## Types

### BMDAtomicData

Atomic data with optional velocity and mass for MD simulations.

- `coord` (list of double, required) — Cartesian coordinates of the atoms in Angstrom, flattened list [x1, y1, z1, x2, y2, z2, ...].
- `numbers` (list of integer, required) — Atomic numbers of the atoms.
- `charge` (integer, optional, nullable, default: 0) — Charge of the system. Default is 0.
- `mult` (integer, optional, nullable, default: 1) — Spin multiplicity of the system (2S+1). Default is 1.
- `cell` (list of double, optional, nullable) — Unit cell parameters in Angstrom, flattened list (9 elements). If not set, the system is assumed to be infinite (no unit cell).
- `pbc` (list of boolean, optional, nullable, default: [true,true,true]) — Boolean values indicating periodic boundary conditions for each direction (x, y, z).Default is [True, True, True] (periodic boundary conditions in all directions).
- `structure_id` (string, optional, nullable) — Unique string identifier for the structure. Defaults to empty string.
- `mass` (list of double, optional, nullable) — Atomic masses in amu. If None, uses standard atomic masses.
- `velocity` (list of double, optional, nullable) — Initial velocities in Å/fs, flattened list [vx1, vy1, vz1, ...]. If None, velocities are initialized from Maxwell-Boltzmann distribution.

### MDConfig

Configuration for a single MD simulation run. All fields use Triton type annotations to enable serialization as Triton tensors.

- `temperature` (double, optional, default: 300) — Target temperature in Kelvin
- `dt` (double, optional, default: 1) — Time step in femtoseconds
- `nvt` (boolean, optional, default: true) — Enable NVT ensemble (Langevin thermostat)
- `friction` (double, optional, default: 1) — Langevin thermostat friction coefficient in ps^-1
- `npt` (boolean, optional, default: false) — Enable NPT ensemble (Monte Carlo barostat)
- `pressure` (double, optional, default: 0) — Target pressure in kBar
- `barostat_anisotropic` (boolean, optional, default: false) — Enable anisotropic barostat for non-cubic cells
- `barostat_every` (integer, optional, default: 25) — Barostat update frequency in steps
- `barostat_prob_shear` (double, optional, default: 0.5) — Probability of shear move in anisotropic barostat
- `barostat_shear_max` (double, optional, default: 0.01) — Maximum shear move magnitude
- `barostat_diag_max` (double, optional, default: 0.01) — Maximum diagonal cell shape change
- `barostat_log_scale_max` (double, optional, default: 0.001) — Maximum log-scale volumetric move
- `md_time` (double, optional, default: 0) — Current simulation time in picoseconds (for restart)
- `md_time_max` (double, optional, default: 10) — Maximum simulation time in picoseconds
- `save_interval` (integer, optional, default: 100) — Save trajectory snapshot every N steps
- `istep` (integer, optional, default: 0) — Current step number (for restart)
- `efield` (list of double, optional, default: [0,0,0]) — External electric field vector [Ex, Ey, Ez] in μV/Å (AIMNet2 only)

### BMDSnapshot

Single trajectory snapshot from MD simulation.

- `coord` (list of double, required) — Atomic coordinates in Angstrom, flattened list.
- `velocity` (list of double, required) — Atomic velocities in Å/fs, flattened list.
- `energy` (double, required) — Potential energy in eV.
- `istep` (integer, required) — Step number in the simulation.
- `md_time` (double, required) — Simulation time in picoseconds.
- `cell` (list of double, optional, nullable) — Unit cell parameters (9 elements), if periodic.
- `stress` (list of double, optional, nullable) — Stress tensor in kBar (9 elements), if periodic.
- `charges` (list of double, optional, nullable) — Partial atomic charges, if available.

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)

### ValidationErrorLocItems

- string
- integer

## Examples

**Request**

```json
{
  "atoms": {
    "coord": [
      0,
      0,
      0,
      1.5,
      0,
      0,
      0.75,
      1.3,
      0
    ],
    "numbers": [
      8,
      1,
      1
    ]
  }
}
```

**Response**

```json
{
  "trajectory": [
    {
      "coord": [
        0.012,
        0.003,
        -0.001,
        1.498,
        0.011,
        0.002,
        0.753,
        1.295,
        0.001
      ],
      "velocity": [
        0.0023,
        -0.0011,
        0.0005,
        -0.0018,
        0.0009,
        -0.0003,
        0.0014,
        -0.0007,
        0.0002
      ],
      "energy": -14.237,
      "istep": 100,
      "md_time": 0.1,
      "cell": [
        10,
        0,
        0,
        0,
        10,
        0,
        0,
        0,
        10
      ],
      "stress": [
        -0.152,
        0.003,
        0.001,
        0.003,
        -0.148,
        0.002,
        0.001,
        0.002,
        -0.15
      ],
      "charges": [
        -0.834,
        0.417,
        0.417
      ]
    }
  ],
  "config": {
    "temperature": 300,
    "dt": 1,
    "nvt": true,
    "friction": 1,
    "npt": false,
    "pressure": 0,
    "barostat_anisotropic": false,
    "barostat_every": 25,
    "barostat_prob_shear": 0.5,
    "barostat_shear_max": 0.01,
    "barostat_diag_max": 0.01,
    "barostat_log_scale_max": 0.001,
    "md_time": 0.1,
    "md_time_max": 10,
    "save_interval": 100,
    "istep": 100,
    "efield": [
      0,
      0,
      0
    ]
  },
  "status": "Success",
  "info": "water molecule NVT simulation at 300K"
}
```

**SDK Code**

```python
import requests

url = "https://api.example.com/v1/infer"

payload = { "atoms": {
        "coord": [0, 0, 0, 1.5, 0, 0, 0.75, 1.3, 0],
        "numbers": [8, 1, 1]
    } }
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.example.com/v1/infer';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: '{"atoms":{"coord":[0,0,0,1.5,0,0,0.75,1.3,0],"numbers":[8,1,1]}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.example.com/v1/infer"

	payload := strings.NewReader("{\n  \"atoms\": {\n    \"coord\": [\n      0,\n      0,\n      0,\n      1.5,\n      0,\n      0,\n      0.75,\n      1.3,\n      0\n    ],\n    \"numbers\": [\n      8,\n      1,\n      1\n    ]\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.example.com/v1/infer")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n  \"atoms\": {\n    \"coord\": [\n      0,\n      0,\n      0,\n      1.5,\n      0,\n      0,\n      0.75,\n      1.3,\n      0\n    ],\n    \"numbers\": [\n      8,\n      1,\n      1\n    ]\n  }\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.example.com/v1/infer")
  .header("Content-Type", "application/json")
  .body("{\n  \"atoms\": {\n    \"coord\": [\n      0,\n      0,\n      0,\n      1.5,\n      0,\n      0,\n      0.75,\n      1.3,\n      0\n    ],\n    \"numbers\": [\n      8,\n      1,\n      1\n    ]\n  }\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.example.com/v1/infer', [
  'body' => '{
  "atoms": {
    "coord": [
      0,
      0,
      0,
      1.5,
      0,
      0,
      0.75,
      1.3,
      0
    ],
    "numbers": [
      8,
      1,
      1
    ]
  }
}',
  'headers' => [
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.example.com/v1/infer");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"atoms\": {\n    \"coord\": [\n      0,\n      0,\n      0,\n      1.5,\n      0,\n      0,\n      0.75,\n      1.3,\n      0\n    ],\n    \"numbers\": [\n      8,\n      1,\n      1\n    ]\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Content-Type": "application/json"]
let parameters = ["atoms": [
    "coord": [0, 0, 0, 1.5, 0, 0, 0.75, 1.3, 0],
    "numbers": [8, 1, 1]
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.example.com/v1/infer")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```