> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendpost.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> Notable changes to the SendPost public REST API, including the full field-level diff of the v1 response contract.

<Update label="2026-09-22" tags={["v1 contract"]}>
  ## Versioned response contract (legacy → v1)

  The public REST API now supports two response contracts, selected per request with the `X-SendPost-Public-Contract` header.

  * **`legacy`** (today's shape) remains the **default** — existing integrations are unaffected.
  * **`v1`** is available now via `X-SendPost-Public-Contract: v1`.
  * Responses carry `Deprecation`, `Sunset` (**31 March 2027, 23:59:59 UTC**), and `Link` headers. After the sunset, `v1` becomes the default.

  See [API Versioning & Migration](/api-reference/api-versioning) for the mechanism and step-by-step migration.

  ### What v1 changes, field by field

  `v1` normalizes field casing, removes internal/sensitive fields, and adds a few new fields. The complete diff per resource:

  <AccordionGroup>
    <Accordion title="Suppression">
      * **Added:** `reasonText` — public reason label (`manual` / `unsubscribe` / `hardBounce` / `spamComplaint` / `unknown`).
      * **Removed:** `groups`, `ipId`, `accountIPPoolId` (plus dashboard-only `ipPublicIP`, `ipPoolName`).
      * **Note:** `smtpError` is **unchanged** (already camelCase in legacy — it is *not* renamed).
    </Accordion>

    <Accordion title="IP">
      * **Added:** `autoWarmupEnabled` (boolean; computed from warmup state).
      * **Renamed:** `publicIP` → `publicIp`, `reverseDNSHostname` → `reverseDnsHostname`.
      * **Removed:** `systemDomain`, `accountIPPools`, `autoWarmupPlan` (replaced by `autoWarmupEnabled`), `deliverabilityPolicies`, and all per-provider settings blobs (`gmailSettings` … `checkpointSettings`).
    </Accordion>

    <Accordion title="IP Pool">
      * **Sub-account pools:** add `shouldOverflow`, `overflowPoolName`. No removals.
      * **Account pools:** **removed** `thirdPartySendingProviders`, `toAccountIPPools`, `warmupInterval`, `warmupIntervalSeconds`, `warmupQueueMode`, `resolveTemplateLocally`.
      * Nested `ips[]` follow the **IP** changes above.
    </Accordion>

    <Accordion title="Domain">
      * **Added:** `dnsProvider` (detected DNS host).
      * **Removed:** `gpt`, `gptVerified`, `dkimDelegationInfo`, `dmarcDelegationInfo`, `returnPathDelegationInfo`, `trackDelegationInfo`.
      * **Unchanged under v1:** the `domain/v2` endpoints (`/subaccount/domain/v2`, `/account/domain/v2`) return the same shape for legacy and v1.
    </Accordion>

    <Accordion title="Message">
      * **Renamed:** `messageID` → `messageId`, `subAccountID` → `subAccountId`, `publicIP` → `publicIp`.
      * **Removed:** `customFields`, `resolveTemplateLocally` (plus internal-plumbing fields already hidden from legacy).
    </Accordion>

    <Accordion title="Event">
      * **Renamed:** `eventID` → `eventId`, `messageID` → `messageId`, `messageSubject` → `subject`.
      * **Removed (top-level):** `smtpCode`, `smtpDescription` (still available nested under `eventMetadata`), plus mock-send flags.
      * **`eventMetadata`:** renamed `clickedURL` → `clickedUrl`, `trackedIP` → `trackedIp`, `cityID` → `cityId`; removed `sendpostLinkId` and all provider-specific fields (`sendgrid*`, `ses*`, `sparkpost*`, `mailgun*`, `customSmtp*`, `postmark*`).
    </Accordion>

    <Accordion title="SubAccount">
      * **Removed:** `smtpAuths`, `blocked_at`, `hb_exempt`, `generate_weekly_report`, `skip_global_suppression_check`, `handlers` (plus `block_reason`, `created_by`, `updated_by` already hidden from legacy).
      * `apiKey`, `accountId` are unchanged.
    </Accordion>

    <Accordion title="Member">
      * **Renamed:** `url` → `logoUrl`.
      * **Removed:** `isForbidden`, `notesColor`, `twoFactorEnabled`, `twoFactorVerifiedAt` (plus `firebaseUID`, `isGodMode` already hidden from legacy).
    </Accordion>

    <Accordion title="Webhook">
      * **Removed:** `secret` (HMAC signing key), `eventSubOptions`. `secret` remains available on the **legacy** contract for same-account callers.
      * **List variant** (`successRate`): `v1` always returns a number; legacy returns `null` when unmeasured.
    </Accordion>

    <Accordion title="Account / Account Setting">
      * **Renamed:** `logoURL` → `logoUrl`.
      * **Removed:** all billing internals (`stripe*`, `creditBalance`, `promoCode`, `isLegacyBilling`, `trialPeriod`, …), moderation/ops fields (`demoLocked*`, `*SlackEndpoint`, `slackToken`, `rbacEnabled`, `hubspotCompanyId`, …) and audit fields. Public callers already receive the curated `v1` shape today.
    </Accordion>

    <Accordion title="Email (send)">
      * **`EmailResponse`:** no field changes (`to`, `submittedAt`, `messageId`, `errorCode`, `message`).
      * **Request body:** the TPSP routing internals `tpspIppool`, `tpspTemplate`, `tpspIp` are not part of the v1 shape.
    </Accordion>

    <Accordion title="Stats (all stat endpoints)">
      Pervasive v1 changes across the stat family:

      * **Removed everywhere:** the bot/human breakdown `botOpened`, `botClicked`, `humanOpened`, `humanClicked`; the ops-only `spamRate`, `totalQD`, `warmupVersion`, `warmupSkipped`; and the raw `day` / `month` / `year` date columns.
      * **Renamed:** `publicIP` → `publicIp`, `ipid` → `ipId`; provider stats `email_type` → `emailType` (and `email_type`/`name` → `provider` on the provider breakdown); sub-account stats `sid` → `subAccountId`, `name` → `subAccountName`; account IP-pool stats `accountIPPoolId` → `ipPoolId`, `name` → `ipPoolName`.
      * **`seedContactStats`** nested keys renamed: `rStat` → `rStats`, `agStat` → `groupStats`, `agDomainStat` → `domainStats`, `aIPStat` → `ipStats`, `aPStat` → `providerStats`.
      * **`blacklistResource`** normalized from `Snake_Case`/`PascalCase` to camelCase throughout (`Add_Date` → `addDate`, `Last_Check` → `lastCheck`, `Contact_List_ID` → `contactListId`, etc.).
      * **`?filter=bot`** returns a normalized `{ enabled, raw, filtered, botOpened, botClicked }` view under v1.
      * **Unchanged:** `dateStat`, `validationStat`, `accountCycleUsage`, `postmasterDomainStat`.
    </Accordion>
  </AccordionGroup>

  <Info>
    For the authoritative response of any endpoint under `v1`, the schema on that endpoint's API Reference page is the source of truth.
  </Info>
</Update>
