> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snipp.gg/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js

> Official Node.js wrapper for the Snipp API.

<Card horizontal icon="github" href="https://github.com/snipp-gg/snipp-js">
  snipp-gg/snipp-js
</Card>

<Card horizontal icon="npm" href="https://npmjs.com/package/@snipp-gg/snipp">
  @snipp-gg/snipp
</Card>

## Installation

```bash theme={null}
npm install @snipp-gg/snipp
```

Requires Node.js 18 or later. Zero dependencies. Uses native `fetch` and `FormData`.

## Getting Started

```javascript theme={null}
import { SnippClient } from "@snipp-gg/snipp";

const client = new SnippClient({ apiKey: process.env.SNIPP_API_KEY });

const me = await client.getUser("@me");
console.log(me.user.username);
```

## Methods

### `getUser(id, options?)`

Fetch a user by ID. Pass `"@me"` for the authenticated user.

| Option         | Type      | Description                          |
| -------------- | --------- | ------------------------------------ |
| `includePosts` | `boolean` | Include the user's public uploads.   |
| `postsLimit`   | `number`  | Number of posts to return (1 to 50). |

```javascript theme={null}
const user = await client.getUser("@me", { includePosts: true, postsLimit: 10 });
```

### `getPost(code)`

Fetch a post by its share code.

```javascript theme={null}
const post = await client.getPost("AbCd1234");
console.log(post.post.url);
```

### `upload(file, options?)`

Upload a file. Accepts a `File`, `Blob`, `Buffer`, or `Uint8Array`.

| Option        | Type                                  | Description                                                                       |
| ------------- | ------------------------------------- | --------------------------------------------------------------------------------- |
| `privacy`     | `"public" \| "unlisted" \| "private"` | Visibility of the upload.                                                         |
| `filename`    | `string`                              | Filename sent with the upload (defaults to `"upload"`).                           |
| `title`       | `string`                              | Optional post title (max 30 chars).                                               |
| `description` | `string`                              | Optional post description (max 200 chars).                                        |
| `postType`    | `"album" \| "individual"`             | `album` (default) or `individual`. Only applies when uploading two or more files. |

```javascript theme={null}
import { readFileSync } from "node:fs";

const buffer = readFileSync("./image.png");
const result = await client.upload(buffer, { privacy: "unlisted", filename: "image.png" });
console.log(result.url);
```

### `listUploads(options?)`

List the authenticated user's recent uploads. Defaults to 30. Pass `limit` to control the count (max 1000).

| Option  | Type     | Description                         |
| ------- | -------- | ----------------------------------- |
| `limit` | `number` | Maximum uploads to return (1-1000). |

```javascript theme={null}
const uploads = await client.listUploads({ limit: 100 });
```

### `editUpload(code, options)`

Edit an existing upload's title, description, or privacy.

| Option        | Type                                  | Description                                             |
| ------------- | ------------------------------------- | ------------------------------------------------------- |
| `title`       | `string`                              | New title (max 30 chars). Empty string to clear.        |
| `description` | `string`                              | New description (max 200 chars). Empty string to clear. |
| `privacy`     | `"public" \| "unlisted" \| "private"` | New visibility setting.                                 |

```javascript theme={null}
await client.editUpload("AbCd1234", { title: "New title", privacy: "public" });
```

### `appendUpload(code, files, options?)`

Add one or more files to an existing album post. The post's share code, privacy, title, and description are preserved. Albums cap at 9 files total. Requests that would exceed the cap are rejected. New files inherit the post's privacy. Returned URLs are signed with a 24-hour expiry for private posts.

| Parameter           | Type                                          | Description                          |
| ------------------- | --------------------------------------------- | ------------------------------------ |
| `code`              | `string`                                      | Share code of the post to append to. |
| `files`             | `Array<File \| Blob \| Buffer \| Uint8Array>` | One or more files to append.         |
| `options.filenames` | `string[]`                                    | Optional filenames (one per file).   |

```javascript theme={null}
import { readFileSync } from "node:fs";

const a = readFileSync("./photo-a.png");
const b = readFileSync("./photo-b.png");

const result = await client.appendUpload("AbCd1234", [a, b], {
  filenames: ["photo-a.png", "photo-b.png"],
});
console.log(result.post.fileCount);
```

### `deleteUpload(filename)`

Delete an upload by its filename. On albums, only that file is removed; on single-file posts the entire post is deleted.

```javascript theme={null}
await client.deleteUpload("a3f7b2c91d4e8f0612ab34cd56ef7890.png");
```

## Error Handling

All API errors throw a `SnippError` with `status` and `message` properties.

```javascript theme={null}
import { SnippClient, SnippError } from "@snipp-gg/snipp";

try {
  await client.getUser("nonexistent");
} catch (err) {
  if (err instanceof SnippError) {
    console.error(err.status, err.message);
  }
}
```
