Status & Metrics
Observe campaign setup, execution state, and execution counts.
Base URL: https://api.experiture.ai/public/v1
Get Campaign Summary
Returns a redacted setup summary for a broadcast campaign. The summary is safe for third-party systems: it does not include internal wizard state, sample contact records, private execution metadata, or caller-supplied tenant headers.
GET /campaigns/:id/summary
Authorization: Bearer <token>Required scope: campaigns:read
Response - 200 OK
{
"success": true,
"data": {
"campaignId": "4130bada-9264-465f-bc0c-a26bebcfcc81",
"name": "Spring Re-engagement Direct Mail",
"campaignType": "broadcast",
"channel": "direct_mail",
"authoringStatus": "draft",
"createdAt": "2026-04-25T10:00:00.000Z",
"updatedAt": "2026-04-25T10:30:00.000Z",
"schedule": {
"kind": "digital_send",
"mode": "at",
"sendAt": "2026-05-01T09:00:00.000Z",
"timezone": "America/New_York",
"scheduled": true
},
"audience": {
"included": [
{ "id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "name": null, "type": "segment", "memberCount": null }
],
"excluded": [],
"reach": {
"status": "ok",
"evaluatedCount": 18432,
"evaluatedAt": "2026-04-25T10:20:00.000Z",
"isStale": false
}
},
"content": {
"template": {
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
"name": "Spring DM v3",
"status": "published",
"channel": "direct_mail"
},
"proofStatus": "unavailable"
},
"preflight": {
"status": "not_evaluated",
"checks": []
},
"latestExecution": {
"status": "not_scheduled",
"lastExecutionAt": null,
"counts": null
},
"links": {
"self": "/public/v1/campaigns/4130bada-9264-465f-bc0c-a26bebcfcc81/summary"
}
}
}audience.reach.status values
| Status | Meaning |
|---|---|
idle | No reach evaluation has run since this audience was bound. |
pending | Evaluation is queued or in progress — evaluatedCount is not yet reliable. |
ok | Evaluation completed successfully. evaluatedCount and evaluatedAt reflect the current state. |
failed | Evaluation failed. evaluatedCount reflects the prior successful run if available. Retry after a short delay or rebind the audience to trigger a fresh evaluation. |
schedule object variants
The schedule object uses a kind discriminator based on channel. For digital channels (email, SMS, push):
{
"kind": "digital_send",
"mode": "at",
"sendAt": "2026-05-01T09:00:00.000Z",
"timezone": "America/New_York",
"scheduled": true
}For direct mail campaigns:
{
"kind": "direct_mail_batch",
"mode": "batch_on_date",
"batchDate": "2026-05-01",
"timezone": "America/New_York",
"timezoneSource": "request",
"scheduled": true
}timezoneSource is one of "request" (caller-supplied), "tenant_default" (tenant fallback), or "utc_fallback" (no timezone configured).
isStale is true when the audience definition changed after the last evaluation — counts may not reflect current segment membership.
If the campaign exists but is not a supported public v1 type, the API returns 409 SUMMARY_TYPE_UNSUPPORTED, not 404.
Get Campaign Status
Returns schedule details and the latest execution run for a broadcast campaign.
GET /campaigns/:id/status
Authorization: Bearer <token>Required scope: campaigns:read
Response - 200 OK
{
"success": true,
"data": {
"campaignId": "4130bada-9264-465f-bc0c-a26bebcfcc81",
"name": "Spring Re-engagement Direct Mail",
"authoringStatus": "published",
"schedule": {
"scheduleId": "44444444-4444-4444-4444-444444444444",
"sendAt": "2026-05-01T09:00:00.000Z",
"timezone": "America/New_York",
"active": true
},
"execution": {
"state": "completed",
"touchpointId": 123,
"manifestId": "33333333-3333-3333-3333-333333333333",
"channel": "direct_mail",
"lastExecution": {
"executionId": "55555555-5555-5555-5555-555555555555",
"startedAt": "2026-05-01T09:00:05.000Z",
"completedAt": "2026-05-01T09:47:22.000Z",
"status": "completed",
"counts": {
"scheduled": 17491,
"hydrated": 17491,
"composed": 17485,
"injected": 17485,
"sent": 17480,
"failed": 5
}
}
}
}
}If the campaign has not been scheduled, the response omits schedule and returns execution.state: "not_scheduled".
execution.state values
| State | Meaning |
|---|---|
not_scheduled | Campaign has no execution history and no schedule. |
scheduled | Campaign has a future scheduled send. |
pending_or_overdue | Scheduled send time has passed but no execution has started. |
running | Latest execution is running. |
completed | Latest execution completed. |
failed | Latest execution failed. |
Get Campaign Metrics
Returns pipeline counts for the latest execution. Campaigns with no execution return zero counts.
GET /campaigns/:id/metrics
Authorization: Bearer <token>Required scope: analytics:read
Metrics intentionally use analytics:read, not campaigns:read.
Response - 200 OK
{
"success": true,
"data": {
"campaignId": "4130bada-9264-465f-bc0c-a26bebcfcc81",
"counts": {
"scheduled": 17491,
"hydrated": 17491,
"composed": 17485,
"injected": 17485,
"sent": 17480,
"failed": 5
}
}
}Common errors
| Code | HTTP | Meaning |
|---|---|---|
JOURNEY_API.PUBLIC.CAMPAIGNS.NOT_FOUND | 404 | Campaign not found. |
JOURNEY_API.PUBLIC.CAMPAIGNS.TYPE_UNSUPPORTED | 409 | Campaign type is not supported for this public operation yet. |
JOURNEY_API.PUBLIC.CAMPAIGNS.STATUS_INCONSISTENT | 500 | Status cannot be assembled because execution metadata is inconsistent. |
JOURNEY_API.AUTH.INSUFFICIENT_SCOPE | 403 | Token lacks the required scope. |
Choosing Between Status and Metrics
/status | /metrics | |
|---|---|---|
| Scope | campaigns:read | analytics:read |
| Execution state | Yes | No |
| Schedule details | Yes | No |
| Pipeline counts | Latest run | Latest run counts only |
| Use case | Operational monitoring | BI and reporting |
See Also
- Campaign Reporting Guide - reporting patterns
- Schedule & Send - trigger execution
- Campaigns Overview - scope reference