InboxGuard Integrations API
Third-party reputation and inbox-placement integrations (Microsoft SNDS, seed-list testing).
Third-party reputation and inbox-placement integrations (Microsoft SNDS, seed-list testing).
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/inboxguard-io:inboxguard-io-integrations-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: InboxGuard Integrations API
version: 1.2.0
summary: Email deliverability monitoring, DMARC reporting, and DNS authentication scanning.
description: 'The InboxGuard REST API lets developers and AI agents run on-demand deliverability scans (SPF, DKIM, DMARC, MTA-STS, TLS-RPT, BIMI, and DNS blocklists), re-verify raw email headers, manage monitored domains, read DMARC aggregate reports, list alerts, and manage API keys.
## Authentication
Authenticated endpoints accept an InboxGuard API key as a bearer token:
```
Authorization: Bearer ig_live_xxxxxxxxxxxxxxxxxxxxxxxx
```
Mint keys in the dashboard (Settings → API keys) or via `POST /api-keys`. Keys carry scopes: `read` (GET only) or `full` (all methods). See https://inboxguard.io/auth.md.
## Errors
Every error returns the same structured envelope (`#/components/schemas/Error`): `{ "error": { "code": "RATE_LIMIT", "message": "...", "requestId": "..." } }`.
## Rate limits
The anonymous `POST /scan-domain` endpoint allows 5 requests/hour per IP; authenticated callers get their plan''s hourly limit. `POST /scan-domain` responses carry `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` (and `X-RateLimit-*` equivalents); 429 responses add `Retry-After`.
## Idempotency
`POST /scan-domain` accepts an optional `Idempotency-Key` header with real replay semantics: a retry with the same key from the same caller within 1 hour returns the stored response instead of re-running the scan, marked with an `Idempotency-Replayed: true` response header.
## Versioning
The API uses unversioned, stable URLs (one surface — no `/v1` path prefix). The current API version is echoed on every response in the `API-Version` header. Additive, backward-compatible changes (new endpoints, new optional fields) ship continuously without a version bump. Breaking changes — when they are ever needed — ship under a NEW version that you opt into by sending an optional `Accept-Version` request header; the existing behaviour remains the default so unversioned callers are never broken. Omit `Accept-Version` to always get the current stable version. Upcoming breaking changes are announced in these docs and at https://inboxguard.io/llms-full.txt in advance.
## Pagination
Only `GET /scans` is paginated: pass `?before=` (from the previous response''s `nextCursor`) to walk older scans. `GET /domains`, `GET /alerts`, and `GET /api-keys` return the full (limit-capped) list in one response — there are no `cursor` parameters.'
termsOfService: https://inboxguard.io/terms
contact:
name: InboxGuard Support
email: support@inboxguard.io
url: https://inboxguard.io/contact
license:
name: Proprietary
url: https://inboxguard.io/terms
x-deprecation-policy: 'Unversioned, stable URLs. When an endpoint or field is ever deprecated, responses carry a ''Deprecation: true'' header and a ''Sunset: <HTTP-date>'' header marking the removal date — at least 6 months out — plus a ''Link: <url>; rel="deprecation"'' pointer to migration notes. Opt into a future breaking version with the optional ''Accept-Version'' request header. Nothing is deprecated today.'
servers:
- url: https://api.inboxguard.io
description: Production
security:
- ApiKeyBearer: []
tags:
- name: Integrations
description: Third-party reputation and inbox-placement integrations (Microsoft SNDS, seed-list testing).
paths:
/integrations/snds:
get:
tags:
- Integrations
summary: Microsoft SNDS connection status
operationId: getSndsStatus
description: Whether Microsoft SNDS (Smart Network Data Services) is connected for the org, plus the last sync time and status, the number of sending IPs tracked, and how many are currently blocked by Outlook/Hotmail. Readable by any org member.
security:
- ApiKeyBearer: []
responses:
'200':
description: Connection status.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
content:
application/json:
schema:
$ref: '#/components/schemas/SndsStatus'
'401':
$ref: '#/components/responses/Unauthorized'
post:
tags:
- Integrations
summary: Connect Microsoft SNDS
operationId: connectSnds
description: Store (or replace) this org's SNDS automated-data-access key, KMS-encrypted, so the daily sync pulls per-IP Outlook/Hotmail reputation. The first sync runs on the next daily schedule; data appears within ~24h. Requires an owner/admin key with write or full scope.
security:
- ApiKeyBearer: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SndsConnectRequest'
example:
key: 00000000-0000-0000-0000-000000000000
label: prod sending IPs
responses:
'200':
description: Key stored; first sync pending.
content:
application/json:
schema:
$ref: '#/components/schemas/SndsConnectResult'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
delete:
tags:
- Integrations
summary: Disconnect Microsoft SNDS
operationId: disconnectSnds
description: Drop the stored SNDS key and all synced per-IP stats + block status for the org. Requires an owner/admin key with write or full scope.
security:
- ApiKeyBearer: []
responses:
'200':
description: Disconnected.
content:
application/json:
schema:
type: object
required:
- connected
properties:
connected:
type: boolean
enum:
- false
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/integrations/snds/ips:
get:
tags:
- Integrations
summary: Microsoft SNDS per-IP reputation
operationId: getSndsIpStats
description: Latest per-IP reputation window from Microsoft SNDS for the org's sending IPs (most recent activity window per IP), left-joined to current block status. Requires SNDS to be connected.
security:
- ApiKeyBearer: []
responses:
'200':
description: Per-IP stats.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
content:
application/json:
schema:
type: object
required:
- ips
properties:
ips:
type: array
items:
$ref: '#/components/schemas/SndsIpStat'
'401':
$ref: '#/components/responses/Unauthorized'
/integrations/inbox-placement:
get:
tags:
- Integrations
summary: Inbox-placement provider status
operationId: getInboxPlacementStatus
description: Whether a seed-list inbox-placement provider is connected for the org, which provider, and how many tests have run. Always lists the supported providers. Readable by any org member.
security:
- ApiKeyBearer: []
responses:
'200':
description: Provider status.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
content:
application/json:
schema:
$ref: '#/components/schemas/InboxPlacementStatus'
'401':
$ref: '#/components/responses/Unauthorized'
post:
tags:
- Integrations
summary: Connect an inbox-placement provider
operationId: connectInboxPlacement
description: Store (or replace) the org's seed-list inbox-placement provider + API key, KMS-encrypted. Provider is `mailreach` or `glockapps`; GlockApps additionally requires a `projectId`. Requires an owner/admin key with write or full scope.
security:
- ApiKeyBearer: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/InboxPlacementConfigRequest'
example:
provider: mailreach
apiKey: mr_live_xxxxxxxx
responses:
'200':
description: Provider saved.
content:
application/json:
schema:
type: object
required:
- connected
- provider
properties:
connected:
type: boolean
enum:
- true
provider:
type: string
enum:
- mailreach
- glockapps
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
delete:
tags:
- Integrations
summary: Disconnect inbox placement
operationId: disconnectInboxPlacement
description: Drop the stored inbox-placement provider config and all recorded tests for the org. Requires an owner/admin key with write or full scope.
security:
- ApiKeyBearer: []
responses:
'200':
description: Disconnected.
content:
application/json:
schema:
type: object
required:
- connected
properties:
connected:
type: boolean
enum:
- false
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/integrations/inbox-placement/tests:
get:
tags:
- Integrations
summary: List inbox-placement tests
operationId: listInboxPlacementTests
description: Recent seed-list inbox-placement tests for the org (most recent first, up to 50) with their status and Inbox/Spam/Missing scores.
security:
- ApiKeyBearer: []
responses:
'200':
description: Tests.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
content:
application/json:
schema:
type: object
required:
- tests
properties:
tests:
type: array
items:
$ref: '#/components/schemas/InboxPlacementTest'
'401':
$ref: '#/components/responses/Unauthorized'
post:
tags:
- Integrations
summary: Start an inbox-placement test
operationId: startInboxPlacementTest
description: Start a seed-list inbox-placement test with the connected provider. Returns the seed addresses to mail your campaign to and, if the provider requires it, a header to insert; then poll GET /integrations/inbox-placement/tests/{id} for the verdict. Requires an inbox-placement provider to be configured and an owner/admin key with write or full scope.
security:
- ApiKeyBearer: []
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/InboxPlacementTestStartRequest'
example:
subject: June newsletter
responses:
'202':
description: Test started.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
content:
application/json:
schema:
$ref: '#/components/schemas/InboxPlacementTestStarted'
example:
testId: 7c9e4b1a-1f6e-4c2a-9a3d-2f9d2f3e4a5b
provider: mailreach
status: running
seedAddresses:
- seed1@gmail-seed.example
- seed2@outlook-seed.example
headerName: X-IG-Test
headerToken: abc123
instructions: 'Send your campaign to every seed address and insert the header X-IG-Test: abc123, then poll GET /integrations/inbox-placement/tests/7c9e4b1a-1f6e-4c2a-9a3d-2f9d2f3e4a5b for the verdict.'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'502':
description: The inbox-placement provider failed to start the test (upstream). Retry with backoff.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/integrations/inbox-placement/tests/{id}:
get:
tags:
- Integrations
summary: Poll an inbox-placement test
operationId: getInboxPlacementTest
description: Get one seed-list inbox-placement test by id. While the verdict is still open the server polls the provider and persists the result; once measured it returns the Inbox/Spam/Missing counts and the 0–100 score. A transient polling failure returns the last-known row with a `pollError` field rather than erroring.
security:
- ApiKeyBearer: []
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Test state.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
content:
application/json:
schema:
$ref: '#/components/schemas/InboxPlacementTestDetail'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
components:
schemas:
SndsIpStat:
type: object
required:
- ip
properties:
ip:
type: string
activityStart:
type: string
format: date-time
activityEnd:
type:
- string
- 'null'
format: date-time
filterResult:
type:
- string
- 'null'
description: 'SNDS filter result for the window: GREEN, YELLOW, or RED.'
complaintRate:
type:
- string
- 'null'
description: Complaint-rate band as reported by SNDS (e.g. "< 0.1%").
messageRecipients:
type:
- integer
- 'null'
trapHits:
type:
- integer
- 'null'
description: Spam-trap hits in the window.
sampleHelo:
type:
- string
- 'null'
blocked:
type: boolean
blockStatus:
type:
- string
- 'null'
description: Raw block-status string from SNDS, if any.
InboxPlacementTestStartRequest:
type: object
properties:
subject:
type: string
maxLength: 255
description: Optional subject line to associate with the test.
SndsConnectRequest:
type: object
required:
- key
properties:
key:
type: string
minLength: 8
maxLength: 200
description: The SNDS automated-data-access key (no whitespace), from the SNDS Automated Data Access page.
label:
type: string
maxLength: 120
description: Optional label, e.g. "prod sending IPs".
InboxPlacementTestStarted:
type: object
required:
- testId
- provider
- status
- seedAddresses
properties:
testId:
type: string
format: uuid
provider:
type: string
enum:
- mailreach
- glockapps
status:
type: string
enum:
- running
seedAddresses:
type: array
items:
type: string
description: Mail your campaign to every one of these seed addresses.
headerName:
type:
- string
- 'null'
description: Header to insert in the campaign, if the provider requires one.
headerToken:
type:
- string
- 'null'
description: Value for `headerName`.
instructions:
type: string
InboxPlacementTestDetail:
allOf:
- $ref: '#/components/schemas/InboxPlacementTest'
- type: object
properties:
seedAddresses:
type: array
items:
type: string
description: The seed addresses for this test.
pollError:
type: string
description: Present if polling the provider failed on this read; the rest is the last-known state.
InboxPlacementTest:
type: object
required:
- testId
- provider
- status
properties:
testId:
type: string
format: uuid
provider:
type: string
enum:
- mailreach
- glockapps
status:
type: string
description: pending, running, completed, or failed.
subject:
type: string
inbox:
type:
- integer
- 'null'
description: Seed messages landing in the inbox.
spam:
type:
- integer
- 'null'
description: Seed messages landing in spam/junk.
missing:
type:
- integer
- 'null'
description: Seed messages not delivered.
totalSeeds:
type:
- integer
- 'null'
score:
type:
- number
- 'null'
description: Inbox-placement score, 0–100.
createdAt:
type: string
format: date-time
completedAt:
type: string
format: date-time
InboxPlacementStatus:
type: object
required:
- connected
- providers
properties:
connected:
type: boolean
provider:
type: string
enum:
- mailreach
- glockapps
description: Present only when connected.
updatedAt:
type: string
format: date-time
description: Present only when connected.
testCount:
type: integer
description: Present only when connected.
providers:
type: array
items:
type: string
description: Supported inbox-placement providers.
SndsConnectResult:
type: object
required:
- connected
- lastSyncStatus
properties:
connected:
type: boolean
enum:
- true
label:
type:
- string
- 'null'
lastSyncStatus:
type: string
enum:
- pending
note:
type: string
Error:
type: object
description: Structured error envelope returned by every non-2xx response.
properties:
error:
type: object
properties:
code:
type: string
description: Stable machine-readable code.
enum:
- BAD_REQUEST
- UNAUTHORIZED
- FORBIDDEN
- NOT_FOUND
- CONFLICT
- RATE_LIMIT
- UPSTREAM_ERROR
- INTERNAL_ERROR
- SERVICE_UNAVAILABLE
- DNS_TEMPORARY_FAILURE
message:
type: string
description: Human-readable description.
requestId:
type: string
description: Correlation id for support.
details:
description: Optional structured validation detail (e.g. zod field errors).
retryAfterSeconds:
type: integer
description: Present on RATE_LIMIT responses.
required:
- code
- message
required:
- error
SndsStatus:
type: object
required:
- connected
description: 'When not connected, only `{ connected: false }` is returned.'
properties:
connected:
type: boolean
label:
type:
- string
- 'null'
lastSyncAt:
type:
- string
- 'null'
format: date-time
lastSyncStatus:
type: string
description: e.g. pending, ok, error.
lastSyncError:
type:
- string
- 'null'
ipCount:
type: integer
description: Distinct sending IPs with stats.
blockedCount:
type: integer
description: Sending IPs currently blocked by Outlook/Hotmail.
InboxPlacementConfigRequest:
type: object
required:
- provider
- apiKey
description: GlockApps additionally requires `projectId`.
properties:
provider:
type: string
enum:
- mailreach
- glockapps
apiKey:
type: string
minLength: 8
maxLength: 300
description: The vendor API key.
projectId:
type: string
maxLength: 200
description: GlockApps project id (required for provider=glockapps).
headers:
ApiVersion:
description: The API version that served this response. The URL surface is unversioned and stable; this header reports the current version so clients can detect breaking-change rollouts. Send the optional `Accept-Version` request header to pin a version once a future breaking version is published.
schema:
type: string
responses:
NotFound:
description: Resource not found. Returns the structured error envelope with code `NOT_FOUND`.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
BadRequest:
description: Invalid request. Returns the structured error envelope with code `BAD_REQUEST`.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: Authenticated but missing required scope or role. Returns the structured error envelope with code `FORBIDDEN`.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: Missing or invalid credentials. Returns the structured error envelope with code `UNAUTHORIZED`.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
WWW-Authenticate:
schema:
type: string
description: Bearer resource_metadata="https://api.inboxguard.io/.well-known/oauth-protected-resource"
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
securitySchemes:
ApiKeyBearer:
type: http
scheme: bearer
bearerFormat: InboxGuard API key (ig_live_… / ig_test_…)
description: 'PRIMARY auth: send an InboxGuard API key as a bearer token (`Authorization: Bearer ig_live_…`). Scopes: `read` (GET) and `full` (all methods). Mint a key at https://inboxguard.io/settings or per https://inboxguard.io/auth.md.'
OAuth2:
type: oauth2
description: 'OAuth-shaped wrapper around the same API key. The ONLY grant is client_credentials at POST https://api.inboxguard.io/oauth/token, where the client_secret IS an InboxGuard API key (HTTP Basic or body); the returned access_token is that same key. There is NO authorization_code flow, NO PKCE, and NO /oauth/authorize endpoint. Discovery: /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource on api.inboxguard.io. See https://inboxguard.io/auth.md.'
flows:
clientCredentials:
tokenUrl: https://api.inboxguard.io/oauth/token
scopes:
read: Read-only access (GET).
full: Full read/write access (all methods).
externalDocs:
description: API quickstart and guides
url: https://inboxguard.io/guides/api-quickstart