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

# API Introduction

> Everything you need to know about the SnowSEO REST API — how to connect, what to expect, and how errors work.

The **SnowSEO API** lets you access your SEO data programmatically. Use it to run audits, check keyword rankings, fetch analytics, or embed SnowSEO data into your own dashboards, scripts, and integrations.

<Info>
  The API is available on the **Scale plan**. Generate API keys from **Settings → Integrations → API** in your dashboard. Each key is scoped to a specific brand — one key per brand.
</Info>

***

## Base URL

All API requests go to this base URL:

```
https://api.snowseo.com/v3
```

Every response is **JSON**. Send request bodies as JSON with the `Content-Type: application/json` header.

***

## What You Can Do With the API

| Use Case                | Example                                                        |
| ----------------------- | -------------------------------------------------------------- |
| **Run site audits**     | Check any website's SEO health score and get detailed findings |
| **Track keywords**      | Add, list, and monitor keyword rankings over time              |
| **Fetch traffic data**  | Pull GSC and Google Analytics metrics for your articles        |
| **Manage articles**     | List, create, and publish content via connected CMS            |
| **Read brand settings** | Pull brand info, target audience, and competitors              |
| **Build dashboards**    | Pipe SnowSEO data into your own BI tools or internal reports   |

***

## Authentication

All endpoints require an API key in the `Authorization` header:

```
Authorization: Bearer sk_your_key_here
```

Keys start with `sk_` and are generated in **Settings → Integrations → API**. See the [Authentication guide](/docs/api-reference/authentication) for full details on creating keys, scoping, and security best practices.

***

## How to Make a Request

Here's the typical pattern for any API call:

```bash theme={null}
# 1. Choose an endpoint
# 2. Set the Authorization header
# 3. Send JSON body (for POST/PUT requests)

curl -X POST https://api.snowseo.com/v3/website-audit \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "example.com"}'
```

For `GET` requests, pass parameters as query strings:

```bash theme={null}
curl "https://api.snowseo.com/v3/rank-tracking/keywords" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

***

## Your First Integration

Here's a minimal Node.js example to get you started:

```javascript theme={null}
const SNOWSEO_API_KEY = process.env.SNOWSEO_API_KEY;
const BASE_URL = 'https://api.snowseo.com/v3';

async function auditSite(url) {
  const response = await fetch(`${BASE_URL}/website-audit`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${SNOWSEO_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ url }),
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }

  return response.json();
}

// Run it
auditSite('example.com').then(data => {
  console.log(`SEO Score: ${data.seoAudit.overallScore}/100`);
});
```

<Note>
  The API key carries your brand context automatically — no need to pass `teamId` as a query parameter.
</Note>

***

## Endpoints Overview

The API is organized into these categories:

| Group                   | Description                                   |
| ----------------------- | --------------------------------------------- |
| **Website Analysis**    | Audits, health scores, and page findings      |
| **Keywords & Research** | Keyword research, suggestions, search history |
| **Traffic & Analytics** | GSC and Google Analytics data                 |
| **Rank Tracking**       | Tracked keywords, position history, changes   |
| **Content**             | Article management and CMS integration        |
| **Dashboard**           | Activity feed and overview data               |
| **Settings**            | Brand settings and configuration              |

Browse all endpoints using the navigation on the left.

***

## Response Format

All responses follow a consistent structure. Successful responses return the data directly:

```json theme={null}
{
  "url": "https://example.com",
  "seoAudit": {
    "overallScore": 87,
    "totalTests": 32,
    "passedTests": 28
  }
}
```

Error responses always include an `error` field with a human-readable message (there are no machine-readable error codes):

```json theme={null}
{
  "success": false,
  "error": "Team not found"
}
```

***

## Rate Limits

Limits vary by endpoint — up to 60 requests per minute per endpoint, while heavier endpoints may have stricter caps.

When rate limited, the API returns `429` with a `retryAfterSeconds` hint:

```json theme={null}
{
  "success": false,
  "statusCode": 429,
  "code": "Too Many Requests",
  "error": "Rate limit exceeded.",
  "message": "Rate limit exceeded.",
  "retryAfterSeconds": 60
}
```

**Handling rate limits:**

* Wait for the number of seconds indicated by `retryAfterSeconds`
* If you don't have a `retryAfterSeconds` value, use exponential backoff (1s, 2s, 4s, 8s...)
* If you're regularly hitting the limit, batch your requests or add delays between calls

***

## Error Handling

The API uses standard HTTP status codes:

| Code  | Meaning                                              |
| ----- | ---------------------------------------------------- |
| `200` | Success                                              |
| `201` | Created                                              |
| `400` | Bad request — check your parameters                  |
| `401` | Unauthorized — invalid or missing API key            |
| `403` | Forbidden — valid key but no access to this resource |
| `404` | Not found                                            |
| `429` | Rate limited                                         |
| `500` | Internal error — something went wrong on our end     |
| `503` | Service unavailable — try again later                |

Always check both the HTTP status code and the `error` field in the response body:

```javascript theme={null}
const response = await fetch(url, options);

if (!response.ok) {
  const error = await response.json();
  console.log(error.error);    // Human-readable message, e.g. "Rate limit exceeded."
  console.log(error.message);   // Same human-readable description
  // Handle accordingly
}
```

***

## Testing with cURL

The quickest way to test the API is with cURL from your terminal:

```bash theme={null}
# Check your API key is working
curl https://api.snowseo.com/v3/rank-tracking/keywords \
  -H "Authorization: Bearer YOUR_KEY"

# Run a site audit
curl -X POST https://api.snowseo.com/v3/website-audit \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "example.com"}'

# List tracked keywords
curl https://api.snowseo.com/v3/rank-tracking/keywords \
  -H "Authorization: Bearer YOUR_KEY"
```

***

## SDKs & Client Libraries

Currently, the API is raw HTTP — no official SDK yet. The authentication guide has examples in Node.js and Python that you can copy into your project.

If you build a client library, let us know and we can list it here.

***

## Need Help?

* **Errors?** Check the [error handling section](/docs/api-reference/authentication#error-handling) in the Authentication guide.
* **Questions?** Email [support@snowseo.com](mailto:support@snowseo.com).
* **Bugs or missing features?** Open an issue on our [GitHub](https://github.com/Snow-SEO).
