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

# TypeScript SDK

> Official TypeScript/JavaScript SDK for the Gumnut API

The official Gumnut TypeScript SDK provides full type safety and works seamlessly in both Node.js and browser environments.

## Installation

```bash theme={null}
npm install gumnut-sdk
# or
yarn add gumnut-sdk
# or
pnpm add gumnut-sdk
```

## Quick Start

```typescript theme={null}
import Gumnut from 'gumnut-sdk';

const client = new Gumnut({
  apiKey: process.env.GUMNUT_API_KEY
});

// Upload an asset
const asset = await client.assets.create({
  asset_data: fs.createReadStream('photo.jpg'),
  device_asset_id: 'photo_001',
  device_id: 'my_device',
  file_created_at: new Date().toISOString(),
  file_modified_at: new Date().toISOString()
});

// Create an album
const album = await client.albums.create({
  album_name: 'Vacation 2024',
  description: 'Summer vacation photos'
});

// Add asset to album
await client.albums.addAssets(album.id, {
  asset_ids: [asset.id]
});
```

## Location-based browsing

Once you've initialized a client, you can use the same location filters as the REST API to power map-style browsing.

```typescript theme={null}
const viewport = '-77.1,38.9,-77.0,39.0';

// List the individual assets inside a bounding box.
const page = await client.assets.list({
  bbox: viewport,
  limit: 100,
});

// Or search around a single point instead of a rectangle.
const nearby = await client.assets.list({
  center: '-77.05,38.95',
  radius: 1000,
  limit: 100,
});

// Summarize the viewport into map-friendly clusters.
const clusters = await client.assets.clusterByGeo({
  bbox: viewport,
  cell_size: 0.01,
});

for (const cluster of clusters.data) {
  console.log(cluster.count, cluster.latitude, cluster.longitude);
}
```

Use either `bbox` or `center` + `radius` on `client.assets.list()`, not both. If a dense viewport returns `422` from `client.assets.clusterByGeo()`, increase `cell_size` or zoom in and retry. For the HTTP equivalents and filter details, see [Pagination & Filtering](../apis/pagination-and-filtering#filtering-by-location) and [Map views with geo clusters](../apis/pagination-and-filtering#map-views-with-geo-clusters).

## Key Features

* **Full TypeScript Support**: Complete type definitions for all API endpoints
* **Universal Compatibility**: Works in Node.js 16+ and modern browsers
* **Automatic Retries**: Built-in exponential backoff for failed requests
* **File Upload Helpers**: Support for various file formats (File, Buffer, Stream)
* **Streaming Support**: Handle large responses efficiently
* **Tree-shakeable**: Optimized bundle size for frontend applications

## File Upload Options

Multiple ways to upload files:

```typescript theme={null}
// File stream (Node.js)
import fs from 'fs';
const asset = await client.assets.create({
  asset_data: fs.createReadStream('photo.jpg'),
  device_asset_id: 'unique_id',
  device_id: 'my_device'
});

// Buffer with helper
import { toFile } from 'gumnut-sdk';
const asset = await client.assets.create({
  asset_data: await toFile(buffer, 'photo.jpg'),
  device_asset_id: 'unique_id', 
  device_id: 'my_device'
});

// Fetch response
const asset = await client.assets.create({
  asset_data: await fetch('https://example.com/photo.jpg'),
  device_asset_id: 'unique_id',
  device_id: 'my_device'
});

// Web File API (browser)
const asset = await client.assets.create({
  asset_data: new File([bytes], 'photo.jpg'),
  device_asset_id: 'unique_id',
  device_id: 'my_device'
});
```

## Configuration

```typescript theme={null}
const client = new Gumnut({
  apiKey: process.env.GUMNUT_API_KEY,
  maxRetries: 3, // Default retry count
  timeout: 60000 // Request timeout in milliseconds
});
```

## Error Handling

```typescript theme={null}
import { APIError } from 'gumnut-sdk';

try {
  const asset = await client.assets.get('invalid_id');
} catch (error) {
  if (error instanceof APIError) {
    console.log(`API Error: ${error.status} - ${error.message}`);
    if (error.status === 429) {
      console.log(`Rate limited. Retry after: ${error.retryAfter}s`);
    }
  }
}
```

## Repository & Documentation

**GitHub Repository**: [github.com/gumnut-ai/photos-sdk-typescript](https://github.com/gumnut-ai/photos-sdk-typescript)

For complete API documentation, examples, and advanced usage:

* [Full API Reference](https://github.com/gumnut-ai/photos-sdk-typescript/blob/main/api.md)
* [Examples Directory](https://github.com/gumnut-ai/photos-sdk-typescript/tree/main/examples)
* [Changelog](https://github.com/gumnut-ai/photos-sdk-typescript/blob/main/CHANGELOG.md)

## Browser Usage

The SDK works in browsers with proper bundling:

```javascript theme={null}
import Gumnut from 'gumnut-sdk';

// Use OAuth token, not API key in browser
const client = new Gumnut({
  apiKey: oauthToken // Get from your OAuth flow
});

// Upload from file input
const fileInput = document.getElementById('file');
const file = fileInput.files[0];

const asset = await client.assets.create({
  asset_data: file,
  device_asset_id: `browser_${Date.now()}`,
  device_id: 'web_client'
});
```

## Next Steps

* Check the [GitHub repository](https://github.com/gumnut-ai/photos-sdk-typescript) for detailed documentation
* Review the [API Reference](https://github.com/gumnut-ai/photos-sdk-typescript/blob/main/api.md) for all available methods
* See [Authentication](../authentication/overview) for setup options
* Explore other [SDK options](./overview) for different languages
