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

# JSON primitives

> Send token and tensor data with Whitney's typed JSON contract.

All Whitney v1 requests use `application/json`. Training data is expressed as
token ID arrays and dense tensors; you do not need generated protocol code or a
provider SDK.

## Forward and backward

Submit this payload as the `payload` of a `forward` or `forward_backward`
operation:

```json theme={null}
{
  "data": [
    {
      "input": { "token_ids": [9707, 374, 264] },
      "loss_inputs": {
        "target_tokens": {
          "dtype": "int64",
          "shape": [3],
          "values": [374, 264, 1273]
        },
        "weights": {
          "dtype": "float32",
          "shape": [3],
          "values": [1, 1, 1]
        }
      }
    }
  ],
  "loss_function": "cross_entropy",
  "loss_config": {}
}
```

Tensor `values` are dense and row-major. Their count must equal the product of
`shape`. Cross-entropy targets must be `int64`; optional weights must be
`float32`; both tensors must match the input length.

### GRPO's `importance_sampling` payload

RL loops align four tensors instead of two — shifted `target_tokens`,
prompt-masked `weights`, the rollout-policy `logprobs` returned by `sample()`,
and per-token `advantages` — all the same length as `input.token_ids`.
Positions inside the prompt carry zero weight, zero logprob, and zero
advantage; only completion positions carry real values:

```json theme={null}
{
  "data": [
    {
      "input": { "token_ids": [9707, 374, 264, 15592] },
      "loss_inputs": {
        "target_tokens": {
          "dtype": "int64",
          "shape": [4],
          "values": [374, 264, 15592, 1614]
        },
        "weights": {
          "dtype": "float32",
          "shape": [4],
          "values": [0, 0, 1, 1]
        },
        "logprobs": {
          "dtype": "float32",
          "shape": [4],
          "values": [0, 0, -0.31, -0.08]
        },
        "advantages": {
          "dtype": "float32",
          "shape": [4],
          "values": [0, 0, 1.22, 1.22]
        }
      }
    }
  ],
  "loss_function": "importance_sampling",
  "loss_config": {}
}
```

Here the model saw a 3-token prompt and a 2-token completion; `input` and
`target_tokens` both cover the shifted 4-token window (the completion's last
token only ever appears as a target). The first two positions are
prompt-masked to zero; the last two carry the sampler's own logprobs and a
single scalar advantage broadcast across the completion. Building this by
hand for every algorithm variant is exactly what
[`examples/training/http/whitney_datums.py`](https://github.com/try-whitney/whitney/blob/main/examples/training/http/whitney_datums.py)'s
`rl_datum()` does — see [GRPO](/cookbooks/grpo) for the full loop.

## Sample

```json theme={null}
{
  "prompt": { "token_ids": [9707, 374, 264] },
  "parameters": {
    "max_tokens": 64,
    "temperature": 0.7,
    "top_p": 0.95,
    "top_k": -1,
    "min_p": 0,
    "seed": 0,
    "stop_token_ids": []
  },
  "num_samples": 4,
  "include_prompt_logprobs": false,
  "topk_prompt_logprobs": 0,
  "required_weight_version": 1
}
```

Use the same payload for run-scoped or explicit sampler-scoped `sample`.
`required_weight_version` prevents reading stale weights.

## Full operation envelope

Every primitive is posted to `/v1/training/runs/{run_id}/operations` or, for
an existing sampler, `/v1/training/samplers/{sampler_id}/operations`:

```json theme={null}
{
  "seq_id": 1,
  "idempotency_key": "stable-key-for-this-operation",
  "request_hash": "sha256-of-the-canonical-envelope-without-request_hash",
  "kind": "forward_backward",
  "payload": {}
}
```

The request hash is SHA-256 of canonical JSON containing `surface` and
`payload`; see the [HTTP cookbook helper](https://github.com/try-whitney/whitney/blob/main/examples/training/http/whitney_http.py)
for an executable implementation. On an ambiguous response, retry the exact
same sequence ID, idempotency key, hash, and body.

<Warning>
  Never place token or tensor payloads in URLs, logs, documentation feedback, or durable operation metadata.
</Warning>
