# @fixragent/triage

One maintenance photo in, one fixed JSON out: what it is, how urgent, which trade to call, what to say. This is the JavaScript client for the fixRAgent triage API — `POST https://fixragent.com/api/triage` — in one file with no dependencies. Node 18 or newer, or a browser with `fetch`.

## Install

The file is the install. Download it and import it:

```sh
curl -fsSL https://fixragent.com/sdk/js/index.mjs -o fixragent-triage.mjs
```

The same file is the `@fixragent/triage` package; the `npm install @fixragent/triage` line lands here with the first publish, and the import below stays the same.

## Triage a photo

```js
import { triage, FixragentError } from './fixragent-triage.mjs';
import { readFile } from 'node:fs/promises';

const reply = await triage(await readFile('photo.jpg'), {
  key: process.env.TRIAGE_DEMO_KEY,   // sent as x-triage-key
  config: 'fast',                     // 'fast' reads the photo three times, 'deep' five
  problemText: 'Water on the floor under the heater.',
});

console.log(reply.core.tier, reply.core.trade_required, reply.core.resident_explanation);
// e.g. TODAY Plumber "There is water on the floor under the heater …"
console.log(reply.agreement);         // { mode: 'fast', n: 3, k: 3, decided: true, … }
console.log(reply.diagnosis_id);      // keep it: the Triage Profile is https://fixragent.com/c/<diagnosis_id>
```

`photo` is a `Buffer`, a `Uint8Array`, an `ArrayBuffer`, a base64 string or a `data:image/…;base64,` URL (JPEG, PNG or WebP, 1 KB to 3 MB decoded). The reply is the API's own JSON — `core` carries the twenty fixed fields, `agreement` says how many independent reads agreed, `callback_url` is where the outcome goes. Every field is typed in `types.d.ts`, generated from the published OpenAPI document.

Read three fields first: `core.tier` (one of `EMERGENCY`, `TODAY`, `THIS WEEK`, `WHENEVER`, assigned in code from fixed rules), `core.trade_required`, and `core.resident_explanation`.

### Spanish

```js
const reply = await triage(photo, { key, lang: 'es' });
```

`lang: 'es'` answers with the prose fields — `fault_summary`, `photo_subject`, `asset_type`, `trade_required`, `resident_explanation` — in Spanish. `hazard_detail` stays in English, on purpose: the hazard line is never machine-translated. `reply.language` says what was served.

### Options

| option | values | default |
|---|---|---|
| `key` | your demo key | — (required on production) |
| `config` | `'fast'` (three reads) · `'deep'` (five reads) | `'fast'` |
| `extended` | `true` adds the `extended` block | `false` |
| `mimeType` | `'image/jpeg'` · `'image/png'` · `'image/webp'` | `'image/jpeg'`, or the type in a data URL |
| `problemText` | the reporter's own words, up to 1,200 characters | — |
| `reporter` | `'resident'` · `'assessor'` · `'technician'` | — |
| `lang` | `'en'` · `'es'` | — |
| `variant` | up to 40 characters, stored on the row | `'source:sdk-js'` |
| `baseUrl` | the API base | `https://fixragent.com` |
| `fetch` | an injected `fetch` | `globalThis.fetch` |
| `signal` | an `AbortSignal` | — |

## Report what happened

```js
import { reportOutcome } from './fixragent-triage.mjs';

await reportOutcome({ callbackUrl: reply.callback_url, outcome: 'fixed', fixedBy: 'pro', trade: 'plumber' });
```

`outcome` is `fixed`, `not_fixed` or `partial`. Photo, triage, what actually happened — that loop is the point.

## Errors

A reply the API refused throws a `FixragentError`:

```js
try {
  await triage(photo, { key });
} catch (e) {
  if (e instanceof FixragentError) {
    console.log(e.status, e.code, e.message, e.retryAfter);
    // 429 rate_limited "…" 1800   — the guard that stopped you, in a sentence, with the seconds to wait
  }
}
```

`code` is the API's own `error` value (`demo_key_required`, `rate_limited`, `demo_key_quota`, `budget_exhausted`, `image_too_large`, …), `message` its plain-words sentence, `retryAfter` the `Retry-After` header in seconds when one was set.

## Try it without a key

Point `baseUrl` at the mock, which replays captured replies and runs no engine:

```js
const reply = await triage(photo, { baseUrl: 'https://b1442b0b-4a7a-4135-ab4d-9c4b9c1ab0d2.mock.pstmn.io' });
```

The mock takes a request body of up to 1 MB, so send it a small copy of the photo. Details: https://fixragent.com/docs#mock.

## The key

Ask at https://fixragent.com/docs#key, or email legal@fixragent.com with one line on what you are building, and a person replies with your key. A demo key carries 60 requests a day; one address gets 20 an hour.

## The rest

- The reference, field by field: https://fixragent.com/docs
- OpenAPI: https://fixragent.com/openapi.json · Postman: https://fixragent.com/docs/fixragent-triage-api.postman_collection.json
- The Python client: https://fixragent.com/sdk/python/fixragent_triage/__init__.py · The MCP tool: https://fixragent.com/mcp/README.md
- Terms for the API: https://fixragent.com/api-terms — the reply is an educational triage for routing; gas, water near electrics and exposed wiring go straight to a licensed trade.
