InboxGuard Integrations API

Third-party reputation and inbox-placement integrations (Microsoft SNDS, seed-list testing).

GitHub OpenAPI

Operations 10

GET /integrations/snds Microsoft SNDS connection status #
POST /integrations/snds Connect Microsoft SNDS #
DELETE /integrations/snds Disconnect Microsoft SNDS #
GET /integrations/snds/ips Microsoft SNDS per-IP reputation #
GET /integrations/inbox-placement Inbox-placement provider status #
POST /integrations/inbox-placement Connect an inbox-placement provider #
DELETE /integrations/inbox-placement Disconnect inbox placement #
GET /integrations/inbox-placement/tests List inbox-placement tests #
POST /integrations/inbox-placement/tests Start an inbox-placement test #
GET /integrations/inbox-placement/tests/{id} Poll an inbox-placement test #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • 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.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/inboxguard-io:inboxguard-io-integrations-api"
All apis
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.

Get an API 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 Specification

inboxguard-io-integrations-api-openapi.yml Raw ↑
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