Skip to Content
Partner APIOverview

Partner API

Provision and manage end-customers entirely server-to-server. The Partner API is for resellers and platform integrators who want to embed Warm AI’s identification under their own brand — without sending their customers into the Warm AI dashboard.

Looking for the standard customer-facing API? See Identification API. The Partner API is only enabled for accounts flagged as partners — contact us if you need partner status enabled.


When to use it

Use the Partner API when:

  • You sell a product that bundles visitor identification (cold-email tools, sales-intel platforms, agency dashboards).
  • Your customers should never log into a Warm AI URL — you control the UX end-to-end.
  • You want per-customer quotas, billing, and reporting that you mirror into your own backend.

You don’t need the Partner API if you’re just identifying visitors on your own site — use the Identification API directly.


How the model works

┌──────────────────────────────────────────────────────────────┐ │ Partner account (you) │ │ ─────────────── │ │ • is_partner = true │ │ • one master api_key (the warm_… you authenticate with) │ │ │ │ ├── Child customer A (parent_api_key_id = master) │ │ │ • own api_key, own quota, own webhook │ │ │ • own tracking_script_id, own domain │ │ │ │ │ ├── Child customer B │ │ └── Child customer C │ └──────────────────────────────────────────────────────────────┘
  • Each child is a phantom user under your account. They have no login, no email inbox, no dashboard access. They exist purely as a billing + tracking unit you manage on their behalf.
  • Each child has its own api_key (which you can hand back to the customer for server-side calls), its own tracking_script_id (for pulse.js install), its own subscription row (quota / period / topup balance), and its own optional webhook_url.
  • All partner-* endpoints authenticate with your master x-access-key — never the child’s. The child’s key is for the child’s own tracker traffic.

Authentication

Every Partner API request must include:

HeaderDescription
x-access-keyYour master partner api key (starts with warm_…)
Content-Typeapplication/json for POST endpoints

The API rejects the call with 401 if the key is missing, unknown, or revoked, and 403 if the key is valid but the account isn’t flagged is_partner=true.

Never embed your master x-access-key in a browser, mobile app, or any client-side bundle. It has full provisioning authority over every customer you’ve created — treat it like a Stripe secret key.


Billing model

Each child has its own subscription row with:

FieldMeaning
monthly_id_quotaIDs the child gets each period (resets on roll-over). Set this when creating or updating the child.
ids_used_this_periodCounter, resets to 0 at period roll-over (or when you change monthly_id_quota).
topup_balanceNon-expiring pool consumed after monthly_id_quota is exhausted.
current_period_endWhen the period rolls over and the counter resets. Defaults to 30 days from creation.
id_price_pence_overrideYour per-ID rate for this child, in pence. Informational — used for partner-side billing math.

The partner is invoiced for the IDs their children consume, aggregated across all customers, on whatever commercial agreement you have with us. You bill your end-customers however you like — the per-child id_price_pence_override is the unit cost you’ve agreed for that customer, so you can build margin into your own pricing.

How your own pool is billed

Above the per-child rows sits your pool. Every identification any of your children consumes draws from it. Which way you pay for that pool is set by pool_billing_mode, returned by partner-pool-state.

Modepool_billing_modeHow it works
PrepaidprepaidYou buy IDs up front. They land in topup_balance and are drawn down as your children consume. Optionally refills itself, see auto-reload below.
Monthly invoiceinvoice_monthlyYou consume first and we invoice in arrears on your billing anchor day. No balance to keep topped up.

Both modes price at partner_per_id_pence, your agreed rate per identification. That rate is set by Warm as part of your commercial agreement and is not self-serve. Until it is set, top-ups are rejected, so if you are onboarding and partner-pool-state returns partner_per_id_pence: null, that is the thing to chase before anything else.

On prepaid you can have the pool refill itself: save a card, set a threshold and a reload amount, and we charge that card whenever available drops below the threshold. If auto-reload looks enabled but the pool is not refilling, check auto_reload.stripe_payment_method_id and auto_reload.consecutive_declines in the pool-state response before contacting support.


Endpoint surface

These endpoints cover the full customer lifecycle:

EndpointPurpose
POST partner-create-child-keyMint a brand-new managed customer (key + tracker + subscription)
POST partner-update-childChange a child’s name, quota, rate, status, or period
GET partner-list-childrenEnumerate your customers with their current quota / usage / status
POST partner-adopt-existing-keyConvert one of your existing direct trackers into a managed customer
POST partner-release-childReverse an adoption — child’s tracker returns to your direct account
GET partner-pool-stateRead your pool balance, auto-reload config and recent top-ups

Plus the standard customer-facing endpoints, which you’ll call with the child’s api key (not yours) to fetch their visitors:

EndpointPurpose
GET list-visitorsPull identified visitors for one tracker — accepts tracker_site, since, source, search, limit, offset
GET api-account-statusQuota / topup status for one child

What’s not in the API yet

These pieces are planned and tracked on the roadmap. Until they ship, work around them as noted.

FeatureWorkaroundTracking
Real-time events for period roll-over, quota exhaustion, topup balance changesThe 4 immediate-action events (child.created / updated / released / adopted) are live — see Webhooks. Poll partner-list-children for per-child state, and partner-pool-state for your own balance.KAN-79 / 80 / 81
Programmatic pool balanceSee partner-pool-state — balance, auto-reload config and last 10 top-ups in one read✅ Live
Paginated top-up history beyond the last 10partner-pool-state returns the most recent 10. Ask support if you need a fuller export.Planned
Partner → child topup transfer (gift IDs from your balance to one child’s topup_balance)See partner-transfer-topup — atomic transfer with insufficient-balance protection and child.topup_changed(reason="gift") event✅ Live
Rotate a lost child api key plaintextSee partner-rotate-child-key — rate-limited to 10/child/24h, audit-logged✅ Live
CDN whitelabel for the tracker scriptSee separate CDN whitelabel docs (coming soon)KAN-38

Next steps

  • Quick Start — end-to-end TypeScript walkthrough: create a child, install the tracker, fetch visitors, release.
  • Endpoints — full reference for every partner-* endpoint.
  • Webhooks — real-time partner-side state-change events.
Last updated on