npm package: @shanecode/metascrape
Description: Official Node.js client for the MetaScrape API — extract metadata from any URL in one call
Author: Shane Code
Latest version: 1.0.1

# @shanecode/metascrape

Official Node.js client for the **MetaScrape API** -- extract metadata from any URL in one call.

Get Open Graph tags, Twitter Cards, favicons, canonical URLs, and more with a single request. Zero dependencies. Works with Node.js 18+ and any runtime that supports `fetch`.

## Install

```bash
npm install @shanecode/metascrape
```

## Quick Start

```javascript
import { MetaScrape } from '@shanecode/metascrape';

const ms = new MetaScrape('your-api-key');

const meta = await ms.extract('https://example.com');
console.log(meta.title);       // "Example Domain"
console.log(meta.og_image);    // "https://example.com/image.png"
console.log(meta.description); // "An example website"
```

## Getting an API Key

1. Sign up at [metascrape.shanecode.org](https://metascrape.shanecode.org)
2. Your API key is returned on login

Or use the SDK directly:

```javascript
import { MetaScrape } from '@shanecode/metascrape';

// Create an account
await MetaScrape.signup('you@example.com', 'your-password');

// Login to get your API key
const { api_key } = await MetaScrape.login('you@example.com', 'your-password');
console.log(api_key); // Use this for all authenticated requests
```

## API Reference

### `new MetaScrape(apiKey, options?)`

Create a client instance.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `apiKey` | `string` | *required* | Your MetaScrape API key |
| `options.baseUrl` | `string` | `https://api.shanecode.org` | API base URL |

### `ms.extract(url)`

Extract metadata from a URL. Returns the metadata object directly (envelope is unwrapped).

```javascript
const meta = await ms.extract('https://github.com');
```

**Returns:**

| Field | Type | Description |
|-------|------|-------------|
| `title` | `string` | Page title |
| `description` | `string` | Meta description |
| `og_title` | `string` | Open Graph title |
| `og_description` | `string` | Open Graph description |
| `og_image` | `string` | Open Graph image URL |
| `twitter_card` | `string` | Twitter card type |
| `twitter_title` | `string` | Twitter title |
| `twitter_description` | `string` | Twitter description |
| `twitter_image` | `string` | Twitter image URL |
| `favicon` | `string` | Favicon URL |
| `canonical` | `string` | Canonical URL |
| `language` | `string` | Page language |

### `ms.usage()`

Get your current month's API usage.

```javascript
const usage = await ms.usage();
console.log(`${usage.used} / ${usage.limit} requests used`);
```

**Returns:** `{ plan, used, limit, remaining }`

### `MetaScrape.signup(email, password, options?)`

Static method. Create a new account. No API key required.

```javascript
await MetaScrape.signup('you@example.com', 'secure-password');
```

### `MetaScrape.login(email, password, options?)`

Static method. Login and retrieve your API key. No API key required.

```javascript
const { api_key } = await MetaScrape.login('you@example.com', 'secure-password');
```

## Error Handling

The client throws descriptive errors for non-2xx responses:

```javascript
try {
  const meta = await ms.extract('https://example.com');
} catch (err) {
  console.error(err.message);
  // "MetaScrape API error (401): invalid API key"
  // "MetaScrape API error (429): rate limit exceeded"
}
```

## Pricing

| Plan | Requests/month | Price |
|------|---------------|-------|
| Free | 100 | $0 |
| Hobby | 1,000 | $9/mo |
| Growth | 10,000 | $29/mo |
| Business | 100,000 | $79/mo |

Start free at [metascrape.shanecode.org](https://metascrape.shanecode.org).

## Links

- [Full Documentation](https://metascrape.shanecode.org)
- [Sign Up / Get API Key](https://metascrape.shanecode.org)
- [ShaneCode](https://shanecode.org)

## License

MIT -- see [LICENSE](./LICENSE)

---

Built by [ShaneCode](https://shanecode.org) -- https://shanecode.org