API ReferenceCampaigns
Campaign Analytics
Per-campaign donation analytics with trend data, top donors, and breakdowns.
GET /api/reporting/campaign/:id
Returns detailed analytics for a single campaign. Includes a daily donation trend, top donor list, payment method breakdown, frequency breakdown, UTM source breakdown, and peak donation hour.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The campaign ID to retrieve analytics for |
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
orgId | string | Yes | The organization ID. Used to verify access. | |
startDate | string | No | 30 days ago | ISO 8601 start date for the trend window |
endDate | string | No | Today | ISO 8601 end date for the trend window |
Authentication
Requires a valid Clerk session JWT in the Authorization: Bearer header. The authenticated user must be a member of the organization that owns this campaign.
Response
campaign object
| Field | Type | Description |
|---|---|---|
id | string | Campaign ID |
title | string | Campaign title |
goalAmountCents | integer or null | Fundraising goal in cents |
raisedAmountCents | integer | Running total raised (all-time) |
donationCount | integer | Total succeeded donation count (all-time) |
status | string | Campaign status |
startDate | string or null | ISO 8601 campaign start date |
endDate | string or null | ISO 8601 campaign end date |
summary object
| Field | Type | Description |
|---|---|---|
totalRaisedCents | integer | Total amount raised in cents |
donationCount | integer | Total number of succeeded donations |
avgGiftCents | integer | Average donation amount in cents |
uniqueDonors | integer | Number of unique donors |
recurringCount | integer | Number of recurring donations |
oneTimeCount | integer | Number of one-time donations |
trend array
Daily donation data for the requested date range. One entry per calendar day.
| Field | Type | Description |
|---|---|---|
date | string | Date in YYYY-MM-DD format |
amountCents | integer | Total donated on this day in cents |
count | integer | Number of donations on this day |
topDonors array
Up to 10 top donors by total amount given.
| Field | Type | Description |
|---|---|---|
donorId | string | Internal donor ID |
firstName | string | Donor first name, or "Anonymous" |
lastName | string | Donor last initial (e.g., "S.") |
totalCents | integer | Total amount given in cents |
count | integer | Number of donations |
paymentMethods array
| Field | Type | Description |
|---|---|---|
method | string | "CARD", "ACH", "APPLE_PAY", "GOOGLE_PAY", or "UNKNOWN" |
count | integer | Number of donations via this method |
amountCents | integer | Total donated via this method in cents |
frequencyBreakdown array
| Field | Type | Description |
|---|---|---|
frequency | string | "ONE_TIME", "MONTHLY", "QUARTERLY", or "ANNUAL" |
count | integer | Number of donations at this frequency |
amountCents | integer | Total donated at this frequency in cents |
topSources array
Up to 5 top UTM sources by total amount raised.
| Field | Type | Description |
|---|---|---|
source | string | UTM source value (e.g., "email") |
count | integer | Number of donations from this source |
amountCents | integer | Total donated from this source in cents |
peakHour
The UTC hour of day (0-23) that received the most donations. null if the campaign has no donations.
Example
curl "https://givelink-api-production.up.railway.app/api/reporting/campaign/clx9876543210?orgId=clxabc123456&startDate=2026-02-01&endDate=2026-03-04" \
-H "Authorization: Bearer <clerk-session-jwt>"{
"campaign": {
"id": "clx9876543210",
"title": "Spring 2026 Annual Fund",
"goalAmountCents": 5000000,
"raisedAmountCents": 1245000,
"donationCount": 87,
"status": "ACTIVE",
"startDate": "2026-03-01T00:00:00.000Z",
"endDate": "2026-06-30T23:59:59.000Z"
},
"summary": {
"totalRaisedCents": 1245000,
"donationCount": 87,
"avgGiftCents": 14310,
"uniqueDonors": 74,
"recurringCount": 23,
"oneTimeCount": 64
},
"trend": [
{ "date": "2026-02-01", "amountCents": 0, "count": 0 },
{ "date": "2026-02-02", "amountCents": 25000, "count": 2 },
{ "date": "2026-02-03", "amountCents": 100000, "count": 7 }
],
"topDonors": [
{ "donorId": "clxdonor001", "firstName": "Margaret", "lastName": "T.", "totalCents": 250000, "count": 1 },
{ "donorId": "clxdonor002", "firstName": "Robert", "lastName": "K.", "totalCents": 100000, "count": 2 }
],
"paymentMethods": [
{ "method": "CARD", "count": 70, "amountCents": 900000 },
{ "method": "ACH", "count": 17, "amountCents": 345000 }
],
"frequencyBreakdown": [
{ "frequency": "ONE_TIME", "count": 64, "amountCents": 800000 },
{ "frequency": "MONTHLY", "count": 23, "amountCents": 445000 }
],
"topSources": [
{ "source": "email", "count": 45, "amountCents": 650000 },
{ "source": "facebook", "count": 12, "amountCents": 180000 }
],
"peakHour": 19
}Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Validation failed | orgId is missing or invalid |
| 401 | Unauthorized | Missing or invalid Authorization header |
| 403 | Forbidden | Authenticated user is not a member of the specified org |
| 404 | Campaign not found | No campaign with this ID exists for the given org |
Last updated on 4/5/2026