Partner API
AI index
Launch contract: sandbox is synthetic and cannot charge or create a patient. Use only signed-onboarding origins and credentials.

Settlement summaries

The finance surface is intentionally separate from catalog delivery. Run it in an isolated finance worker with the environment's finance key; the runtime key cannot read it. Sandbox returns synthetic fixtures. Production 2.1 returns only immutable statement revisions explicitly authored and released by Finance from a separate append-only release store.

The Partner API has no read access to live purchase activity. It does not derive amount due, paid state, counts, or release timing from configuration, runtime events, or the wall clock.

Read every immutable release#

Amounts are integer USD cents. Follow only an opaque next_cursor returned by Chia; do not construct, decode, join to a user, or use a release ID as a cursor. Cursors expire after 24 hours.

Production releases are newest first. Persist each release by its unique id. A correction has a higher revision and points directly to the immediately prior immutable release in supersedes_id. Never mutate a stored release and never sum a release after it has been superseded.

import {
  createFinancePartnerClient,
  type ProductionSettlementSummary,
} from "@chiahealth/partner";

const finance = createFinancePartnerClient({
  environment: "production",
  apiOrigin: process.env.CHIA_API_ORIGIN!,
  financeKey: process.env.CHIA_FINANCE_KEY!,
});

let startingAfter: string | undefined;
do {
  const page = await finance.listSettlementSummaries({
    limit: 25,
    ...(startingAfter ? { startingAfter } : {}),
  });

  await financeStore.transaction(async (tx) => {
    for (const release of page.data.data as ProductionSettlementSummary[]) {
      await tx.insertImmutableRelease(release.id, release);
      if (release.supersedes_id !== null) {
        await tx.markSuperseded(release.supersedes_id, release.id);
      }
    }
  });

  startingAfter = page.data.has_more
    ? page.data.next_cursor ?? undefined
    : undefined;
} while (startingAfter);

The complete runnable worker is examples/partner-reference-backend/src/finance.ts.

Finish a traversal within 24 hours. Do not store a cursor as a long-lived job checkpoint or carry it into a later run. On cursor_expired, discard the cursor, restart from the first page, and idempotently reconcile release IDs and supersession links. Treat invalid_cursor or any other invalid-request response as malformed or wrong-environment input and investigate rather than retrying it.

Release semantics#

Field/state Meaning Required handling
id Unique immutable Finance release ID Insert once; reject a different body for an existing ID
revision: 1 First released revision of a logical statement supersedes_id is null
revision > 1 Append-only correction or paid-state revision supersedes_id names the immediately prior release
released_at Time Finance released this exact revision Do not replace with fetch or processing time
service_fee.status: finalized The released record says the full fixed fee remains due amount_paid is zero and amount_due_to_partner equals the fixed fee
service_fee.status: paid The released record says the fixed fee was paid amount_paid equals the fixed fee, amount due is zero, and paid_at is present
aggregate_activity: null No aggregate was released with this revision Do not infer zero activity
null aggregate count with below_minimum_group_size A privacy release exists but the value is suppressed Store/display suppression; do not estimate
non-null aggregate count Chia's internal immutable threshold and composition release checks passed Treat only as the documented period aggregate
Empty production page No Finance release is present in this traversal Do not infer zero activity, zero liability, no amount owed, or no payment

fixed_service_fee, amount_paid, amount_due_to_partner, status, payable_on, paid_at, terms_version, and as_of all come from the same Finance-authored immutable release record. The API validates their internal consistency but never calculates them from purchases or events.

Privacy boundary#

The public production projection contains no patient, order, payment-level, shipment, program, geography, event, treatment, or date-row field. There is no line item, individual status, filter, expansion, or lookup endpoint.

aggregate_activity is nullable. For a non-null count, the private release record must prove both:

  1. the released group threshold passed and is at least the hard floor of 10; and
  2. the approved composition check passed for the immutable reporting population.

Those threshold and composition release proofs remain internal and are not returned. A partner-specific approval may require a group larger than 10 but can never reduce the floor. A malformed release, an unapproved composition, or a count below the threshold fails closed or returns a null suppressed count; it is never silently skipped or rounded into a public value.

The fixed commercial fee is activity-independent. Aggregate activity is informational and cannot change compensation. A refund, cancellation, or support interaction never turns this API into an order ledger.

Refresh model#

  • Poll from the isolated finance worker on the agreed schedule and traverse all pages.
  • V2 emits no live settlement webhook. The synthetic settlement_summary.finalized test never wakes a worker.
  • Reconcile immutable IDs and supersession links transactionally before calculating the current effective view.
  • Cache only within the returned private cache policy.
  • Never expose settlement data to the mobile app, catalog service, general analytics, or an AI agent.

The synthetic settlement_summary.finalized webhook-test shape contains only a synthetic summary ID and UTC period. It is a receiver certification no-op, not a live refresh hint, statement, or proof that a payment occurred.