---
title: "Getting started with the API"
description: "Create an API key, make your first request and learn the conventions every endpoint follows."
publishedAt: 2026-09-14
---
The DMARCguard API gives your own tooling the same data the dashboard shows:
reports, sources, scores, domain health and events. It is read-oriented, JSON
over HTTPS, and available on the Pro and Enterprise
plans.

## Before you start

You need an organization on a plan with API access and a role that can create
keys. Keys are created and revoked in the dashboard, never over the API, so a
leaked key can neither mint a replacement nor silence the others.

1. Open [Settings, Security, API Keys](https://app.dmarcguard.io/settings?tab=security&section=api-keys).
1. Give the key a name, pick a scope (`read` is the default and enough for everything in this reference) and an expiry.
1. Copy the key. It is shown once; the dashboard keeps only a prefix so you can tell keys apart later.
## Your first request

Every key starts with `dg_` and goes in the
`Authorization` header as a bearer token. Every path in this reference is
relative to the base URL `https://api.dmarcguard.io/api/v1`.

```bash
curl "https://api.dmarcguard.io/api/v1/domains" \
    -H "Authorization: Bearer dg_your_key"
```

A successful response is a paged envelope; the domains your organization
monitors are the `domains` array. If you get a `401`, the key is missing,
malformed, revoked, expired or on an organization that no longer has API
access. The [authentication guide](/docs/authentication/) walks through each
case.

## Conventions

These hold for every endpoint in the [reference](/docs/api/):

- **Versioned base URL.** Use the `/api/v1` base. Fields are only added within
  a version; anything breaking ships as a new version at a new base URL. The
  reference is the contract: a path that is not in it is unsupported and may
  change without notice.
- **IDs are strings.** Identifiers are Crockford Base32. Never parse one as a
  number.
- **Paging.** Paged lists return an envelope with `total`, `limit` and
  `offset` beside the resource's own array: `reports`, `sources`, `events` or
  `domains`; top sources uses `sources` too. A `limit` above
  200 is clamped. A list is never `null`; an empty one is
  `[]`.
- **Dates.** An instant is RFC 3339 in UTC with whole seconds. A field naming
  a day rather than a moment is `YYYY-MM-DD`. An absent value is `null`. The
  [report object](/docs/api/v1/reports/#getReport) keeps the reporter's own
  epoch seconds.
- **Rates** such as `compliance_rate` are percentages from 0 to 100.
- **Rate limits** are reported in response headers on every metered response
  on a plan with an hourly quota. Read the
  [rate limits guide](/docs/rate-limits/) before you write a loop.
- Every response from the API carries an `X-Request-Id` header. Quote it when
  you contact support about a specific request.

> **Where to look first**
>
> [Organization overview](/docs/api/v1/analytics/#getDashboardOverview) returns
> organization health, one card per domain and open action items in a single
> call. Most integrations start there and drill into [Domain
> health](/docs/api/v1/domains/#getDomainHealth) for one domain. Both count
> against the heavy-route budget, so cache what you read.

## Client requirements

- HTTPS only, TLS 1.2 or newer.
- Call the API from your own backend. A browser calling from another origin is
  refused by CORS.
- Design for responses well under 100 seconds. A request still running at that
  point is cut off.
- Send a descriptive `User-Agent`.

## Keep keys read-only

No key can create or revoke a key, whatever its scope: a request that
authenticated with a key is refused on both endpoints, so a leaked key cannot
replace itself or silence the organization's other integrations. Both are
actions for a signed-in person in the dashboard. Beyond that, a `read` key
cannot change billing or manage members either, since its scope allows read,
export and preview operations only, and that covers everything in this
reference. A `full` key can do whatever its
owner's role allows, so reserve it for automation that has to write and revoke
it when that job is done.