Quickstart

Search Documentation

Search across all developer documentation

Quickstart

This guide takes you from zero to a successful API call against your SendOps data. Plan on five minutes.

Not a send API

The SendOps API does not send mail. Your application keeps calling AWS SES directly — the SendOps API lets you read what happened after.

What you need

  • A SendOps account.
  • Permission to manage API keys in your org (Owner or Admin role by default).
  • A working terminal with curl, or a runtime in one of the languages below.

Create a key in the dashboard

Open Settings → API Keys and click New API Key.

  • Give it a recognizable name (e.g. local-dev, production-readme).
  • Choose Live unless you specifically want test-quota behaviour.
  • Select scopes. For this quickstart you only need api.reports.view.

When you submit, the raw key is shown once. Copy it now — there is no way to retrieve it later.

Verify the key with the meta endpoint

The _health endpoint costs nothing and is the fastest way to confirm a key works.

curl -i https://api.sendops.dev/v1/_health \
-H "Authorization: Bearer sk_live_..."

A successful response looks like:

HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 599
X-RateLimit-Reset: 60

{"status":"ok","version":"v1"}

If you see 401, the key is malformed or revoked. If you see 403, the key is valid but is missing the scope the endpoint requires.

Fetch your first useful response

Now pull a deliverability snapshot for the last 7 days. This requires api.reports.view.

curl -s 'https://api.sendops.dev/v1/reports/deliverability?range=7d' \
-H "Authorization: Bearer sk_live_..." | jq
const res = await fetch(
"https://api.sendops.dev/v1/reports/deliverability?range=7d",
{ headers: { Authorization: `Bearer ${process.env.SENDOPS_API_KEY}` } }
)
if (!res.ok) {
const problem = await res.json()
throw new Error(`${problem.title}: ${problem.detail ?? ""}`)
}
const data = await res.json()
console.log(data)
import os, requests

r = requests.get(
  "https://api.sendops.dev/v1/reports/deliverability",
  params={"range": "7d"},
  headers={"Authorization": f"Bearer {os.environ['SENDOPS_API_KEY']}"},
  timeout=10,
)
r.raise_for_status()
print(r.json())
package main

import (
"encoding/json"
"fmt"
"net/http"
"os"
)

func main() {
req, _ := http.NewRequest("GET", "https://api.sendops.dev/v1/reports/deliverability?range=7d", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SENDOPS_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
	panic(err)
}
defer resp.Body.Close()
var out map[string]any
json.NewDecoder(resp.Body).Decode(&out)
fmt.Printf("%+v\n", out)
}

Paginate a list endpoint

/v1/messages returns up to 50 items per page by default. The Link header advances the cursor.

curl -s -D - 'https://api.sendops.dev/v1/messages?limit=10' \
-H "Authorization: Bearer sk_live_..." -o /dev/null | grep -i ^link

You’ll see something like:

Link: <https://api.sendops.dev/v1/messages?limit=10&cursor=eyJvZmZzZXQiOjEwfQ>; rel="next"

Follow that URL exactly — the cursor is opaque; do not parse it. See Pagination for the contract.

Where to next

  • Read the full Authentication page if you need to rotate keys, set per-environment quotas, or understand the test-vs-live model.
  • The Errors page documents every error shape you can receive.
  • The OpenAPI spec describes every endpoint, request, and response in machine-readable form.