---
title: "Connect a Whop account"
method: POST
path: "/v1/connect/whop-ads/credentials"
tags: ["Connect"]
---

# Connect a Whop account

`POST /v1/connect/whop-ads/credentials`

## Request

- Base URL: `https://zernio.com/api`
- URL: `https://zernio.com/api/v1/connect/whop-ads/credentials`
- Auth: HTTP bearer

Connect a Whop account with an Account API key from the Whop dashboard (Developer >
API keys). The key only has to be able to read its own account: Zernio calls
`GET /accounts/me` once to learn the account id (`biz_...`) and name, then stores the key.

What the connection unlocks today is the Whop Pixel through the tracking-tags API: the
account id is the pixel, so `GET /v1/accounts/{accountId}/tracking-tags` lists it and
`POST .../tracking-tags/{biz_...}/install` puts it on a Shopify store or WordPress site.
Whop campaigns are not managed through Zernio. One Whop account per profile.

## Request body

- object
  - `apiKey` string, required: Account API key from the Whop dashboard.
  - `profileId` string, required: Your Zernio profile ID
  - `state` string: Optional state passthrough for the connect flow.
  - `redirect_url` string, uri: Optional URL to redirect to after successful connection, echoed back as redirectUrl.

## Response `200`

Whop account connected

- object
  - `accountId` string: The Zernio account id (platform `whopads`) to use as `{accountId}` on the tracking-tags routes.
  - `whopAccountId` string: The Whop account id (`biz_...`), which is also the tracking tag id.
  - `accountName` string
  - `redirectUrl` string

## Other responses

- `400`: Invalid request
- `401`: Unauthorized, or the API key could not read its Whop account (code invalid_credentials).
- `402`: Payment method or enterprise contract required. The authenticated account hit a billing gate before the connection could proceed. Three reasons: - `free_tier_exceeded`: the team has connected more accounts than the free tier allows. Add a payment method on the dashboard to continue (the user will be billed per additional connected account). - `twitter_passthrough`: connecting an X account requires a card on file from day one because X API calls incur real per-call pass-through costs. Applies to the 1st X account, not only the 3rd+. - `enterprise_required`: the team is on an enterprise contract with a negotiated connected-account cap and has reached it. Self-service teams have NO connected-account cap (the $1/account rate continues at any scale), so this reason can only fire for teams whose contract sets an explicit limit. `dashboard_url` deep-links to the enterprise contact page rather than the billing tab. The end-user already has a card on file; this gate is about contract terms, not card collection. - `card_verification_required`: the card on file was flagged at add time (prepaid, or issued in a different country than the billing address) and a one-time verification charge of `details.verification_amount_cents` (USD) is pending. The charge is credited to the team's usage balance, not a fee. `dashboard_url` opens the billing page on the verification step; the request succeeds once it is paid. SDK consumers should switch on `reason` to render the right prompt. For `free_tier_exceeded`, `twitter_passthrough` and `card_verification_required`, redirect the end-user to `dashboard_url`: it opens the add-payment-method drawer on the Zernio billing page, and the request succeeds once the card is on file (or verified). For `enterprise_required`, redirect to `dashboard_url` (the enterprise contact form) to adjust the contract's limit.
- `403`: Ads add-on required.
- `409`: The profile already has a different Whop account connected (code PROFILE_PLATFORM_CONFLICT).

## Changes

- **2026-10-06** `698fd1d46648`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/connect/whop-ads/credentials/post.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) · [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zernio/apis/zernio-api/revisions/4e74db179e73?raw)
