# Test Email Connection

> Check a mailbox's SMTP and IMAP login without saving anything.

Requires an API key with the `write` scope.

FoxReach connects to the mail servers you name and tries the login, then reports each result. Nothing is saved. The password is sent to the mail provider only; it is never stored, logged or returned. The `write` scope is needed because the call makes FoxReach connect out with your credentials.

The SMTP login is tested on ports 465 and 587. On any other port only the connection and greeting are checked. IMAP is tested with a login and opening the inbox read-only.

The hosts must resolve to public mail servers. A host that is, or resolves to, a private, loopback or link-local address is refused without connecting, and both results come back as failed with a message saying so.

## Body Parameters

<ParamField body="email" type="string" required>The mailbox address.</ParamField>
<ParamField body="password" type="string" required>The mailbox password or app password.</ParamField>
<ParamField body="smtpHost" type="string" required>SMTP server, for example `smtp.gmail.com`.</ParamField>
<ParamField body="smtpPort" type="integer">SMTP port. Default `587`.</ParamField>
<ParamField body="imapHost" type="string" required>IMAP server, for example `imap.gmail.com`.</ParamField>
<ParamField body="imapPort" type="integer">IMAP port. Default `993`.</ParamField>

## Response

<ResponseField name="data" type="object">
  <Expandable title="data">
    <ResponseField name="smtpSuccess" type="boolean">Whether the SMTP connection (and login, on 465 and 587) worked.</ResponseField>
    <ResponseField name="smtpError" type="string">The error, or `null`.</ResponseField>
    <ResponseField name="imapSuccess" type="boolean">Whether the IMAP login and inbox open worked.</ResponseField>
    <ResponseField name="imapError" type="string">The error, or `null`.</ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
```bash cURL
curl -X POST "https://api.foxreach.io/api/v1/email-accounts/test" \
  -H "X-API-Key: otr_your_key" \
  -H "Content-Type: application/json" \
  -d '{"email": "sales@acme.com", "password": "app-password", "smtpHost": "smtp.gmail.com", "imapHost": "imap.gmail.com"}'
```

```python Python SDK
from foxreach import FoxReach

client = FoxReach(api_key="otr_your_key")
result = client.email_accounts.test_connection(
    "sales@acme.com", "app-password", smtp_host="smtp.gmail.com", imap_host="imap.gmail.com",
)
```

```typescript TypeScript SDK
import { FoxReach } from "foxreach";

const client = new FoxReach({ apiKey: "otr_your_key" });
const result = await client.emailAccounts.testConnection({
  email: "sales@acme.com", password: "app-password",
  smtpHost: "smtp.gmail.com", imapHost: "imap.gmail.com",
});
```
</RequestExample>

<ResponseExample>
```json
{
  "data": {"smtpSuccess": true, "smtpError": null, "imapSuccess": false, "imapError": "IMAP error: [AUTHENTICATIONFAILED] Invalid credentials"}
}
```
</ResponseExample>

## Errors

| Status | Description |
|--------|-------------|
| `401` | Missing, invalid, revoked or expired API key |
| `403` | API key does not have the required scope: `write` |
| `422` | `email` is not an address, or a required field is missing |

## Rate Limit

- **100 requests per minute, shared by every `expensive` call in your workspace.** Fixed 60-second window.
- Every response includes `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` (unix epoch seconds) and `X-RateLimit-Bucket` (`expensive`).
- A `429` response includes a `Retry-After` header (seconds until the bucket resets).

For client-side patterns, see [Rate Limiting](/rate-limiting).
