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

# Get email campaigns' statistics for a contact

GET https://api.brevo.com/v3/contacts/{identifier}/campaignStats

Retrieve email campaign statistics for a specific contact identified by email address or numeric ID. Statistics include messages sent, opens, clicks, hard/soft bounces, deliveries, unsubscriptions, complaints, and transactional attributes. By default, data covers the last 90 days; use startDate and endDate parameters (YYYY-MM-DD) to specify a custom range with a maximum span of 90 days.

Reference: https://developers.brevo.com/reference/get-contact-stats

## Authentication

- `api-key` header (required) — The API key should be passed in the request headers as `api-key` for authentication.

## Request

### Path parameters

- `identifier` (string or integer, required) — Email (urlencoded) OR ID of the contact

### Query parameters

- `startDate` (string, optional) — **Mandatory if endDate is used.** Starting date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be lower than equal to endDate. Must not be greater than the current date.
- `endDate` (string, optional) — **Mandatory if startDate is used.** Ending date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be greater than equal to startDate. Must not be greater than the current date. Maximum difference between startDate and endDate should not be greater than 90 days.

## Response

### 200

Contact campaign statistics informations

- `clicked` (list of object, optional)
  - `campaignId` (long, required) — ID of the campaign which generated the event
  - `links` (list of object, required)
    - `count` (long, required) — Number of clicks on this link for the campaign
    - `eventTime` (string, required) — UTC date-time of the event
    - `ip` (string, required) — IP from which the user has clicked on the link
    - `url` (string, required) — URL of the clicked link
- `complaints` (list of object, optional)
  - `campaignId` (long, required) — ID of the campaign which generated the event
  - `eventTime` (string, required) — UTC date-time of the event
- `delivered` (list of object, optional)
  - `campaignId` (long, required) — ID of the campaign which generated the event
  - `eventTime` (string, required) — UTC date-time of the event
- `hardBounces` (list of object, optional)
  - `campaignId` (long, required) — ID of the campaign which generated the event
  - `eventTime` (string, required) — UTC date-time of the event
- `messagesSent` (list of object, optional)
  - `campaignId` (long, required) — ID of the campaign which generated the event
  - `eventTime` (string, required) — UTC date-time of the event
- `opened` (list of object, optional)
  - `campaignId` (long, required) — ID of the campaign which generated the event
  - `count` (long, required) — Number of openings of the campaign
  - `eventTime` (string, required) — UTC date-time of the event
  - `ip` (string, required) — IP from which the user has opened the campaign
- `softBounces` (list of object, optional)
  - `campaignId` (long, required) — ID of the campaign which generated the event
  - `eventTime` (string, required) — UTC date-time of the event
- `transacAttributes` (list of object, optional)
  - `orderDate` (date, required) — Date of the order
  - `orderId` (long, required) — ID of the order
  - `orderPrice` (float, required) — Price of the order
- `unsubscriptions` (object, optional)
  - `adminUnsubscription` (list of object, required) — Contact has been unsubscribed from the administrator
    - `eventTime` (string, required) — UTC date-time of the event
    - `ip` (string, optional) — IP from which the user has been unsubscribed
  - `userUnsubscription` (list of object, required) — Contact has unsubscribed via the unsubscription link in the email
    - `campaignId` (long, required, nullable) — ID of the campaign which generated the event
    - `eventTime` (string, required) — UTC date-time of the event
    - `ip` (string, optional) — IP from which the user has unsubscribed

## Errors

### 400 Bad Request Error

bad request

- `code` (enum, required) — Error code displayed in case of a failure
  - Allowed values: `invalid_parameter`, `missing_parameter`, `out_of_range`, `campaign_processing`, `campaign_sent`, `document_not_found`, `not_enough_credits`, `permission_denied`, `duplicate_parameter`, `duplicate_request`, `method_not_allowed`, `unauthorized`, `account_under_validation`, `not_acceptable`, `bad_request`, `unprocessable_entity`, `Domain does not exist`, `Contact email not found`, `Attribute not found`, `Category id not found`, `Invalid parameters passed`, `Record(s) for identifier not found`, `Returned when query params are invalid`, `Returned when invalid data posted`, `Feed not found`, `Campaign ID not found`, `api-key not found`, `DMARC policy requires domain authentication`, `DNS records not properly configured`, `Invalid OTP code provided`, `OTP code has expired`, `Domain already exists in your account`, `The sum of all IP weights must equal 100`, `Authentication failed`, `Insufficient credits`, `Request already processed`
- `message` (string, required) — Readable message associated to the failure

### 404 Not Found Error

Contact not found

- `message` (string, required) — Readable message associated to the failure
- `code` (string, optional) — Error code displayed in case of a failure

## Examples

**Response**

```json
{
  "clicked": [
    {
      "campaignId": 21,
      "links": [
        {
          "count": 2,
          "eventTime": "2016-05-03T21:25:01Z",
          "ip": "66.249.93.118",
          "url": "https://url.domain.com/fbe5387ec717e333628380454f68670010b205ff/1/go?uid={EMAIL}&utm_source=brevo&utm_campaign=test_camp&utm_medium=email"
        }
      ]
    }
  ],
  "delivered": [
    {
      "campaignId": 21,
      "eventTime": "2016-05-03T21:24:56Z",
      "count": 2,
      "ip": "66.249.93.118"
    }
  ],
  "messagesSent": [
    {
      "campaignId": 21,
      "eventTime": "2016-05-03T20:15:13Z"
    },
    {
      "campaignId": 42,
      "eventTime": "2016-10-17T10:30:01Z"
    },
    {
      "campaignId": 45,
      "eventTime": "2016-11-09T11:45:02Z"
    }
  ],
  "opened": [
    {
      "campaignId": 21,
      "count": 2,
      "eventTime": "2016-05-03T21:24:56Z",
      "ip": "66.249.93.118"
    },
    {
      "campaignId": 45,
      "count": 1,
      "eventTime": "2017-01-30T13:56:40Z",
      "ip": "66.249.93.217"
    }
  ]
}
```

**SDK Code**

```typescript response
import { BrevoClient } from "@getbrevo/brevo";

async function main() {
    const client = new BrevoClient({
        apiKey: "YOUR_API_KEY_HERE",
    });
    await client.contacts.getContactStats({
        identifier: "string",
    });
}
main();

```

```python response
from brevo import Brevo

client = Brevo(
    api_key="YOUR_API_KEY_HERE",
)

client.contacts.get_contact_stats(
    identifier="string",
)

```

```php response
<?php

namespace Example;

use Brevo\Brevo;
use Brevo\Contacts\Requests\GetContactStatsRequest;

$client = new Brevo(
    apiKey: 'YOUR_API_KEY_HERE',
);
$client->contacts->getContactStats(
    'string',
    new GetContactStatsRequest([]),
);

```

```go response
package main

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

func main() {

	url := "https://api.brevo.com/v3/contacts/string/campaignStats"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("api-key", "<apiKey>")

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

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

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

}
```

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

url = URI("https://api.brevo.com/v3/contacts/string/campaignStats")

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

request = Net::HTTP::Get.new(url)
request["api-key"] = '<apiKey>'

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

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

HttpResponse<String> response = Unirest.get("https://api.brevo.com/v3/contacts/string/campaignStats")
  .header("api-key", "<apiKey>")
  .asString();
```

```csharp response
using RestSharp;

var client = new RestClient("https://api.brevo.com/v3/contacts/string/campaignStats");
var request = new RestRequest(Method.GET);
request.AddHeader("api-key", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift response
import Foundation

let headers = ["api-key": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.brevo.com/v3/contacts/string/campaignStats")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

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()
```