> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://mailchimp.com/developer/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://mailchimp.com/developer/_mcp/server.

# Search recently sent messages

POST https://mandrillapp.com/api/1.4/messages/search
Content-Type: application/json

Search recently sent messages and optionally narrow by date range, tags, senders, and API keys. Results can include both email and SMS messages. If no date range is specified, results within the last 7 days are returned.

Reference: https://mailchimp.com/developer/transactional/api/messages/search

## Request

### Body (application/json)

This endpoint expects a MessagesSearchRequest.

- `key` (string, required) — A valid Mandrill API key
- `query` (string, optional) — search terms to find matching messages
- `date_from` (date, optional, nullable) — start date
- `date_to` (date, optional, nullable) — end date
- `tags` (list of string, optional, nullable) — an array of tag names to narrow the search to
- `senders` (list of string, optional, nullable) — an array of sender addresses to narrow the search to
- `api_keys` (list of string, optional, nullable) — an array of API keys to narrow the search to
- `limit` (integer, optional) — the maximum number of results to return, defaults to 100, upper limit of 1000

## Response

### 200

Success

- `list of MessagesSearchResponseItems`

## Errors

### 401 Unauthorized Error

Invalid or missing API key.

- `status` (string, required) — Status of the response, typically "error"
- `code` (enum, required) — Numeric error code
  - Allowed values: `401`
- `name` (enum, required) — Machine-friendly error name
  - Allowed values: `Invalid_Key`
- `message` (string, required) — Human-readable error message

### 500 Internal Server Error

An unexpected internal server error occurred.

- `status` (string, required) — Status of the response, typically "error"
- `code` (integer, required) — Numeric error code
- `name` (string, required) — Machine-friendly error name
- `message` (string, required) — Human-readable error message

### 503 Service Unavailable Error

Service unavailable

- `status` (string, required) — Status of the response, typically "error"
- `code` (integer, required) — Numeric error code
- `name` (string, required) — Machine-friendly error name
- `message` (string, required) — Human-readable error message

## Types

### MessagesSearchResponseItems

### MessagesEmailInfo

Detailed information about a sent email message

- `ts` (integer, required) — Unix timestamp when the message was sent
- `_id` (string, required) — The message's unique id
- `tags` (list of string, required) — List of tags associated with the message
- `sender` (string, required) — The sender email address
- `subject` (string, required) — The message subject
- `email` (string, required) — The recipient email address
- `opens` (integer, required) — Number of times the message has been opened
- `clicks` (integer, required) — Number of times links in the message have been clicked
- `opens_detail` (list of MessagesOpenDetail, required) — Details about opens, if captured
- `clicks_detail` (list of MessagesClickDetail, required) — Details about clicks, if captured
- `state` (enum, required) — Sending status of this message
  - Allowed values: `sent`, `bounced`, `rejected`, `queued`, `scheduled`, `canceled`
- `smtp_events` (list of MessagesSmtpEvent, required) — SMTP events related to the message
- `subaccount` (string, required, nullable) — The subaccount used to send the message
- `resends` (list of MessagesEmailInfoResendsItems, required) — Array of resend attempts
- `reject` (MessagesEmailInfoReject, required, nullable) — Rejection details if message was rejected
- `template` (string, optional, nullable) — Template used if applicable
- `mc_template` (string, optional, nullable) — Mailchimp template used if applicable
- `metadata` (MessagesEmailInfoMetadata, optional) — Any custom metadata provided when the message was sent
- `diag` (string, optional, nullable) — Diagnostic information about why the message was rejected
- `bounce_description` (string, optional) — Description of bounce/rejection reason (only present for rejected messages)

### MessagesSmsInfo

Detailed information about a sent SMS message

- `ts` (integer, required) — Unix timestamp when the message was sent
- `_id` (string, required) — The message's unique id
- `tags` (list of string, required) — List of tags associated with the message
- `opens` (integer, required) — Number of times the message has been opened
- `clicks` (integer, required) — Number of times links in the message have been clicked
- `opens_detail` (list of MessagesOpenDetail, required) — Details about opens, if captured
- `clicks_detail` (list of MessagesClickDetail, required) — Details about clicks, if captured
- `state` (enum, required) — Sending status of this message
  - Allowed values: `sent`, `bounced`, `rejected`, `queued`, `scheduled`, `canceled`
- `channel` (enum, required) — The channel type for this message
  - Allowed values: `sms`
- `to` (string, required) — The recipient phone number
- `from` (string, required) — The SMS sender identifier
- `text` (string, required) — The SMS message text content
- `consent` (enum, required) — The consent type for this SMS
  - Allowed values: `onetime`, `recurring`, `recurring-no-confirm`
- `sms_events` (list of MessagesSmsEvent, required) — SMS events related to the message
- `metadata` (MessagesSmsInfoMetadata, optional) — Any custom metadata provided when the message was sent
- `subaccount` (string, optional, nullable) — The subaccount used to send the message
- `reject` (MessagesSmsInfoReject, optional, nullable) — Rejection details if message was rejected

### MessagesOpenDetail

Details about a message open event

- `ts` (integer, required) — Unix timestamp when the open occurred
- `ip` (string, required) — IP address of the opener
- `location` (string, required) — Geographic location of the opener
- `ua` (string, required) — User agent of the opener

### MessagesClickDetail

Details about a message click event

- `ts` (integer, required) — Unix timestamp when the click occurred
- `url` (string, required) — The URL that was clicked
- `ip` (string, required) — IP address of the clicker
- `location` (string, required) — Geographic location of the clicker
- `ua` (string, required) — User agent of the clicker

### MessagesSmtpEvent

Details about an SMTP event

- `ts` (integer, required) — Unix timestamp when the event occurred
- `type` (enum, required) — The type of SMTP event
  - Allowed values: `sent`, `bounced`, `rejected`, `delivered`
- `source_ip` (string, required) — The IP address that sent the message
- `destination_ip` (string, required) — The IP address of the recipient's server (empty string for internal processing)
- `size` (integer, required) — The size of the message in bytes
- `diag` (string, optional, nullable) — The SMTP response from the recipient's server or internal diagnostic

### MessagesEmailInfoResendsItems

### MessagesEmailInfoReject

Rejection details if message was rejected

- `reason` (string, optional) — The reason for rejection
- `last_event_at` (string, optional) — When the rejection occurred

### MessagesEmailInfoMetadata

Any custom metadata provided when the message was sent

### MessagesSmsEvent

Details about an SMS event

- `ts` (integer, required) — Unix timestamp when the event occurred
- `state` (enum, required) — The state of the SMS event
  - Allowed values: `sent`, `delivered`, `failed`, `canceled`
- `sub_state` (string, optional, nullable) — Additional state details

### MessagesSmsInfoMetadata

Any custom metadata provided when the message was sent

### MessagesSmsInfoReject

Rejection details if message was rejected

- `reason` (string, optional) — The reason for rejection
- `last_event_at` (string, optional) — When the rejection occurred

## Examples

**Request**

```json
{
  "key": "ONzNrsmbtNXoIKyfPmjnig"
}
```

**Response**

```json
[
  {
    "_id": "string",
    "bounce_description": "string",
    "clicks": 1,
    "clicks_detail": [
      {
        "ip": "string",
        "location": "string",
        "ts": 1,
        "ua": "string",
        "url": "string"
      }
    ],
    "diag": "string",
    "email": "user@example.com",
    "mc_template": "string",
    "metadata": {},
    "opens": 1,
    "opens_detail": [
      {
        "ip": "string",
        "location": "string",
        "ts": 1,
        "ua": "string"
      }
    ],
    "reject": {
      "last_event_at": "string",
      "reason": "string"
    },
    "resends": [
      {}
    ],
    "sender": "user@example.com",
    "smtp_events": [
      {
        "destination_ip": "198.2.132.48",
        "diag": "string",
        "size": 1,
        "source_ip": "string",
        "ts": 1,
        "type": "sent"
      }
    ],
    "state": "sent",
    "subaccount": "string",
    "subject": "string",
    "tags": [
      "string"
    ],
    "template": "string",
    "ts": 1
  }
]
```

**SDK Code**

```python
import requests

url = "https://mandrillapp.com/api/1.4/messages/search"

payload = { "key": "ONzNrsmbtNXoIKyfPmjnig" }
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://mandrillapp.com/api/1.4/messages/search';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: '{"key":"ONzNrsmbtNXoIKyfPmjnig"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://mandrillapp.com/api/1.4/messages/search"

	payload := strings.NewReader("{\n  \"key\": \"ONzNrsmbtNXoIKyfPmjnig\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://mandrillapp.com/api/1.4/messages/search")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n  \"key\": \"ONzNrsmbtNXoIKyfPmjnig\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://mandrillapp.com/api/1.4/messages/search")
  .header("Content-Type", "application/json")
  .body("{\n  \"key\": \"ONzNrsmbtNXoIKyfPmjnig\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://mandrillapp.com/api/1.4/messages/search', [
  'body' => '{
  "key": "ONzNrsmbtNXoIKyfPmjnig"
}',
  'headers' => [
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://mandrillapp.com/api/1.4/messages/search");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"key\": \"ONzNrsmbtNXoIKyfPmjnig\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Content-Type": "application/json"]
let parameters = ["key": "ONzNrsmbtNXoIKyfPmjnig"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://mandrillapp.com/api/1.4/messages/search")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```