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
| Concern | Method + Path |
|---|---|
| Billing chip summary | GET /api/v1/billing/referral |
| Public landing redirect | GET /refer/{code} |
| Referrer dashboard | GET /api/v1/referrals/dashboard |
| Wallet balance | GET /api/v1/referrals/wallet |
| Pending release schedule | GET /api/v1/referrals/wallet/pending |
| Transaction ledger | GET /api/v1/referrals/transactions |
| Active count + upgrade eligibility | GET /api/v1/referrals/active-count |
| Redeem credits | POST /api/v1/referrals/credits/redeem |
| Affiliate upgrade (initiate) | POST /api/v1/affiliates/upgrade |
| KYC submit | POST /api/v1/affiliates/kyc/submit |
| KYC profile (read) | GET /api/v1/affiliates/kyc/profile |
| Payout request | POST /api/v1/affiliates/payouts/request |
| Payouts list | GET /api/v1/affiliates/payouts |
| Credits → cash | POST /api/v1/affiliates/credits-to-cash |
| TDS certificates list | GET /api/v1/affiliates/tds-certificates |
| Agency deal register | POST /api/v1/agencies/deals/register |
| Agency deal proof | POST /api/v1/agencies/deals/{id}/proof |
| Agency dashboard | GET /api/v1/agencies/dashboard |
Billing chip summary
GET /api/v1/billing/referralSingle-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_status ∈ USER / 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/upgradeCreates 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-certificatesTDS 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_type ∈ DEMO_SCHEDULED / PROPOSAL_SENT / CONTRACT_SIGNED. Missing the 14-day deadline auto-expires the deal.
Agency dashboard
GET /api/v1/agencies/dashboardReturns 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 string | Meaning |
|---|---|
NOT_AGENCY | Trying to register a deal without AGENCY tier |
DEAL_LOCKED | Domain already registered by another agency |
KYC_NOT_APPROVED | Payout requested before KYC approval |
BELOW_MIN_THRESHOLD | Payout amount below ₹1,000 |
NET30_GUARDRAIL | Insufficient eligible commission (>30 days old) |
PASSTHROUGH_INVOICE | Tried to redeem credits against channel pass-through invoice |
Related
- User guide: Refer & Earn