# Ky quick start

Install Ky, send a JSON request, consume its response, and handle an HTTP failure.

Ky builds on the Fetch API, so you use standard Fetch inputs and options with Ky's additional options.

## Prerequisites

Use Node.js 22 or later and npm for this tutorial. Ky also targets modern browsers, Bun, and Deno; no framework is required. The examples use JavaScript ES modules and absolute URLs so you can run them in Node.

## 1. Install Ky

Run this command in your project:

```bash
npm install ky
```

Import the default export as [`ky`](https://bench-ky-61.atloria.app/p/bench-ky-61-6TqdzXtmKC/developer/ky#default). You do not need to construct a client before making a request.

## 2. Send JSON and consume the response

Save this as `request.mjs`. It sends a POST request to HTTPBin's inspection endpoint and logs the parsed response body.

```js title="request.mjs"
import ky from 'ky';

async function main() {
	const json = await ky.post('https://httpbin.org/anything', {
		json: {foo: true},
	}).json();

	console.log(json);
}

void main();
```

Run it:

```bash
node request.mjs
```

Look for your outgoing JSON in the service's response. The `json` option serializes `{foo: true}` with `JSON.stringify()` and sets `Content-Type` to `application/json` unless you override that header through `headers`.

The `.json()` shortcut parses the incoming response without first awaiting a `Response`. It also sets an appropriate `Accept` header. In TypeScript, its result defaults to `unknown`; see [Send and validate JSON](https://bench-ky-61.atloria.app/p/bench-ky-61-6TqdzXtmKC/developer/send-and-validate-json) for typed and validated responses.

If you need status or headers before reading the body, await the request instead:

```js title="response.mjs"
import ky from 'ky';

async function main() {
	const response = await ky.get('https://httpbin.org/anything');
	console.log(response.status, response.headers.get('content-type'));

	const json = await response.json();
	console.log(json);
}

void main();
```

Run `node response.mjs` to inspect the response metadata and parsed JSON separately.

## 3. Handle an HTTP failure

By default, a non-2xx response throws an [`HTTPError`](https://bench-ky-61.atloria.app/p/bench-ky-61-6TqdzXtmKC/developer/ky-httperror#httperror). Use [`isHTTPError`](https://bench-ky-61.atloria.app/p/bench-ky-61-6TqdzXtmKC/developer/ky#ishttperror) to narrow the caught error before accessing its response.

Save this as `failure.mjs`. It adds HTTP-failure handling to the JSON request:

```js title="failure.mjs"
import ky, {isHTTPError} from 'ky';

async function main() {
	try {
		const json = await ky.post('https://httpbin.org/anything', {
			json: {foo: true},
		}).json();
		console.log(json);
	} catch (error) {
		if (isHTTPError(error)) {
			console.error('HTTP error status:', error.response.status);
			console.error('Error body:', error.data);
		} else {
			throw error;
		}
	}
}

void main();
```

Run `node failure.mjs`. A successful request logs the parsed JSON. If the service rejects the request with a non-2xx response, the HTTP-error branch logs its status and any available error data. Other failures are rethrown rather than treated as HTTP responses. For error-body handling and retry implications, continue to [Handle request errors](https://bench-ky-61.atloria.app/p/bench-ky-61-6TqdzXtmKC/developer/handle-request-errors).

## What you have

You now have a JSON POST request, two ways to consume a successful response, and an HTTP-failure handler using Ky's type guard.

- Read [How Ky works](https://bench-ky-61.atloria.app/p/bench-ky-61-6TqdzXtmKC/developer/how-ky-works) for the core ideas.
- Use [Instances and defaults](https://bench-ky-61.atloria.app/p/bench-ky-61-6TqdzXtmKC/developer/instances-and-defaults) to share request options.
- See [Retry failed requests](https://bench-ky-61.atloria.app/p/bench-ky-61-6TqdzXtmKC/developer/retry-failed-requests) to control retry behavior.
