API Reference
Campaigns
Status & Metrics

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

StatusMeaning
idleNo reach evaluation has run since this audience was bound.
pendingEvaluation is queued or in progress — evaluatedCount is not yet reliable.
okEvaluation completed successfully. evaluatedCount and evaluatedAt reflect the current state.
failedEvaluation 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

StateMeaning
not_scheduledCampaign has no execution history and no schedule.
scheduledCampaign has a future scheduled send.
pending_or_overdueScheduled send time has passed but no execution has started.
runningLatest execution is running.
completedLatest execution completed.
failedLatest 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

CodeHTTPMeaning
JOURNEY_API.PUBLIC.CAMPAIGNS.NOT_FOUND404Campaign not found.
JOURNEY_API.PUBLIC.CAMPAIGNS.TYPE_UNSUPPORTED409Campaign type is not supported for this public operation yet.
JOURNEY_API.PUBLIC.CAMPAIGNS.STATUS_INCONSISTENT500Status cannot be assembled because execution metadata is inconsistent.
JOURNEY_API.AUTH.INSUFFICIENT_SCOPE403Token lacks the required scope.

Choosing Between Status and Metrics

/status/metrics
Scopecampaigns:readanalytics:read
Execution stateYesNo
Schedule detailsYesNo
Pipeline countsLatest runLatest run counts only
Use caseOperational monitoringBI and reporting

See Also