---
title: HttpOutput
description: "The output of an `http` Effect: what the `onDone` of its state gets as `event.output`."
---

# `HttpOutput`

Type, in `@jr2/orchestrator/src/effector-wire.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Effects.

```ts
type HttpOutput = {
  outcome: "response";
  status: number;
  headers: Record<string, string>;
  contentType: string;
  size: number;
  body?: string | undefined;
  truncated?: boolean | undefined;
} | {
  outcome: "unknown" | "unreachable" | "refused";
  reason: string;
};
```

The output of an `http` Effect: what the `onDone` of its state gets as `event.output`. Every
outcome is output. A 4xx or 5xx status is output too. Route on `outcome`:

- `response`: an answer came back. `status` is its HTTP status. `headers`, `contentType` and
  `size` tell about the body. `body` is there when the body is text: at most `maxBody` bytes
  (`truncated` is `true` when jr2 cut it). A body that is not text gives only its size and
  content type. jr2 replaces each value of an Effect secret that the Effector holds, and its
  usual encodings, with `[secret:<name>]`, in the body and the headers.
- `unreachable`: the call did not go out, for example because the name did not resolve, or the
  connection or TLS failed. `reason` tells why.
- `refused`: jr2 or the Effector refused the call, and nothing was sent. For example, a path
  segment that is `.`, `..` or empty, or a request that is too large. `reason` tells why.
- `unknown`: the call can have gone out, but no answer came, or jr2 cannot tell after a restart.
  `reason` tells why. jr2 does not send it again unless it is marked `idempotent`.

**Forms**: it is one of these objects.

- Form 1: `outcome`, `status`, `headers`, `contentType`, `size`, `body`, `truncated`

  - `outcome`: `"response"`
  - `status`: `number`
  - `headers`: `Record<string, string>`
  - `contentType`: `string`
  - `size`: `number`
  - `body` (optional): `string`
  - `truncated` (optional): `boolean`
- Form 2: `outcome`, `reason`

  - `outcome`: `"unknown" | "unreachable" | "refused"`
  - `reason`: `string`

**Example**

```ts
import { fail, http, jr2Setup, type HttpOutput } from "@jr2/orchestrator";

const ok = (output: HttpOutput): boolean => output.outcome === "response" && output.status < 300;

export const machine = jr2Setup({
  actors: { health: http({ method: "GET", url: "https://app.example.com/healthz" }), fail: fail() },
}).createMachine({
  id: "health",
  initial: "checking",
  states: {
    checking: {
      invoke: {
        src: "health",
        onDone: [
          { guard: ({ event }) => ok(event.output), target: "healthy" },
          { target: "unhealthy" },
        ],
      },
    },
    healthy: { type: "final" },
    // Not a final state: the run ends `failed`, and `jr2 run` exits 1.
    unhealthy: { invoke: { src: "fail", input: { reason: "the app is not healthy" } } },
  },
});
```

**See also**

- [Effects](../../concepts/effects.md)
- [Run a command or call a URL with an Effect](../../guides/run-a-command-or-call-a-url.md)
- [ADR-0068: An Effector holds an Effect's secrets and signs its wire](../decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md)
