# List Send Sources

> GET /emails/sources — per-source send and engagement rollups for campaigns, automations and individual sends.

`GET /emails/sources`

Rolls up every email on your account by **what sent it** and returns one row per source: one per campaign, one per automation, an `api` row covering [`POST /emails`](https://www.sendping.co/docs/api/emails-send) sends made with an API key, and an `individual` row for mail composed in the dashboard. Use it for a one-request overview of which surfaces are sending and how that mail is performing, without walking [`GET /emails`](https://www.sendping.co/docs/api/emails-list) yourself. Read-only; requires a read-scoped key.

Rows are ordered by `last_sent_at`, newest activity first. This endpoint takes no query parameters and is **not** paginated: it returns every source in one response and `has_more` is always `false`.

**Node.js**

```js
import { SendPing } from 'sendping';

const mb = new SendPing('mb_xxxxxxxxx');

const { data, error } = await mb.emails.sources();
console.log({ data, error });
```

**Ruby**

```ruby
require "sendping"

SendPing.api_key = "mb_xxxxxxxxx"

SendPing::Emails.sources
```

**PHP**

```php
<?php
require 'vendor/autoload.php';

use SendPing\SendPing;

$sendping = SendPing::client('mb_xxxxxxxxx');

$sendping->emails->sources();
```

**Python**

```python
import sendping

sendping.api_key = "mb_xxxxxxxxx"

sendping.Emails.sources()
```

**Go**

```go
import "github.com/shekhu10/sendping-sdks/sendping-go"

client := sendping.NewClient("mb_xxxxxxxxx")

sources, err := client.Emails.Sources()
```

**Rust**

```rust
use sendping::SendPing;

let mb = SendPing::new("mb_xxxxxxxxx");

let _sources = mb.emails.sources().await?;
```

**Java**

```java
import co.sendping.SendPing;
import co.sendping.SendPingResponse;

SendPing sendping = new SendPing("mb_xxxxxxxxx");

SendPingResponse response = sendping.emails().sources();
```

**.NET**

```csharp
using SendPing;

ISendPing sendping = SendPingClient.Create("mb_xxxxxxxxx");

var resp = await sendping.EmailListSourcesAsync();
```

**cURL**

```bash
curl -X GET 'https://www.sendping.co/api/emails/sources' \
  -H 'Authorization: Bearer mb_xxxxxxxxx'
```

**CLI**

```bash
sendping emails sources
```

### Response

**Response fields**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | string | No | The source type: `campaign`, `automation`, `api` (one-off API-key sends), or `individual` (composed in the dashboard). |
| `id` | string | null | No | The campaign or automation id. Always `null` for the `individual` row. |
| `name` | string | null | No | The campaign or automation name. `null` when the parent campaign or automation has since been deleted; for an unnamed campaign the subject line stands in here instead. |
| `subject` | string | null | No | The campaign subject line, as a secondary label. `null` for automation and individual rows, and `null` when the subject was already used as `name`. |
| `status` | string | null | No | The current campaign or automation status. `null` for the individual row and for a deleted parent. |
| `total` | number | No | Emails attributed to this source. |
| `sent` | number | No | How many of those were actually handed off for delivery (they have a `sent_at`). |
| `delivered` | number | No | Recorded `delivered` events for this source. |
| `opened` | number | No | Recorded `opened` events. These are raw event counts, not unique recipients — one recipient opening twice counts twice. |
| `clicked` | number | No | Recorded `clicked` events, counted the same raw way as `opened`. |
| `replied` | number | No | Recorded `replied` events. |
| `failed` | number | No | Emails from this source in the `failed` status. |
| `last_sent_at` | string | null | No | ISO 8601 creation time of the newest email in the group, or `null` when the group is empty. |

```json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "kind": "campaign",
      "id": "8f5c2a1e-7b3d-4f9a-9c12-2e6d4a7b8c90",
      "name": "June newsletter",
      "subject": "What's new in June",
      "status": "sent",
      "total": 1240,
      "sent": 1240,
      "delivered": 1216,
      "opened": 612,
      "clicked": 104,
      "replied": 12,
      "failed": 0,
      "last_sent_at": "2026-06-23T10:20:00.000Z"
    },
    {
      "kind": "automation",
      "id": "c9b16d4f-ba6c-4e2e-b044-6bf4404e57fd",
      "name": "Welcome series",
      "subject": null,
      "status": "enabled",
      "total": 318,
      "sent": 318,
      "delivered": 311,
      "opened": 190,
      "clicked": 44,
      "replied": 3,
      "failed": 0,
      "last_sent_at": "2026-06-22T18:04:00.000Z"
    },
    {
      "kind": "individual",
      "id": null,
      "name": null,
      "subject": null,
      "status": null,
      "total": 47,
      "sent": 47,
      "delivered": 47,
      "opened": 29,
      "clicked": 8,
      "replied": 1,
      "failed": 0,
      "last_sent_at": "2026-06-21T09:12:00.000Z"
    }
  ]
}
```

> **Note:** The `individual` row is omitted entirely when the account has never sent a direct email. A campaign or automation that was deleted still appears while its emails remain in the logs, with `name` and `status` as `null`.
