// faq
What mailQA does, how mail gets into an inbox, how a test suite waits on it, and how the mail it holds is stored. Anything that turns into a paragraph of API detail links through to the docs; anything that is a number links to the plan comparison, which reads it from the live plans rather than repeating it here.
A mail server that captures instead of delivering. Your application sends email to mailQA rather than to a real mailbox; you read what arrived in a dashboard and assert on it from a test suite. Nothing is ever forwarded or relayed onward, so a misconfigured staging environment cannot reach a real customer through it.
link to this answerYes — that is what the SMTP sink is: a mail server that accepts everything your app sends, keeps it for you to read and assert on, and delivers none of it. Point your mailer at smtp.mailqa.io with your organization’s credentials and nothing else about your app changes between local development, CI and staging. The sandbox page has the configuration for Nodemailer, Rails, Django, Laravel, Spring Boot, .NET and Go.
Anyone whose tests have an email in the middle of them — signup confirmations, one-time codes, password resets, invites, invoices. It is built for QA engineers driving a browser and for developers writing the API tests underneath, which is why the dashboard and the SDK see exactly the same inboxes.
link to this answerNeither. Your organization is provisioned with its own receiving subdomain and its own SMTP credentials when you sign up — there is no MX record to publish, no certificate to renew and no server of ours to operate. The Quickstart goes from nothing to an assertion on a real email in about five minutes.
link to this answerNo — every tier is paid, but every tier starts with a 14-day free trial, and capture works identically on all of them. What differs is capacity: how many inboxes, how much mail a month, how long it is kept, how many teammates. Compare the plans to see where the lines fall.
link to this answerNo. mailQA captures and stops; there is no forwarding path and no relay to enable. It is for the environments you test in — local development, CI and staging — and the Acceptable Use Policy says so explicitly.
link to this answerTwo ways, one inbox model. Point your app at the SMTP sink — smtp.mailqa.io, port 587 or 2525, with your organization’s credentials — and everything it sends is captured, whoever the recipient is. Or let it send to a real address on your subdomain, qa@your-org.mailqa.io, over the public internet. Both land in the same inbox and read identically. On Pro and above that address can be on a domain of your own — qa@test.yourcompany.com — by adding a single MX record.
The sink for local development and CI: it needs one environment variable and it catches mail addressed to anyone, so you do not have to rewrite recipients in test fixtures. The MX address when you want the delivery itself to be real — full DNS resolution, with SPF, DKIM and DMARC verified on arrival, which is the only way to test that staging signs its mail correctly.
link to this answerThrough the sink it is captured like everything else and filed into an inbox named for that recipient — customer@example.com appears in your inbox list, created on first use. The real address never receives anything. That is the point of pointing a staging environment at the sink rather than at a real mail provider.
With catch-all on, any address on your subdomain gets an inbox the first time mail arrives for it, with no create step in between — which is what a signup test that mints a fresh address every run wants. Without it, mail to an address you have not created is refused with “no such mailbox”. It is one of the rows that differs by tier in the plan comparison.
link to this answerPublic delivery opens once an organization owner has confirmed their email address. Until then inbound mail is answered with a temporary 450, so well-behaved senders hold it and retry rather than giving up on the address. The SMTP sink is unaffected — it needs your credentials, so it is not something a stranger can abuse.
Each inbox keeps its most recent messages up to the plan’s cap and evicts the oldest first, so a test loop left running overnight fills one inbox instead of your whole account. Separately, retention deletes a message once it is older than your plan’s window — the message, its attachments and its raw source together.
link to this answerYes. They are listed with name, type and size and can be downloaded individually from the dashboard or the API, and inline images referenced from the HTML render in the preview. A message larger than the plan’s size limit is refused on the wire with a 552, so your app sees the rejection in its own log instead of a message that quietly never arrives.
It still shows up. The raw message is stored before anything is parsed, so a message MIME parsing chokes on gets a row marked failed with its original source attached rather than disappearing — which is usually exactly the message you needed to look at.
link to this answerUse the @mailqa/client SDK. waitForMessage, waitForCode and waitForLink are promises that resolve the moment a matching message lands and reject with a typed timeout if it never does — so a test is as fast as your app is, and a failure says what was being waited for. The waiting semantics and the runner recipes are in the SDK guide.
Yes — everything the SDK does is a call to the REST API under /v1, authenticated with an API key, and the endpoint reference has a curl sample for each one. The OpenAPI 3.1 document is generated from the same contracts the server validates against and served at /openapi.json, so you can generate a client in your own language or load it straight into Postman.
That is the pattern it is built around: one throwaway inbox per run. Every suite is then isolated by construction, and no message left over from an earlier run can satisfy this run’s wait — the failure mode that makes shared test mailboxes flaky.
link to this answerNot if you do not want one. Creating an inbox is idempotent — the same name gives you back the same inbox, at the same address, with the same id — and passing empty: true clears whatever the last run left in it. Re-creating an inbox that already exists consumes no quota, so a fixture can hardcode its address and simply run again.
With an API key, sent as Authorization: Bearer mqa_live_…. You create named keys in Settings → API keys with an optional expiry, and revoke them individually. The plaintext key is shown once at creation and stored only as a hash, so a lost key is replaced rather than recovered — keep it in your CI secret store, never in the repository.
No. Messages appear the instant they are parsed, streamed to the open page over server-sent events — useful when you are watching a browser test drive a signup flow and want to see the mail land beside it.
link to this answerOwners handle billing. Owners and admins manage members, roles and the organization’s SMTP credentials. Members read every inbox and manage the ones they created themselves.
link to this answerOwners and admins can empty or delete any inbox. A member can do so to the inboxes they created, and to inboxes the SMTP sink created on its own — nobody made those deliberately and the next send recreates them. Reading is organization-wide either way, and an API key carries organization-level authority.
link to this answerPer organization. One username and password serves every inbox, and the sink files mail by the address it was sent to rather than by who authenticated. You can re-read them in the dashboard whenever you need them; rotating them is restricted to owners and admins, because a rotation breaks every mailer the team has configured.
link to this answerInvite them by email address from Settings → Members. The link in the invitation is the credential, so they join in one click without a separate signup to complete first. Seats are capped by your plan — compare the tiers.
link to this answerRendered email is attacker-controlled HTML, and mailQA treats it that way in two independent layers: it is sanitized on the server against a strict allowlist, with remote images blocked and counted, and then displayed in a sandboxed iframe on a separate origin that runs no scripts and cannot reach your session.
link to this answerNo. Every request is scoped to the organization the credential belongs to, and no endpoint accepts an organization id from the client — so cross-tenant access is structurally impossible rather than something each handler has to remember to check. Asking for an id that belongs to someone else returns “not found”, since confirming it exists would itself leak.
link to this answerYour SMTP password is encrypted so the dashboard can show it to you again, and separately hashed for authentication. API keys, invitation links and password-reset tokens are stored only as hashes and are never recoverable — losing one means issuing a new one. Account passwords are hashed with argon2.
link to this answerFor your plan’s retention window, after which a daily sweep deletes the message, its attachments and its raw source. You can always delete sooner — a single message, or a whole inbox — from the dashboard or the API. The windows are in the plan comparison.
link to this answerKeep it to test data. mailQA is a testing tool, and the mail it holds is stored so it can be inspected rather than sealed away from you. What we collect and who processes it on our behalf is set out in the Privacy Policy and the Subprocessors page.
link to this answerEvery plan starts with a 14-day free trial. You add a card at checkout, capture mail on the full plan from the first minute, and are charged for the first time when the trial ends; cancel from the billing portal before then and nothing is charged. The trial is granted once per organization — a plan you subscribe to again later is billed from its first day. The refund and cancellation policy has the details.
link to this answerEvery plan captures mail the same two ways and inspects it with the same tools, so the question is only capacity — inboxes, messages a month, how long they are kept, how many seats — plus catch-all addressing. Start at the tier that covers your current suite; you are not migrating anything if you move. The row-by-row breakdown is on the pricing page.
link to this answerAcross every inbox in the organization, for the calendar month. A message addressed to recipients in several of your inboxes is filed in each of them and counts once per inbox, because each copy is stored and retained separately.
link to this answerMove between tiers or cancel from the dashboard at any time. Your limits follow the moment the subscription does, with nothing to migrate, and a cancelled plan keeps capturing until the end of the period you have already paid for.
link to this answerYes — paying annually saves about 20% against the monthly price, for the same limits. Payments are processed by Stripe, and card details are entered on Stripe’s own checkout rather than passing through mailQA.
link to this answerThe circumstances are set out in the Refund and Cancellation Policy. If something has gone wrong with a charge, write to us before it becomes a dispute — it is usually quicker to fix directly.
link to this answerCapture continues while Stripe retries the charge — cutting a team’s CI off mid-dunning over a card that expired would be the wrong trade. If the subscription ends up inactive, new mail is answered with a temporary failure rather than a permanent one, so senders hold it and delivery resumes once billing is sorted out.
link to this answerWrite to support@mailqa.io and a person will answer. If it is about how something works, the Quickstart and the API reference go a good deal deeper than this page does.
link to this answerWrite to support@mailqa.io — or just create an inbox and send it something. That answers most of these faster than reading about it.