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

# Reflex

> Get a decision from text, JSON, or an image. Send a state and a question; read the probabilities.

Need a decision instead of a paragraph? Reflex answers questions about text, JSON, and images with probabilities your code can act on. No output tokens or text parsing.

| Model | Endpoint | Context | Price per million input tokens |
| - | - | - | - |
| `reflex` | `POST /v1/systemone` | 65,536 tokens | $0.042 uncached · $0.01 cached |

## Text quickstart

Ask a yes/no question about a message. Set your [Morph API key](https://www.morphllm.com/dashboard/api-keys), then run:

```bash theme={null}
export MORPH_API_KEY="YOUR_API_KEY"

curl --fail-with-body https://api.morphllm.com/v1/systemone \
  -H "Authorization: Bearer $MORPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "reflex",
    "state": "Checkout is down. Customers cannot pay. Please fix it now.",
    "questions": {
      "is_urgent": {
        "type": "noul",
        "instructions": "Does this message require urgent attention?"
      }
    }
  }'
```

Read `answers.is_urgent.noul`: the probability of yes, from 0 to 1. This request returned:

```json theme={null}
"is_urgent": { "type": "noul", "noul": 0.9999869381991648 }
```

No image or training step is required. To ask about an image instead, follow the three steps below.

![Send an image and a question to Reflex, then use the returned decision and probabilities in your code.](https://mintcdn.com/morph-555d6c14/KkfKAH4I30f3Y0LP/images/reflex/request-flow.svg?fit=max\&auto=format\&n=KkfKAH4I30f3Y0LP\&q=85\&s=d80f7d15a73b96b6df9807f28c5fbe7c)

## 1. Choose an image

This frame comes from our satellite demo. We'll ask whether outdoor mechanical equipment is visible beside the building.

![Satellite image of an industrial building with outdoor mechanical equipment along two sides.](https://mintcdn.com/morph-555d6c14/KkfKAH4I30f3Y0LP/images/reflex/satellite-input.jpg?fit=max\&auto=format\&n=KkfKAH4I30f3Y0LP\&q=85\&s=06853a32eb8b6d2b13fd4ba1471aac34)

Anonymized satellite demo frame. Imagery © Mapbox.

[Download the image](https://docs.morphllm.com/images/reflex/satellite-input.jpg) as `satellite-input.jpg`. Get a [Morph API key](https://www.morphllm.com/dashboard/api-keys) and set it in your terminal:

```bash theme={null}
export MORPH_API_KEY="YOUR_API_KEY"
```

## 2. Ask a question

Save this as `reflex.py`, then run `python3 reflex.py`. It uses Python's standard library.

```python theme={null}
import base64
import json
import os
from pathlib import Path
from urllib.request import Request, urlopen

image = base64.b64encode(Path("satellite-input.jpg").read_bytes()).decode()

payload = {
    "model": "reflex",
    "state": "An anonymized satellite image of an industrial building. "
             "Inspect the equipment visible outside the building.",
    "images": [f"data:image/jpeg;base64,{image}"],
    "questions": {
        "equipment": {
            "type": "choice",
            "instructions": "Is outdoor mechanical equipment visible beside the building?",
            "criteria": {
                "visible": "Outdoor mechanical equipment is visible.",
                "not_visible": "No outdoor mechanical equipment is visible.",
                "unclear": "The image is too unclear to tell.",
            },
        }
    },
}

request = Request(
    "https://api.morphllm.com/v1/systemone",
    data=json.dumps(payload).encode(),
    headers={
        "Authorization": f"Bearer {os.environ['MORPH_API_KEY']}",
        "Content-Type": "application/json",
    },
)
with urlopen(request, timeout=60) as response:
    result = json.load(response)

print(json.dumps(result, indent=2))
```

`state` is the context. `questions` names each decision. `criteria` describes the options. For a text-only request, leave out `images` and put your text or JSON in `state`.

Images must be inline **base64 data URLs**, not web links. PNG, JPEG, and WebP are accepted, up to 16 images and 8 MB per image. Put images in `images` or in `image_url` parts inside `state`, never inside a question.

## 3. Read the decision

This is the production response for the image and request above. Results can vary.

![Observed option probabilities: visible 98.41%, not visible 1.36%, unclear 0.23%. Confidence 97.62%; zero output tokens.](https://mintcdn.com/morph-555d6c14/KkfKAH4I30f3Y0LP/images/reflex/equipment-result.svg?fit=max\&auto=format\&n=KkfKAH4I30f3Y0LP\&q=85\&s=8c0d8a9cbbd98f45e4e4a5d1ab9a62d2)

```json theme={null}
{
  "model": "reflex",
  "answers": {
    "equipment": {
      "type": "choice",
      "choice": "visible",
      "probabilities": {
        "visible": 0.9841100832699332,
        "not_visible": 0.013555884173541434,
        "unclear": 0.0023340325565253434
      },
      "confidence": 0.9761651249048997
    }
  },
  "usage": {
    "input_tokens": 1295,
    "output_tokens": 0,
    "input_tokens_details": { "cached_tokens": 0 }
  }
}
```

`choice` is the most likely option. `probabilities` sum to 1. `confidence` measures the selected answer against the model's full vocabulary, so it can be lower than that option's probability. Choose your own confidence threshold for automatic actions.

## Other question types

Use several named questions in the same request when they share a state.

| Type | `criteria` | Returned value |
| - | - | - |
| `choice` | Option names mapped to descriptions | `choice` plus probabilities per option |
| `noul` | Optional `{"true": "…", "false": "…"}` | `noul`: probability of yes |
| `score` | 2–10 ordered descriptions, lowest first | `score`: expected zero-based level |

The original satellite demo evaluated a capacity claim using observations supplied as text. This example sends the image directly and asks only what is visible; a satellite image alone does not establish usable electrical capacity.

For request fields and errors, see the [API reference](https://docs.morphllm.com/api-reference/endpoint/systemone.md). Invalid images or question shapes return `400`; unsupported media such as audio, video, or remote image URLs return `422`. Check the returned error message before retrying.

## Reuse the image with caching

Caching is automatic. Send the same image, state, and question again; no cache flag or cache ID is needed. Check `usage.input_tokens_details.cached_tokens` to see how much input was reused.

In the Python example above, replace the block starting at `request = Request(...)` with this:

```python theme={null}
from time import perf_counter

for call in range(1, 3):
    request = Request(
        "https://api.morphllm.com/v1/systemone",
        data=json.dumps(payload).encode(),
        headers={
            "Authorization": f"Bearer {os.environ['MORPH_API_KEY']}",
            "Content-Type": "application/json",
        },
    )
    start = perf_counter()
    with urlopen(request, timeout=60) as response:
        result = json.load(response)

    elapsed_ms = round((perf_counter() - start) * 1000)
    usage = result["usage"]
    cached = usage["input_tokens_details"]["cached_tokens"]
    print(f"Call {call}: {cached}/{usage['input_tokens']} cached, {elapsed_ms} ms")
```

In a separate production test using the satellite frame as a PNG, we kept the state and question identical across five calls:

| Request | Cached / input tokens | Time | Decision |
| - | - | - | - |
| Satellite image, first call | 0 / 1,328 | 890 ms | Equipment visible |
| Same image again | 1,216 / 1,328 | 220 ms | Equipment visible |
| Switch to a blank image | 0 / 1,328 | 226 ms | Not visible |
| Same blank image again | 1,216 / 1,328 | 131 ms | Not visible |
| Return to the satellite image | 1,216 / 1,328 | 208 ms | Equipment visible |

The repeated requests reused **91.6% of input tokens**. Changing the image caused a cache miss and changed the decision; returning to the original image reused its cached state. These are measured calls, not latency guarantees. Cache availability and token counts can vary. If the image and context are already warm, even the first call can be a cache hit.

Cached input costs `$0.01` per million tokens; uncached input costs `$0.042`. Input usage sums across questions, including image tokens. Caching reuses model computation, not a saved answer.


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