Skip to main content
The Experimental API uses date-based versions. Pin a version when you want a stable API contract. Official SDKs automatically send the version used to generate them.
If you don’t pass an Api-Version-Date or have a stored API-key pin, the stable API model is used. Requests with neither are served by the pre-versioning behavior, so existing integrations keep working unchanged. Pin a dated version to opt into the latest API.

Application programming interface key version pins

API keys carry their own API version pin. Requests authenticated with an API key use that pin when they omit Api-Version-Date. Existing keys without a stored pin use 2025-01-01. Newly created keys use the latest released version. An explicit Api-Version-Date header always takes precedence over the API key’s pin, so you can test an upgrade before changing the saved version. Every version automatically gets new endpoints and optional fields. Breaking changes create a new dated version, which the changelog below lists.

Changelog

Latest
Account in-transit balances
Account balance breakdowns now expose in_transit alongside pending.
  • Add pending and in_transit to present the total amount awaiting settlement.
  • Callers pinned to earlier versions continue receiving the combined amount in pending.
Webhook API version input removed
The api_version input on POST /webhooks and PATCH /webhooks/{id} is removed.
  • New webhooks always use the v1 events and payloads. Requests passing api_version are rejected with a 400.
  • Pin a webhook’s payload shape with api_version_date instead.
  • Existing v2 and v5 webhooks keep delivering. You can no longer create or switch webhooks to these versions.
Native dispute alert endpoints
Dispute alerts are now a native REST resource and remain dual-served with the legacy proxy.
  • GET /dispute_alerts lists an account’s alerts with cursor pagination, and filters by account_id, payment_id, type, and a creation window.
  • type replaces alert_type and names the two kinds an issuer sends: early_fraud_warning (Visa TC40 / Mastercard SAFE fraud reports) and dispute_alert (pre-dispute notices).
  • fee_charged replaces charge_for_alert and reports whether Whop actually billed the account. Early fraud warnings are never billed.
  • actionable reports whether refunding the payment can still prevent a chargeback.
  • payment and dispute objects are replaced by the payment_id and account_id tags. Timestamps are ISO 8601, with reported_at for when the issuer filed the report.
Fiat currency conversion on swaps
Fiat-pair swaps (POST /swaps with two fiat currencies) now support free-form currency conversion, and amount matches crypto swap semantics.
  • amount is the amount of from_token to convert at the mid-market rate — no negative balance required.
  • Sizing a partial repayment of a negative to_token balance moved to the new to_amount field (denominated in to_token, capped at the debt). amount and to_amount are mutually exclusive.
  • Omitting both still repays the full negative to_token balance.
  • Callers pinned to earlier versions keep the previous behavior: their fiat amount is treated as the to_token repayment amount.
Flat verification requirements
A verification’s requested_information is now a flat list: one requirement per entry, one write per answer.
  • Each entry names what’s needed in requirement — a document such as bank_statement, or a field key such as ssn — with a label to show the user.
  • Answer file entries with file (a direct upload ID). Answer text, date, phone, and select entries with value, and address entries with address. Nothing from the response is echoed back.
  • An entry marked multiple takes several files in one answer, in slot order — front first for a two-sided document.
  • An entry listing options also takes a value. For select entries, the options are the allowed answers. For identity documents, the options are the accepted ID types.
  • Keys that don’t apply are omitted, and rejected submissions carry structured errors with a stable code and a reason.
  • The nested requested_files/category form shape is gone from this version. Callers pinned to earlier versions keep it, and their answers are translated automatically.
Native promo code endpoints
Promo codes are now a complete top-level REST resource and remain dual-served with the legacy proxy.
  • GET /promo_codes lists an account’s promo codes and uses account_id instead of company_id.
  • POST /promo_codes creates promo codes. GET and DELETE /promo_codes/{id} retrieve and archive them.
  • POST /promo_codes/{id}/activate and POST /promo_codes/{id}/deactivate replace the legacy PATCH status write.
  • List responses use cursor pagination and support status, product, plan, timestamp, and sorting filters.
  • Callers pinned to earlier versions keep the legacy proxy contract unchanged.
Richer parent accounts
Account responses now expose a richer parent account relationship for connected accounts.
  • parent_account replaces parent_account_id.
  • The parent account includes its id, title, route, and logo_url.
Supported payout methods
Supported payout methods now have their own paginated endpoint.
  • GET /payouts/supported_methods lists the payout methods an account or user is eligible to add.
  • Supported methods use object: "supported_payout_method", and their podst_ IDs are passed as supported_payout_method_id.
  • Saved payout methods expose supported_payout_method. Payouts expose payout_method.supported_payout_method.
  • Use country to list supported methods for a country other than the payout account’s country.
  • GET /payouts/methods no longer accepts include_available or returns available_destinations.
  • Callers pinned to earlier versions keep destination_id, payout_destination, and payout_token.
Native card transactions, payout method arrival estimates
Card transactions now use native REST endpoints and remain dual-served with the legacy proxy.
  • GET /card_transactions lists an account’s card transactions, and GET /card_transactions/{id} retrieves one by its citx_ id. The list also takes a transaction_ids filter to fetch specific transactions in one request.
  • Card transactions are account-scoped: the owner is selected with account_id, defaulting to the account the credential belongs to.
  • Filters on transaction_ids, card_id, cardholder_id, status, created_after, and created_before. Timestamp filters are ISO 8601.
  • cardholder_id is new on the response: the user the card is assigned to.
Payout methods now carry amount-independent fee and delivery terms, and the quote no longer duplicates arrival estimates.
  • Each payout method returns fee_structure (percentage, fixed amount, and currency) and estimated_arrival (per-speed timestamps) without requiring an amount.
  • The quote’s standard and instant objects no longer include estimated_arrival. Read it from the method’s top-level estimated_arrival field.
Native Resolution Center endpoints
Resolution Center cases now use native REST endpoints and remain dual-served with the legacy proxy.
  • status, escalated, outcome, refund, reason, and available_actions expose case state and permitted actions.
  • Events are available from paginated GET /resolution_center_cases/{id}/events. Summaries are available from GET /resolution_center_cases/summary.
  • Writes use message and attachments. due_date is renamed response_due_at. Listing no longer requires account_id.
Native shipments endpoints
Shipments now use native REST endpoints and remain dual-served with the legacy proxy.
  • GET /shipments lists shipments. GET /shipments/{id} retrieves by shipment id or payment id.
  • POST /shipments creates a shipment, and PATCH /shipments/{id} updates its tracking number.
  • Responses use account_id and tracking_number, alongside carrier, tracking_url, order_id, and payment_id.
  • Callers pinned before this date keep the legacy proxy contract unchanged.
Native disputes endpoints
Disputes now use native REST endpoints and remain dual-served with the legacy proxy.
  • PATCH /disputes/{id} edits evidence, and POST /disputes/{id}/submit submits it. Evidence is nested under evidence.
  • GET /disputes/summary provides totals grouped by status and currency. List and retrieve return the same fields.
  • Responses use account_id, product_id, and plan_id, plus buyer alongside payment. Listing no longer requires account_id.
  • status and reason are normalized enums, and needs_response_by, rdr, and editable are replaced by their new fields.
  • Callers pinned before this date keep the legacy proxy contract unchanged.
Members and memberships
Members and memberships now use native resources with an account-oriented membership model and redesigned lifecycle actions.
  • Membership responses return plan_id and product_id instead of nested plan and product objects.
  • Listing memberships returns everything the caller can read — their own plus their managed accounts’ — and account_id/user_id narrow that list instead of switching modes or erroring.
  • Set cancel_at_period_end to schedule cancellation. The cancel action ends access immediately.
  • The extend action replaces add_free_days.
REST response and timestamp consistency
The Experimental API now uses consistent delete responses, timestamp inputs, and Account naming.
  • Delete endpoints for products, plans, checkout configurations, ads, ad groups, ad campaigns, social accounts, and bounty submissions return { id, deleted: true } instead of a bare boolean.
  • Timestamp filters on products, plans, checkout configurations, transfers, and financial reports accept ISO 8601 only instead of also accepting epoch seconds.
  • Product responses return account instead of company.
Partner business payout percentages
Partner businesses now expose separate payout rates for every income source.
  • payout_percentage is replaced by payout_percentages.
  • The nested object includes sales, ad_spend, transfer, and card_interchange rates.
Products and checkout configurations
Products and checkout configurations now use the Account model consistently.
  • Product request parameters use account_id instead of company_id.
  • Checkout configuration requests use account_id at the top level and inside inline plan objects.
  • Checkout configuration responses return account_id instead of company_id.
Checkout configuration timestamps
Checkout configuration timestamps now use the same format as the rest of the API.
  • created_at and updated_at are ISO 8601 strings instead of Unix epoch integers.
User balances
User balances now provide a complete, structured balance summary.
  • The flat total_usd and balances fields are replaced by a nested balance object.
  • The summary separates cash, crypto, in-flight treasury deposits, and balances for accounts the user owns.
Business referral earnings resources
Business referral earnings now identify the polymorphic resource that generated the earning.
  • receipt is replaced by resource.
  • access_pass is replaced by product.
  • Receipt-backed earnings return resource.object: "receipt" with receipt payment details.
  • The resource field can support additional earning resources in future versions without reusing receipt-specific fields.
Business referrals resource
Business referral volume and earnings are now reported as reconciling groups.
  • processing_volume, total_earnings, pending_payout, and completed_payout are replaced by nested volume_usd and earnings_usd objects.
  • Earnings rename base_amount/amount to transaction_amount_usd/commission_amount_usd and express payout_percentage as a fraction.
Plans resource
Plans now use the Account model consistently.
  • Request parameters and request bodies use account_id instead of company_id.
  • Plan responses return account instead of company.
Users resource
User access requests now use the Account model consistently.
  • Request parameters and request bodies use account_id instead of company_id.
  • Response shapes are unchanged.
Original version
The original Experimental API behavior before dated versioning existed.Requests without Api-Version-Date use this version so existing integrations keep working.