Skip to Content
DevelopersPartner Program APIs

Partner Program APIs

REST reference for the Active Reach partner program (Refer & Earn). The companion user-facing guide is at Refer & Earn.

Distinct from /api/v1/loyalty/referrals/* — those endpoints serve the customer-facing loyalty referral program (operator’s customers refer each other). This page covers the operator → Aegis platform partner program.

All endpoints require a Bearer token in Authorization unless noted.

Surface map

ConcernMethod + Path
Billing chip summaryGET /api/v1/billing/referral
Public landing redirectGET /refer/{code}
Referrer dashboardGET /api/v1/referrals/dashboard
Wallet balanceGET /api/v1/referrals/wallet
Pending release scheduleGET /api/v1/referrals/wallet/pending
Transaction ledgerGET /api/v1/referrals/transactions
Active count + upgrade eligibilityGET /api/v1/referrals/active-count
Redeem creditsPOST /api/v1/referrals/credits/redeem
Affiliate upgrade (initiate)POST /api/v1/affiliates/upgrade
KYC submitPOST /api/v1/affiliates/kyc/submit
KYC profile (read)GET /api/v1/affiliates/kyc/profile
Payout requestPOST /api/v1/affiliates/payouts/request
Payouts listGET /api/v1/affiliates/payouts
Credits → cashPOST /api/v1/affiliates/credits-to-cash
TDS certificates listGET /api/v1/affiliates/tds-certificates
Agency deal registerPOST /api/v1/agencies/deals/register
Agency deal proofPOST /api/v1/agencies/deals/{id}/proof
Agency dashboardGET /api/v1/agencies/dashboard

Billing chip summary

GET /api/v1/billing/referral

Single-shot summary for the chip on /dashboard/settings/billing and the hero on /dashboard/settings/refer-and-earn.

{ "code": "AEG-7K2X9", "referrals_count": 12, "credits_earned": 18500.00, "credits_currency_symbol": "₹", "partner_status": "USER", "credits_available": 11300.00, "credits_pending": 7200.00, "pending_next_release_date": "2026-06-14", "is_dormant": false, "upgrade_eligible": false }

partner_statusUSER / AFFILIATE / AGENCY. Auto-generates a referral code on first call.

Public landing redirect

GET /refer/{code} → 301 /sign-up?ref={code}

The canonical shareable URL. Codes match ^[A-Za-z0-9-]{6,16}$; invalid codes redirect to /sign-up plain (no 404).

Attribution lands when the new org completes onboarding — the sign-up page writes the aegis_ref_code cookie (60-day TTL), the onboarding context reads it, and ReferralService.validate_referral_code_at_signup writes the referee_relationships row.

Wallet balance

GET /api/v1/referrals/wallet
{ "status": "SUCCESS", "credits_balance": 11300.00, "credits_earned": 18500.00, "credits_redeemed": 7200.00, "credits_pending": 7200.00, "pending_next_release_date": "2026-06-14", "cash_balance": 45000.00, "cash_earned": 60000.00, "cash_withdrawn": 15000.00, "is_dormant": false, "last_activity_at": "2026-05-25T14:22:00Z" }

Brand-new tenants without a wallet row get a zeroed shape (wallet rows are lazy-created on first earning event).

Pending release schedule

GET /api/v1/referrals/wallet/pending
{ "status": "SUCCESS", "total_pending": 7200.00, "next_release_date": "2026-06-14", "release_schedule": [ { "release_date": "2026-06-14", "total_amount": 2400.00, "transaction_count": 2 }, { "release_date": "2026-06-28", "total_amount": 3100.00, "transaction_count": 4 } ] }

Credits enter a 30-day hold (India) / 60-day hold (Global) after the referee’s first payment clears. The run_pending_credit_release cron releases them daily at 02:00 UTC.

Redeem credits

POST /api/v1/referrals/credits/redeem Content-Type: application/json { "invoice_id": "inv_abc123", "invoice_total": 11300.00, "requested_amount": 5650.00 }

Caps enforced server-side:

  • requested_amount <= credits_balance (full balance ceiling)
  • requested_amount <= invoice_total * 0.5 (50% per-invoice cap)
  • Passthrough channel costs (SMS / WhatsApp / RCS / email gateway) are NOT eligible — backend rejects with PASSTHROUGH_INVOICE.

Affiliate flow

1. Initiate upgrade (at 11th active referral)

POST /api/v1/affiliates/upgrade

Creates a KYC_PENDING profile. Operator UI surfaces the upgrade banner when GET /api/v1/referrals/active-count returns upgrade_eligible: true.

2. Submit KYC

POST /api/v1/affiliates/kyc/submit Content-Type: application/json { "full_name": "Aman Shivhare", "pan_number": "ABCDE1234F", "pan_name": "Aman Shivhare", "gst_number": "22AAAAA0000A1Z5", "bank_account_number": "1234567890", "bank_ifsc": "HDFC0001234", "bank_account_holder_name": "Aman Shivhare", "entity_type": "INDIVIDUAL" }

PAN + bank account encrypted at the service layer. Admin approves via /api/v1/admin/referrals/kyc/{org_id}/approve.

3. Read masked profile

GET /api/v1/affiliates/kyc/profile
{ "kyc_status": "KYC_APPROVED", "pan_masked": "Aman Shivhare", "gst_number": "22AAAAA0000A1Z5", "bank_account_masked": "XXXXXX7890", "bank_ifsc": "HDFC0001234", "kyc_submitted_at": "2026-05-10T11:23:00Z", "kyc_approved_at": "2026-05-11T09:18:00Z", "rejection_reason": null }

Never returns the encrypted PAN or bank account in cleartext. Update flows require full re-entry.

4. Request payout

POST /api/v1/affiliates/payouts/request Content-Type: application/json { "requested_amount": 18000.00 }

Backend validates:

  • KYC must be KYC_APPROVED
  • Amount ≥ ₹1,000 (program minimum)
  • Amount ≤ cash_balance
  • Net-30 guardrail (commissions less than 30 days old not eligible)

5. Payouts list + TDS

GET /api/v1/affiliates/payouts GET /api/v1/affiliates/tds-certificates

TDS rates: 10% no-PAN · 2% PAN-verified · 0% GST-registered. Form 16A generated quarterly by run_tds_certificate_generation.

Agency flow

Register a deal (90-day exclusivity)

POST /api/v1/agencies/deals/register Content-Type: application/json { "prospect_company_name": "Acme Industries Pvt Ltd", "prospect_domain": "acme.com", "prospect_contact_email": "[email protected]", "estimated_deal_value": 500000, "notes": "Industry: F&B chain. Est MAU: 80K. Demo June 12." }

Requires a signed reseller agreement (enforced by ResellerValidationService — returns 403 otherwise). On success, the deal is locked to your agency until created_at + 90 days. Other agencies registering the same domain receive a DEAL_LOCKED response.

Submit proof (within 14 days)

POST /api/v1/agencies/deals/{id}/proof Content-Type: application/json { "proof_type": "DEMO_SCHEDULED", "proof_document_url": "https://drive.google.com/...", "notes": "Demo on June 12 with CTO + Head of Marketing" }

proof_typeDEMO_SCHEDULED / PROPOSAL_SENT / CONTRACT_SIGNED. Missing the 14-day deadline auto-expires the deal.

Agency dashboard

GET /api/v1/agencies/dashboard

Returns deal_counts (by status) + pipeline.estimated_value / actual_value + win_rate + recent_deals (top 20). The dashboard payload backs the entire Agency tab.

Webhooks

Both Razorpay and Stripe webhooks fire on referee payment success; the referral wallet auto-credits via ReferralService.on_referee_payment_success. No webhook configuration required from the operator side.

Chargebacks fire ReferralService.handle_chargeback which debits the referrer’s referral_credits_balance if the offending commission has been released, or removes the pending entry if still in hold.

Error shapes

All endpoints return {"detail": "<message>"} on 4xx with a stable status string in detail when applicable:

Status stringMeaning
NOT_AGENCYTrying to register a deal without AGENCY tier
DEAL_LOCKEDDomain already registered by another agency
KYC_NOT_APPROVEDPayout requested before KYC approval
BELOW_MIN_THRESHOLDPayout amount below ₹1,000
NET30_GUARDRAILInsufficient eligible commission (>30 days old)
PASSTHROUGH_INVOICETried to redeem credits against channel pass-through invoice