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:
bashnpm install ky
Import the default export as ky. 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.
jsimport 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:
bashnode 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 for typed and validated responses.
If you need status or headers before reading the body, await the request instead:
jsimport 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. Use isHTTPError to narrow the caught error before accessing its response.
Save this as failure.mjs. It adds HTTP-failure handling to the JSON request:
jsimport 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.
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 for the core ideas.
- Use Instances and defaults to share request options.
- See Retry failed requests to control retry behavior.
Was this page helpful?