> This page is for NVIDIA NIM for Batched Geometry Relaxation, version 1.1.0 (Latest) (default).
> For other versions, use one of these documentation indexes:
> - 1.1.0 (Latest) (default): https://docs.nvidia.com/nim/alchemi/alchemi-bgr/1.1.0/llms.txt
> - 1.0.0: https://docs.nvidia.com/nim/alchemi/alchemi-bgr/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.

# API Reference

## OpenAPI Schema

The OpenAPI specification details the following endpoints:

- `/v1/infer` Inference endpoint for batched geometry relaxation
- `/v1/health/live` Health liveliness endpoint
- `/v1/health/ready` Health readiness endpoint
- `/v1/status` System status monitoring endpoint

For the full interactive schema, refer to the [API Reference](https://docs.nvidia.com/nim/alchemi/alchemi-bgr/1.1.0/api-reference/process-request-v-1-infer-post) tab.

## Endpoints

### POST /v1/infer

Perform batched geometry relaxation on one or more atomic structures.

**Request Body**

The request body contains the following fields:

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `atoms` | array | Yes | List of `AtomicData` objects |
| `opttol` | float | No | Per-request force tolerance (eV/Å) |
| `opttol_pressure` | float | No | Per-request pressure tolerance (kBar) |
| `cellopt` | bool | No | Per-request cell optimization flag |
| `info` | string | No | Optional metadata to echo back |

**AtomicData Fields (`atoms`)**

The following table lists the `atoms` field parameters (`AtomicData`):

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `coord` | array[float] | Yes | Flattened coordinates [x1,y1,z1,x2,y2,z2,...] in Angstrom |
| `numbers` | array[int] | Yes | Atomic numbers |
| `cell` | array[float] | Conditional | Unit cell (9 elements, row-major) in Angstrom. Required when backend PBC mode is enabled and forbidden when it is disabled. |
| `pbc` | array[bool] | No | Periodic axes for the supplied cell in [x,y,z] order, default [true,true,true]. This field does not override backend PBC mode. |
| `charge` | int | No | System charge, default 0 |
| `mult` | int | No | Spin multiplicity (2S+1), default 1 |
| `structure_id` | string | No | Unique identifier for tracking |
| `active_mask` | array[bool] | No | Mask for active atoms (true=optimize) |

When a unit cell is provided, its determinant must be positive and its volume
must be greater than 1.0 Å³.

Backend PBC mode is selected at container startup with `ALCHEMI_NIM_PBC`. The
mode controls whether `cell` must be present; the nested `pbc` field controls
which axes of that cell are periodic. To accept both cell-bearing and
cell-free requests, run separate container instances with the corresponding
backend modes.

**Response**

The response contains the following fields:

| Field | Type | Description |
|-------|------|-------------|
| `atoms` | array | List of `OptimizationResult` objects |
| `status` | string | Status message ("Success" or error) |
| `info` | string | Echoed metadata from request |

**OptimizationResult Fields (`atoms` items)**

The following table lists the `atoms` items (`OptimizationResult`):

| Field | Type | Description |
|-------|------|-------------|
| `coord` | array[float] | Optimized coordinates in Angstrom |
| `numbers` | array[int] | Atomic numbers |
| `cell` | array[float] | Optimized unit cell (if cell optimization enabled) |
| `pbc` | array[bool] | Periodic boundary conditions |
| `energy` | float | Total energy in eV |
| `forces` | array[float] | Forces on atoms in eV/Å |
| `stress` | array[float] | Stress tensor in eV/Å³ (if available) |
| `charges` | array[float] | Partial charges (if available) |
| `converged` | bool | Whether optimization converged |
| `optimizer_nsteps` | int | Number of optimization steps taken |
| `structure_id` | string | Echoed structure identifier |

## Error Responses

The API returns the following error responses:

| HTTP Status | Meaning | When |
|-------------|---------|------|
| 200 | Success | Request completed. Check per-structure `converged` field for optimization status. |
| 400 | Bad Request | Malformed JSON or missing required fields. |
| 422 | Validation Error | Invalid field types or values (for example, mismatched `coord` and `numbers` lengths, an empty `atoms` array, or a cell volume of 1.0 Å³ or less). |
| 500 | Internal Server Error | Unexpected server failure or GPU out-of-memory (OOM) error. |
| 503 | Service Unavailable | NIM not ready, backend unavailable, or engine recovery in progress. Retry the request after the readiness check succeeds. |

**Example Validation Error (422)**

The `detail` value is an array for request-schema errors, a string for the
maximum-system-size check, or an object for service validation such as an
invalid cell volume.

```json
{
  "detail": [
    {
      "loc": ["body", "atoms", 0, "coord"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}
```

### Timeout and Memory Behavior

- Requests with structures exceeding `max_system_size` (check by using `GET /v1/status`) return 422 before inference.
- There is no built-in server-side request timeout. Use client-side timeouts for large batches.
- Check the `converged` field in each result structure. A 200 response does not guarantee that all structures converged.

### GET /v1/health/ready

Check if the NIM is ready to accept inference requests.

**Response**

```json
{
  "status": "ready",
  "backends_alive": 2,
  "backends_total": 2
}
```

An HTTP 200 response reports `"status":"ready"` and includes both backend
counts. If Triton is ready but no Alchemi backend worker responds, the endpoint
returns HTTP 503 with `"status":"no backends available"`,
`"backends_alive":0`, and `backends_total`. Other HTTP 503 responses, such as
Triton startup and health-check failures, contain only a `status` message.

### GET /v1/health/live

Check if the Triton server is live.

**Response**

```json
{
  "status": "live"
}
```

The endpoint returns `503` with `{"status":"not live"}` when the Triton
inference server is not live. This check does not report the health of the
Alchemi backend workers.

### GET /v1/status

Get detailed system status including worker metrics.

**Response**

```json
{
  "total": {
    "tasks_received": 100,
    "tasks_completed": 95,
    "queue_size_atoms": 1024,
    "queue_size_tasks": 5,
    "requests_received": 50,
    "requests_completed": 48,
    "requests_in_progress": 2,
    "max_system_size": 36876
  },
  "workers": [
    {
      "device": "cuda:0",
      "tasks_received": 50,
      "tasks_completed": 48,
      "queue_size_atoms": 512,
      "queue_size_tasks": 2,
      "batch_size": 36876,
      "max_batch_size": 47136,
      "gpu_model": "NVIDIA H100 80GB HBM3"
    }
  ]
}
```

## Example Requests

The following sections show how to use the API to start an optimization request.

### Single Structure Optimization

Start this request by running the following command:

```bash
curl -X 'POST' \
  'http://localhost:8000/v1/infer' \
  -H 'Content-Type: application/json' \
  -d '{
    "atoms": [{
      "coord": [0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
      "numbers": [1, 1],
      "cell": [10, 0, 0, 0, 10, 0, 0, 0, 10]
    }]
  }'
```

### Multiple Structures With Custom Tolerance

Start this request by running the following command:

```bash
curl -X 'POST' \
  'http://localhost:8000/v1/infer' \
  -H 'Content-Type: application/json' \
  -d '{
    "atoms": [
      {
        "coord": [0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
        "numbers": [1, 1],
        "cell": [10, 0, 0, 0, 10, 0, 0, 0, 10],
        "structure_id": "H2_struct1"
      },
      {
        "coord": [0.0, 0.0, 0.0, 0.0, 0.0, 1.5],
        "numbers": [1, 1],
        "cell": [10, 0, 0, 0, 10, 0, 0, 0, 10],
        "structure_id": "H2_struct2"
      }
    ],
    "opttol": 0.001
  }'
```