Once an inbox exists, every message sent to that address is stored and queryable through the MailSlurp API. This guide focuses on receive-side patterns that work in application backends and CI tests.

## Receive strategies

Choose the strategy by workload:

- Dashboard viewing: useful for manual QA and support triage.
- `waitFor` APIs: best for deterministic automated tests.
- Webhooks: best for event-driven applications and higher throughput.

## Fetching known emails

If you already have an email ID, fetch the full payload directly:



```typescript
const [email] = await mailslurp.waitForEmailCount(1, inbox.id, 30000, true);
const { id, to, from, subject, isHTML, attachments } = await mailslurp.getEmail(email.id!);
```



This is useful when your prior step already produced the ID (for example from a list query or webhook event).

## WaitFor APIs (recommended for tests)

`waitFor` endpoints hold the request until conditions are met. They reduce flaky polling loops and make assertions predictable.

### Wait for latest email



```typescript
const latestEmail = await mailslurp.waitForLatestEmail(inbox.id, 30000, unreadOnly);
```



### Wait for target count



```typescript
const emails = await mailslurp.waitForEmailCount(1, inbox.id, 30000, unreadOnly);
```



### Wait for matching emails



```typescript
const matchingEmails = await mailslurp.waitForMatchingEmails(
  {
    // match for emails with no attachments
    conditions: [
      {
        condition: ConditionOptionConditionEnum.HAS_ATTACHMENTS,
        value: ConditionOptionValueEnum.FALSE,
      },
    ],
    // match for emails from a specific email address
    matches: [
      {
        field: MatchOptionFieldEnum.FROM,
        should: MatchOptionShouldEnum.CONTAIN,
        value: inbox.emailAddress,
      },
    ],
  },
  1,
  inbox.id,
  timeout,
  unreadOnly,
);
```



### Wait for nth email



```typescript
const nthEmail = await mailslurp.waitForNthEmail(inbox.id!, 0, timeout, unreadOnly);
```



## Listing emails in an inbox

Use list methods to inspect current state or backfill history:



```typescript
await mailslurp.getEmails(inbox.id!);
// or paginated
await mailslurp.getAllEmails(0, 10, [inbox.id!], "DESC");
```



List endpoints return previews. Fetch full content with `getEmail` when you need body, headers, or attachment IDs.

## Webhook-driven receiving

Webhooks are ideal when your system should react immediately to inbound mail without long polling:

- Configure a webhook target on the inbox.
- Receive HTTP POST events when messages arrive.
- Process idempotently (retries are normal in distributed systems).

See [webhook guide](/guides/email-webhooks/) and [webhook testing](/guides/testing-webhooks/).

## Attachments

Attachments are stored separately from message previews. Retrieve metadata and content via attachment endpoints.

```typescript
// download attachment content as octet stream
downloadAttachment(emailId: string, attachmentId: string): Promise<Response>
```

```typescript
interface AttachmentMetaData {
  contentLength: number;
  contentType: string;
  name: string;
}
```

## Reliable receive-side test pattern

1. Create a fresh inbox at test start.
2. Trigger app behavior that sends an email.
3. Wait for matching message criteria.
4. Fetch full message.
5. Assert links, codes, and payload structure.
6. Cleanup inbox resources.

For end-to-end examples, see [Cypress testing guide](/guides/testing/cypress-js/) and [Playwright OTP testing](/guides/test-sms-otp-mfa-using-playwright/).

## Next steps

- [Create inboxes in code](/guides/developers/creating-inboxes/)
- [Send email in JavaScript](/guides/developers/sending-email/)
- [Email API reference](/api/)
