# Overview

> Base URL, credential format, scopes, rate limits, and a five-step quickstart.

Source: https://sndr.sh/docs/cranl/overview

The SNDR Partner API lets your platform act on behalf of SNDR users — sending transactional emails, managing contacts, domains, templates, broadcasts, webhooks, and more — via a standard OAuth 2.0 Authorization Code flow.

> **Note:** Credentials are admin-issued. There is no self-service registration. Contact your SNDR account manager to receive a client_id and a one-time client_secret.

## Base URL

```bash
https://api.sndr.sh
```

## Quickstart

### 1. Get credentials

SNDR issues your `client_id` and a one-time `client_secret`. Store the secret in a vault; it can’t be shown again.

### 2. Send the user to SNDR

Redirect to `GET /api/cranl/oauth/authorize` with `client_id`, `redirect_uri`, `scope`, `state` and, ideally, a PKCE `code_challenge`.

### 3. The user approves

They sign in to SNDR if needed and approve your app on the consent page.

### 4. Handle the callback

SNDR redirects to your `redirect_uri` with a short-lived `code` and your `state`. Check that `state` matches.

### 5. Get tokens

From your backend, `POST /api/cranl/oauth/token` to exchange the code for an `access_token` and a `refresh_token`.

### 6. Call the API

Send `Authorization: Bearer <access_token>` to any `/api/cranl/v1` endpoint.

## Discovery (RFC 8414)

Fetch server metadata at startup rather than hardcoding endpoint URLs. Public — no authentication required.

```bash
curl 'https://api.sndr.sh/.well-known/oauth-authorization-server'
```

```json
{
  "issuer":                                "https://api.sndr.sh",
  "authorization_endpoint":               "https://app.sndr.sh/cranl/authorize",
  "token_endpoint":                        "https://api.sndr.sh/api/cranl/oauth/token",
  "revocation_endpoint":                   "https://api.sndr.sh/api/cranl/oauth/revoke",
  "scopes_supported":                      ["read", "send"],
  "response_types_supported":              ["code"],
  "grant_types_supported":                 ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported":      ["S256"],
  "token_endpoint_auth_methods_supported": ["client_secret_post"]
}
```

## Scopes

| Scope | Allows |
| --- | --- |
| `read` | All `GET` endpoints: emails, analytics, domains, templates, contacts, contact groups, broadcasts, webhooks, suppressions. |
| `send` | Sending email, and creating, updating or deleting any resource above. |

## Credential format

All credentials (client_id, client_secret, access_token, refresh_token) share the format sndr_<32 alphanumeric characters> — 37 characters total.

## Rate limits

| Path | Limit |
| --- | --- |
| `/api/cranl/oauth/*` | 30 requests a minute per IP. |
| `/api/cranl/v1/*` | 300 requests a minute per IP. Over the limit you get `429` with a plain-text body and a `Retry-After` header. |

- Resource quotas come from the connected user's SNDR plan. A full plan cap (domains, templates, webhooks) returns 402 plan_limit_reached; a used-up monthly email quota returns 402 quota_exceeded.
