FirstSales Mail Tester API
Temporary test inbox and received-email analysis.
Temporary test inbox and received-email analysis.
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/firstsales-io:firstsales-io-mail-tester-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: Firstsales Io Mail Tester API
version: 1.0.0
contact:
name: FirstSales Support
email: firstsales@support.communicate.so
url: https://firstsales.io
license:
name: Terms of Service
url: https://firstsales.io/terms-of-service/
termsOfService: https://firstsales.io/terms-of-service/
x-apiVersioning:
strategy: url-path
current: v1
pattern: https://firstsales.io/api/v1/{operation}
policyUrl: https://firstsales.io/developers/#versioning
note: A breaking change ships under a new prefix (/api/v2/); v1 keeps its contract. The unprefixed /api/{operation} form is an unversioned alias of the current version and may change without notice - call the /api/v1/ form.
x-deprecationPolicy:
minimumNoticeDays: 180
signalling: 'A deprecated version''s responses carry Deprecation: true and a Sunset header with the retirement date (RFC 8594), plus a Link rel="deprecation" to the migration notes.'
announcement: https://firstsales.io/developers/#deprecation-policy
policyUrl: https://firstsales.io/developers/#deprecation-policy
currentlyDeprecated: []
description: 'Operations tagged Mail Tester across 2 of this provider''s published API definitions: firstsales-io-openapi.json, openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://firstsales.io
description: Production
security: []
tags:
- name: Mail Tester
description: Temporary test inbox and received-email analysis.
paths:
/api/v1/tools/mail-tester/generate:
post:
operationId: createMailTestInbox
summary: Create a temporary test inbox
description: 'Step 1 of a mail test. No request body is required. Returns top-level emailId, emailAddress and expiresAt (Unix milliseconds); the session expires after seven days. Send an email to emailAddress, then poll check with emailId. Rate limit: 10 requests per minute per IP, plus an in-memory 50-per-hour check and a cap of 50 stored sessions created in the previous hour. The hourly in-memory check shares the legacy default limiter bucket. RateLimit headers describe the 10-per-minute wrapper; Retry-After is present only when that wrapper refuses the request.'
tags:
- Mail Tester
security: []
x-rateLimit:
limit: 10
windowSeconds: 60
note: Also checks an in-memory 50/hour limit in the shared default bucket and a cap of 50 stored sessions created in the previous hour per IP.
responses:
'200':
description: The generated test inbox address and expiry.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
const: true
emailId:
type: string
emailAddress:
type: string
format: email
expiresAt:
type: integer
description: Unix time in milliseconds.
required:
- success
- emailId
- emailAddress
- expiresAt
'429':
description: Minute or hourly limit exceeded. Retry-After is supplied only for the minute-limit refusal.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Error'
- $ref: '#/components/schemas/MailTesterError'
'500':
description: Could not create the test inbox.
content:
application/json:
schema:
$ref: '#/components/schemas/MailTesterError'
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
servers:
- url: https://firstsales.io
description: Production
/api/v1/tools/mail-tester/check:
get:
operationId: getMailTestReport
summary: Read the received emails for a test inbox
description: 'Step 2 of a mail test. Returns {success, session}; poll until session.emails is not empty. Each email may include authentication results, spam score and analysis when available. Rate limit: 60 requests per minute per IP. This handler sends no RateLimit or Retry-After headers.'
tags:
- Mail Tester
security: []
x-rateLimit:
limit: 60
windowSeconds: 60
parameters:
- name: emailId
in: query
required: true
schema:
type: string
description: The top-level emailId returned by generate.
responses:
'200':
description: The test session and its received emails.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
const: true
session:
type: object
properties:
emailId:
type: string
emailAddress:
type: string
format: email
createdAt:
type: integer
description: Unix time in milliseconds.
expiresAt:
type: integer
description: Unix time in milliseconds.
emails:
type: array
items:
type: object
properties:
id:
type: string
from:
type: string
to:
type: string
subject:
type: string
receivedAt:
type: integer
description: Unix time in milliseconds.
headers:
type: object
additionalProperties:
type: string
textBody:
type: string
htmlBody:
type: string
spamScore:
type: number
analysis:
type: object
properties:
spfStatus:
type: string
dkimStatus:
type: string
dmarcStatus:
type: string
spamReasons:
type: array
items:
type: string
recommendations:
type: array
items:
type: string
aiInsights:
type: array
items:
type: string
strengths:
type: array
items:
type: string
required:
- id
- from
- to
- subject
- receivedAt
required:
- emailId
- emailAddress
- createdAt
- expiresAt
- emails
required:
- success
- session
'400':
description: The emailId query parameter is missing or empty.
content:
application/json:
schema:
$ref: '#/components/schemas/MailTesterError'
'404':
description: The session is missing, expired, or unavailable.
content:
application/json:
schema:
$ref: '#/components/schemas/MailTesterError'
'429':
description: The 60-per-minute polling limit was exceeded.
content:
application/json:
schema:
$ref: '#/components/schemas/MailTesterError'
'500':
description: Could not check the test inbox.
content:
application/json:
schema:
$ref: '#/components/schemas/MailTesterError'
servers:
- url: https://firstsales.io
description: Production
components:
schemas:
Error:
type: object
description: Shared error envelope used by public endpoints and the rate-limit wrapper. Mail-tester handler errors use MailTesterError.
properties:
error:
type: string
description: Machine-readable error code, e.g. `invalid_input`.
message:
type: string
description: Human-readable explanation.
hint:
type: string
description: How to fix the request.
required:
- error
- message
- hint
MailTesterError:
type: object
properties:
success:
type: boolean
const: false
error:
type: string
message:
type: string
required:
- success
- error
- message
x-refined-from:
- firstsales-io-openapi.json
- openapi.json
x-apiVersioning:
strategy: url-path
current: v1
pattern: https://firstsales.io/api/v1/{operation}
policyUrl: https://firstsales.io/developers/#versioning
note: A breaking change ships under a new prefix (/api/v2/); v1 keeps its contract. The unprefixed /api/{operation} form is an unversioned alias of the current version and may change without notice - call the /api/v1/ form.
x-deprecationPolicy:
minimumNoticeDays: 180
signalling: 'A deprecated version''s responses carry Deprecation: true and a Sunset header with the retirement date (RFC 8594), plus a Link rel="deprecation" to the migration notes.'
announcement: https://firstsales.io/developers/#deprecation-policy
policyUrl: https://firstsales.io/developers/#deprecation-policy
currentlyDeprecated: []