> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.zata.prathamchopde.site/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.zata.prathamchopde.site/_mcp/server.

# JavaScript and Node.js

The AWS SDK for JavaScript v3 (`@aws-sdk/client-s3`) works with Zata. Point the client at the Zata endpoint, and you can use the normal S3 commands from Node.js.

> **Info**
>
> Tested with @aws-sdk/client-s3 3.1095.0 on Zata in October 2026.

## Before you start

* A bucket. See [Create a bucket](/buckets/create-a-bucket).
* An access key and secret key from the same region as the bucket. See [Access keys](/access/access-keys).
* Node.js with the SDK installed:

  ```bash
  npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
  ```

  You need `@aws-sdk/s3-request-presigner` only for [download and upload links](#make-a-download-or-upload-link).

## Connection settings

| Setting                                                     | Value                                                                                                                   |
| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `endpoint`                                                  | `https://idr01.zata.ai` for Indore, `https://bom01.zata.ai` for Mumbai                                                  |
| `region`                                                    | `us-east-1`                                                                                                             |
| `credentials`                                               | access key and secret key from **Access Keys** in the Zata console. The key must be from the same region as the bucket. |
| `forcePathStyle`                                            | `true`                                                                                                                  |
| `requestChecksumCalculation` / `responseChecksumValidation` | `"WHEN_REQUIRED"`                                                                                                       |

## Create the client

Keep your keys out of the code. Put them in the environment variables `ZATA_ACCESS_KEY` and `ZATA_SECRET_KEY`, then create the client. For a bucket in Mumbai, use `https://bom01.zata.ai`.

```js
import { S3Client } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: "https://idr01.zata.ai",
  region: "us-east-1",
  forcePathStyle: true,
  requestChecksumCalculation: "WHEN_REQUIRED",
  responseChecksumValidation: "WHEN_REQUIRED",
  credentials: {
    accessKeyId: process.env.ZATA_ACCESS_KEY,
    secretAccessKey: process.env.ZATA_SECRET_KEY,
  },
});
```

The two checksum settings are needed from SDK version 3.729 (January 2025): without them, large uploads fail with `XAmzContentSHA256Mismatch`.

The examples on this page use ES modules (`import`) and top-level `await`: save them in a `.mjs` file, or set `"type": "module"` in `package.json`.

## Upload and list files

```js
import { PutObjectCommand, ListObjectsV2Command } from "@aws-sdk/client-s3";
import { readFile } from "node:fs/promises";

await s3.send(new PutObjectCommand({
  Bucket: "my-bucket",
  Key: "folder/myfile.txt",
  Body: await readFile("myfile.txt"),
}));

const { Contents = [] } = await s3.send(new ListObjectsV2Command({ Bucket: "my-bucket", Prefix: "folder/" }));
console.log(Contents.map((o) => o.Key));
```

## Download a file

```js
import { GetObjectCommand } from "@aws-sdk/client-s3";
import { writeFile } from "node:fs/promises";

const res = await s3.send(new GetObjectCommand({ Bucket: "my-bucket", Key: "folder/myfile.txt" }));
await writeFile("myfile-copy.txt", await res.Body.transformToByteArray());
```

## List your buckets

```js
import { ListBucketsCommand } from "@aws-sdk/client-s3";

const { Buckets = [] } = await s3.send(new ListBucketsCommand({}));
console.log(Buckets.map((b) => b.Name));
```

A sub-user's key gets an empty list here, even for buckets it can use. Use the bucket name directly.

## Make a download or upload link

A presigned URL lets someone download or upload one file without keys, until the link expires. `expiresIn` is in seconds.

```js
import { GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const downloadUrl = await getSignedUrl(
  s3,
  new GetObjectCommand({ Bucket: "my-bucket", Key: "folder/myfile.txt" }),
  { expiresIn: 3600 },
);

const uploadUrl = await getSignedUrl(
  s3,
  new PutObjectCommand({ Bucket: "my-bucket", Key: "upload.txt" }),
  { expiresIn: 3600 },
);
```

If you set a `ContentType` in the `PutObjectCommand`, the upload must send exactly that `Content-Type` header, or Zata answers `403`. Anyone who has a link can use it until it expires, so share it only with the intended person.

## Troubleshooting

| Problem                                                               | Fix                                                                                                                                                                                  |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Large uploads fail with `XAmzContentSHA256Mismatch`; small files work | Add `requestChecksumCalculation` and `responseChecksumValidation` set to `"WHEN_REQUIRED"`.                                                                                          |
| `InvalidAccessKeyId`                                                  | `endpoint` is missing (requests go to AWS), or the key is from the other region.                                                                                                     |
| `NoSuchBucket` for a bucket you can see in the console                | Use the endpoint of the region the bucket is in.                                                                                                                                     |
| Calling Zata from a web page in the browser fails (CORS)              | Browser access needs CORS rules for your site. See [Browser and SDK access](/access/browser-access). Do not put keys in browser code: create presigned links on your server instead. |

Never set `NODE_TLS_REJECT_UNAUTHORIZED=0`: Zata's certificates are valid. For other errors, see [Large uploads](/help/troubleshooting/large-uploads) and [Wrong endpoint or region](/help/troubleshooting/endpoint-and-region).