> ## Documentation Index
> Fetch the complete documentation index at: https://docs.revilico.bio/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Create an API key, start a RevRedox run with curl or Python, wait for it to finish, read its results, and upload an input file to the Revilico API.

This guide runs [RevRedox](https://docs.revilico.bio/docs/revredox.md) on one molecule given as a SMILES string, so you don't need to upload a file. It takes a few minutes and uses a small number of credits.

## 1. Create an API key

1. In the [Revilico web app](https://app.revilico.bio/account/developer), open your account and click **Developer** in the sidebar.
2. On the **API keys** tab, click **Create API key**.
3. Name the key, keep **Full access** and pick an expiry.
4. Copy the key. It starts with `rvl_live_` and is shown only once.

Store the key in an environment variable rather than in your code:

```bash theme={null}
export REVILICO_API_KEY="rvl_live_…"
```

See [Authentication](https://docs.revilico.bio/developers/authentication.md) for scopes, rotation and revocation.

## 2. Check the key

`GET /v1/me` works with any key. It returns your account, the key's scopes, the engines you can run and your organization's credits.

```bash curl theme={null}
curl https://public-api.revilico.bio/v1/me \
  -H "Authorization: Bearer $REVILICO_API_KEY"
```

```python Python theme={null}
import os
import requests

API = "https://public-api.revilico.bio/v1"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['REVILICO_API_KEY']}"

print(session.get(f"{API}/me").json())
```

If `engines` doesn't include `revredox`, pick another engine from the list and read its parameters with `GET /v1/engines/{engine}`.

## 3. Start a run

Send the engine's parameters to `POST /v1/engines/{engine}/runs`. Parameters you leave out take their defaults; here RevRedox computes both oxidation and reduction potentials against SCE.

```bash curl theme={null}
curl https://public-api.revilico.bio/v1/engines/revredox/runs \
  -H "Authorization: Bearer $REVILICO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Phenothiazine redox",
    "parameters": { "molecule": "c1ccc2c(c1)Nc1ccccc1S2" }
  }'
```

```python Python theme={null}
run = session.post(
    f"{API}/engines/revredox/runs",
    json={
        "name": "Phenothiazine redox",
        "parameters": {"molecule": "c1ccc2c(c1)Nc1ccccc1S2"},
    },
).json()
print(run["id"], run["status"])
```

The API answers `202 Accepted` with the run:

```json theme={null}
{
  "id": "run_3f2b…",
  "engine": "revredox",
  "name": "Phenothiazine redox",
  "status": "queued",
  "progress": 0,
  "creditsUsed": 0,
  "links": {
    "self": "/v1/runs/run_3f2b…",
    "results": "/v1/runs/run_3f2b…/results"
  }
}
```

> [!TIP]
>
> Check parameters before you spend credits: `POST /v1/engines/{engine}/validate` returns them with defaults filled in, or a `422` that names each problem. It runs nothing.

## 4. Wait for the run to finish

Poll `GET /v1/runs/{runId}` until `status` is `succeeded`, `failed` or `cancelled`. Runs take minutes to hours depending on the engine and input, so poll every 10 to 30 seconds.

```bash curl theme={null}
curl https://public-api.revilico.bio/v1/runs/run_3f2b… \
  -H "Authorization: Bearer $REVILICO_API_KEY"
```

```python Python theme={null}
import time

while run["status"] in ("queued", "running"):
    time.sleep(20)
    run = session.get(f"{API}/runs/{run['id']}").json()

print(run["status"], run["creditsUsed"])
```

A failed run has the reason in `error.message`. Its logs are still listed by `GET /v1/runs/{runId}/files`.

## 5. Read the results

`GET /v1/runs/{runId}/results` returns the results as JSON rows, one per molecule, state or item, with run-level facts such as the level of theory beside them.

```bash curl theme={null}
curl https://public-api.revilico.bio/v1/runs/run_3f2b…/results \
  -H "Authorization: Bearer $REVILICO_API_KEY"
```

```python Python theme={null}
results = session.get(f"{API}/runs/{run['id']}/results").json()
for row in results["data"]:
    print(row)
```

From there you can:

* get everything for one row with `GET /v1/runs/{runId}/results/{index}`
* list every file the run wrote with `GET /v1/runs/{runId}/files`, and download one with `GET /v1/runs/{runId}/files/read?path=…`
* download the engine's named outputs with `GET /v1/runs/{runId}/outputs/{outputId}`

Download links are pre-signed and valid for 15 minutes.

## Use an input file

Engines that take files, such as an SDF of ligands or a CSV of SMILES, need the file uploaded first. Uploading is two requests: create the upload, then `PUT` the bytes to the URL it returns.

```bash curl theme={null}
# 1. Create the upload
curl https://public-api.revilico.bio/v1/files \
  -H "Authorization: Bearer $REVILICO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "molecules.csv", "sizeBytes": 1834, "contentType": "text/csv" }'

# 2. PUT the bytes to upload.url with upload.headers
curl -X PUT "<upload.url>" \
  -H "Content-Type: text/csv" \
  -H "Content-Length: 1834" \
  --data-binary @molecules.csv
```

```python Python theme={null}
from pathlib import Path

path = Path("molecules.csv")
upload = session.post(
    f"{API}/files",
    json={"name": path.name, "sizeBytes": path.stat().st_size, "contentType": "text/csv"},
).json()
requests.put(upload["upload"]["url"], data=path.read_bytes(), headers=upload["upload"]["headers"]).raise_for_status()
file_id = upload["id"]
```

Then pass the file id under the engine's input key in `inputs`. `GET /v1/engines/{engine}` lists each engine's input keys, formats and size limits. For example, [RevOrbitals](https://docs.revilico.bio/docs/revorbitals.md) takes a CSV of SMILES as `molecules`:

```bash theme={null}
curl https://public-api.revilico.bio/v1/engines/revorbitals/runs \
  -H "Authorization: Bearer $REVILICO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Frontier orbitals",
    "parameters": { "solvent": "water" },
    "inputs": { "molecules": "file_8c1d…" }
  }'
```

Until the `PUT` has finished, `GET /v1/files/{fileId}` returns 404 and a run that uses the file is refused.

## Next steps

> **[API reference](https://docs.revilico.bio/api-reference/introduction.md)**
>
> Every endpoint, with a playground.

> **[Errors](https://docs.revilico.bio/developers/errors.md)**
>
> Error codes, pagination and IDs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.