REST API Reference
22 endpoints for credit card intelligence. All responses follow a consistent envelope: { success, data, metadata, error }.
Authentication
All endpoints (except /health) require an API key passed via the X-API-Key header:
X-API-Key: koko_your_api_key
Base URL
https://kokofinance.net/api/v1
Fast vs Verbose Endpoints
Four endpoints offer both a fast (default) and verbose variant:
| Endpoint | Fast (default) | Verbose |
|---|---|---|
/portfolio/analyze |
Deterministic calculations, <100ms | /portfolio/analyze/verbose — adds AI narrative (3-5s) |
/cards/compare |
Side-by-side data, <100ms | /cards/compare/verbose — adds AI winner & pros/cons (3-5s) |
/cards/recommend |
Deterministic ranking, <100ms | /cards/recommend/verbose — adds AI headline & explanation (2-4s) |
/card/renewal-check |
Deterministic verdict, <100ms | /card/renewal-check/verbose — adds retention tips & timing guidance (3-5s) |
The metadata.mode field in every response tells you which variant was used: "fast" or "verbose".
Response Metadata Fields
Calculation endpoints (/portfolio/analyze, /cards/compare, /card/renewal-check, /cards/value) include these fields in their responses:
| Field | Type | Description |
|---|---|---|
spending_source | string | "user_provided" or "national_averages" — indicates whether calculations used your spending data or BLS national averages |
points_program_key | string | Program key (e.g. "chase_ur", "amex_mr") linking the card to its points program |
portal_cpp | number | Portal cents-per-point redemption value (e.g. 1.25 for Chase UR via travel portal) |
rewards_by_category | object | Per-category reward breakdown showing how value was calculated |
Portfolio Analysis
POST /portfolio/analyze
Analyze 1-10 credit cards for total value, per-card verdicts (KEEP/OPTIMIZE/CANCEL), and break-even analysis. Fast deterministic endpoint (<100ms). Use /portfolio/analyze/verbose for AI-generated narrative.
| Field | Type | Required | Description |
|---|---|---|---|
cards | array | Yes | 1-10 cards, each with card_name and optional annual_fee |
params.spending | object | No | Monthly spending by category (dining, travel, groceries, gas, streaming, shopping, other) |
params.primary_goal | string | No | travel, cashback, build_credit, business, or balance_transfer |
params.credit_tier | string | No | poor, fair, good, or excellent |
params.issuer_preferences | array | No | Boost/de-boost issuers, e.g. [{"issuer": "Chase", "weight": 1.5}] |
params.point_balances | array | No | Your rewards balances, e.g. [{"program": "chase_ur", "balance": 150000}]. Enriches analysis with redemption context. |
params.benefit_selections | array | No | Individual benefit keys the user actually uses (e.g. ["uber", "dining", "admirals_club"]). Selected benefits count at 100%; unselected at 0%. If omitted, 50% default utilization is assumed. |
{
"cards": [
{"card_name": "Chase Sapphire Preferred", "annual_fee": 95},
{"card_name": "American Express Gold Card", "annual_fee": 250}
],
"params": {
"spending": {
"dining": 500, "travel": 300,
"groceries": 400, "gas": 100,
"streaming": 30, "shopping": 200,
"other": 150
},
"primary_goal": "travel",
"point_balances": [
{"program": "chase_ur", "balance": 150000},
{"program": "amex_mr", "balance": 80000}
],
"benefit_selections": ["uber", "dining", "travel", "saks"]
}
}
{
"success": true,
"data": {
"card_details": [
{
"card_name": "Chase Sapphire Preferred",
"net_value": 188,
"verdict": "keep",
"points_program_key": "chase_ur",
"portal_cpp": 1.25,
"rewards_by_category": {"dining": 180, "travel": 72, ...},
"break_even": {"status": "spending_required"}
},
...
],
"portfolio_summary": {
"total_annual_fees": 345,
"net_value": 434,
"total_rewards": 444
},
"spending_source": "user_provided",
"assumptions": {"redemption_rate": 1.0, "point_value": 0.01}
},
"metadata": {
"request_id": "a1b2c3d4e5f6",
"api_version": "v1",
"latency_ms": 52,
"mode": "fast",
"timestamp": "2026-03-11T14:30:00Z"
},
"error": null
}
Card Comparison
POST /cards/compare
Compare 2-3 credit cards side-by-side with fees, rewards, net value, and break-even analysis. Fast deterministic endpoint (<100ms). Use /cards/compare/verbose for AI-generated winner and narrative.
| Field | Type | Required | Description |
|---|---|---|---|
card_names | array[string] | Yes | 2-3 card names to compare |
params.spending | object | No | Monthly spending by category |
params.primary_goal | string | No | Optimization goal |
params.credit_tier | string | No | poor, fair, good, or excellent — affects eligibility filtering |
params.benefit_selections | array | No | Benefit keys the user uses (100%/0% model). See /benefit-categories for valid keys. |
{
"card_names": [
"Chase Sapphire Preferred",
"Capital One Venture X"
],
"params": {
"spending": {"dining": 400, "travel": 500, "groceries": 300},
"primary_goal": "travel",
"credit_tier": "excellent",
"benefit_selections": ["travel", "dining"]
}
}
{
"success": true,
"data": {
"comparison_table": [
{
"card_name": "Chase Sapphire Preferred",
"annual_fee": 95,
"net_value": 188,
"total_rewards": 198,
"points_program_key": "chase_ur",
"portal_cpp": 1.25,
"rewards_by_category": {"dining": 180, "travel": 120, ...},
"break_even": {"status": "spending_required"}
},
...
],
"spending_source": "user_provided",
"assumptions": {"redemption_rate": 1.0, "point_value": 0.01}
},
"metadata": {...},
"error": null
}
Recommendations
POST /cards/recommend
Get the best card recommendations for a spending category. From the full market, or from your existing portfolio. Fast deterministic endpoint (<100ms). Use /cards/recommend/verbose for AI-generated narrative (portfolio mode only).
| Field | Type | Required | Description |
|---|---|---|---|
category | string | Yes | Spending category: dining, travel, groceries, gas, etc. |
portfolio_card_names | array[string] | No | If provided, recommend from portfolio instead of market |
params.spending | object | No | Monthly spending by category |
params.credit_tier | string | No | Filter by credit tier |
params.primary_goal | string | No | Optimization goal |
{
"category": "dining",
"params": {
"spending": {"dining": 600, "groceries": 400},
"credit_tier": "excellent",
"primary_goal": "cashback"
}
}
{
"success": true,
"data": {
"recommendations": [
{
"card_name": "American Express Gold Card",
"issuer": "American Express",
"annual_fee": 250,
"net_value": 380,
"points_program_key": "amex_mr",
"portal_cpp": 1.1,
"rewards_structure": "4x dining, 4x groceries..."
}
],
"category": "dining",
"spending_source": "user_provided",
"total_candidates": 8
},
"metadata": {...},
"error": null
}
Renewal Check
POST /card/renewal-check
Check if a card is worth keeping at annual fee renewal time. Returns RENEW, DOWNGRADE, or CANCEL_AND_REPLACE. Fast deterministic endpoint (<100ms).
| Field | Type | Required | Description |
|---|---|---|---|
card_name | string | Yes | Name of the card to check |
params.spending | object | No | Monthly spending by category |
params.primary_goal | string | No | Optimization goal |
params.credit_tier | string | No | poor, fair, good, or excellent |
acquired_date | string | No | Date card was acquired (YYYY-MM-DD) for anniversary-aware analysis |
benefit_selections | array | No | Benefit keys the user actually uses (e.g. ["uber", "airline_fee", "dining"]). Selected benefits count at 100%; unselected at 0%. |
{
"card_name": "Chase Sapphire Preferred",
"acquired_date": "2024-06-15",
"params": {
"spending": {
"dining": 400, "travel": 300, "groceries": 500
},
"primary_goal": "travel",
"credit_tier": "excellent"
},
"benefit_selections": ["dining", "travel"]
}
{
"success": true,
"data": {
"verdict": "RENEW",
"year2_net_value": 120.50,
"confidence": "high",
"points_program_key": "chase_ur",
"portal_cpp": 1.25,
"spending_source": "user_provided",
"downgrade_options": [...],
"replacement_options": [...],
"thresholds_used": {
"cancel": -100,
"keep": 50
}
},
"metadata": {...},
"error": null
}
POST /card/renewal-check/verbose
Same analysis as the fast endpoint, plus AI-generated retention tips, timing guidance, and a detailed narrative. Response time 3-5s.
Accepts the same parameters as /card/renewal-check. Additional response fields:
| Response Field | Type | Description |
|---|---|---|
detailed_analysis | string | AI-generated narrative explaining the verdict |
retention_tips | array | Actionable tips for negotiating with the issuer |
timing_guidance | string | When to call and what to say |
Card Details
GET /cards/details
Look up comprehensive details for a specific credit card by name. Supports fuzzy matching (e.g. "Sapphire Preferred" matches "Chase Sapphire Preferred Card").
| Field | Type | Required | Description |
|---|---|---|---|
card_name | string (query) | Yes | Card name (supports fuzzy matching) |
issuer | string (query) | No | Issuer name to narrow results (e.g. "Chase") |
GET /api/v1/cards/details?card_name=Chase+Sapphire+Preferred
{
"success": true,
"data": {
"card_name": "Chase Sapphire Preferred Card",
"issuer": "Chase",
"network": "Visa",
"card_type": "travel",
"annual_fee": 95,
"credit_score_needed": "good",
"rewards_structure": "3x dining, 2x travel, 1x other",
"key_benefits": [...],
"welcome_bonus": "60,000 points",
"sign_on_bonus": 60000,
"sign_on_bonus_type": "points",
"foreign_transaction_fee": "None",
"apply_url": "https://...",
"best_for": "Dining and travel rewards",
"points_program_key": "chase_ur",
"portal_cpp": 1.25
},
"metadata": {...}
}
Card Value
POST /cards/value
Calculate the financial value and break-even point of a credit card based on your spending. Returns first-year value (with sign-on bonus), ongoing annual value, and a WORTH_IT / NOT_WORTH_IT verdict.
| Field | Type | Required | Description |
|---|---|---|---|
card_name | string | No | Card name for DB lookup (uses actual rewards/benefits if found) |
annual_fee | number | No | Annual fee ($). If card_name is provided, pulled from DB. |
spending | object | No | Monthly spending by category, e.g. {"dining": 500, "travel": 300} |
benefit_selections | array | No | Benefit keys the user uses (100%/0% model) |
rewards_structure | object | No | Custom rewards structure (overrides DB if provided) |
{
"card_name": "Chase Sapphire Preferred",
"spending": {
"dining": 500, "travel": 300,
"groceries": 400
},
"benefit_selections": ["dining", "travel"]
}
{
"success": true,
"data": {
"first_year": {
"total_value": 1250,
"net_value": 1155,
"sign_on_bonus_value": 750,
"benefits_utilized": 0,
"total_rewards": 500
},
"ongoing_annual": {
"total_value": 500,
"net_value": 405
},
"break_even": {
"monthly_spend_needed": 350
},
"rewards_by_category": {
"dining": 180, "travel": 72, "groceries": 48
},
"verdict": "WORTH_IT",
"spending_source": "user_provided",
"points_program_key": "chase_ur",
"portal_cpp": 1.25,
"assumptions": {...}
},
"metadata": {...}
}
Card Discovery
Search the full card database with structured filters. Deterministic ranking based on spending alignment, fee value, and sign-on bonus. Fast (<100ms).
POST /cards/search
Search for credit cards using structured filters. Returns ranked results scored by spending alignment, fee value, purpose match, and sign-on bonus. All filters are optional — omit any to broaden the search.
| Field | Type | Required | Description |
|---|---|---|---|
card_type | string | No | Card type: travel, cashback, balance_transfer, business, student, hotel, airline |
max_annual_fee | integer | No | Maximum annual fee in dollars (e.g. 200). Omit for no limit. |
issuer | string | No | Filter by issuer (e.g. "Chase", "American Express") |
spending | object | No | Monthly spending by category for ranking (e.g. {"dining": 500, "travel": 300}) |
credit_tier | string | No | poor, fair, good, or excellent |
max_results | integer | No | 1-20 results (default 5) |
{
"card_type": "travel",
"max_annual_fee": 300,
"spending": {
"dining": 500, "travel": 400,
"groceries": 300
},
"credit_tier": "excellent",
"max_results": 5
}
{
"success": true,
"data": {
"recommendations": [
{
"card_name": "Chase Sapphire Preferred",
"card_id": 42,
"issuer": "Chase",
"annual_fee": 95,
"card_type": "travel",
"match_score": 0.87,
"reasoning": "Strong dining/travel multipliers...",
"rewards_structure": "3x dining, 2x travel...",
"sign_on_bonus": 60000,
"apply_url": "https://..."
},
...
],
"total_found": 12,
"filters_applied": {
"card_type": "travel",
"max_annual_fee": 300,
"spending_categories": ["dining", "travel", "groceries"]
}
},
"metadata": {...}
}
Merchant Intelligence
Merchant-level endpoints resolve a merchant name to a spending category, match card credits, and rank your portfolio by reward value. Deterministic for 350+ known merchants; uses Gemini AI fallback for unknown merchants.
POST /which-card-at-merchant
Find the best card from your portfolio for a purchase at a specific merchant. Auto-detects the spending category (e.g. Starbucks → dining) and ranks your cards by reward value.
| Field | Type | Required | Description |
|---|---|---|---|
merchant | string | Yes | Merchant name (e.g. "Starbucks", "Saks Fifth Avenue", "Delta Air Lines") |
amount | number | No | Purchase amount in dollars (default 100) |
portfolio | array[string] | Yes | Card names in your portfolio |
{
"merchant": "Starbucks",
"amount": 35,
"portfolio": [
"Chase Sapphire Reserve",
"Amex Gold",
"Citi Double Cash"
]
}
{
"success": true,
"data": {
"recommended_card": "American Express Gold Card",
"category_detected": "dining",
"category_method": "exact",
"reason": "Starbucks codes as dining — Amex Gold 4x vs CSR 3x vs Citi DC 2%",
"earnings_comparison": [
{
"card": "American Express Gold Card",
"multiplier": "4x",
"points_earned": 140,
"program": "Membership Rewards",
"estimated_value": "$2.10"
},
...
]
},
"metadata": {...}
}
POST /merchant-benefits
Check if any cards in your portfolio have credits or benefits at a specific merchant. Also includes an earning recommendation (which card earns the most here).
| Field | Type | Required | Description |
|---|---|---|---|
merchant | string | Yes | Merchant name (e.g. "Saks Fifth Avenue", "Uber", "Disney+") |
portfolio | array[string] | Yes | Card names in your portfolio |
{
"merchant": "Saks Fifth Avenue",
"portfolio": [
"Amex Platinum",
"Chase Sapphire Reserve"
]
}
{
"success": true,
"data": {
"matching_benefits": [
{
"card": "The Platinum Card from American Express",
"benefit_key": "saks",
"name": "Saks Fifth Avenue Credit",
"value": 100,
"frequency": "semi-annual",
"schedule": "$50 Jan-Jun, $50 Jul-Dec",
"note": "Your Amex Platinum has a $100 Saks credit."
}
],
"earning_recommendation": {
"best_card": "The Platinum Card from American Express",
"multiplier": "1x",
"note": "Use Amex Platinum to combine with the credit."
}
},
"metadata": {...}
}
GET /card-benefits
Get all credits, benefits, and rewards multipliers for a specific card. Returns structured data with value, frequency, schedule, and conditions for each credit.
| Field | Type | Required | Description |
|---|---|---|---|
card | string (query param) | Yes | Card name (e.g. "Amex Platinum", "Chase Sapphire Reserve") |
GET /api/v1/card-benefits?card=Amex%20Platinum
{
"success": true,
"data": {
"card": "The Platinum Card from American Express",
"issuer": "American Express",
"annual_fee": 695,
"credits": [
{
"benefit_key": "uber",
"name": "Uber Cash",
"value": 200,
"frequency": "monthly",
"schedule": "$15/mo + $20 Dec"
},
...
],
"total_credit_value": 1584,
"rewards_multipliers": {
"airlines": 5, "hotels": 5, "base": 1
},
"points_program": "amex_mr",
"portal_cpp": 1.1
},
"metadata": {...}
}
GET /benefit-categories
Returns the benefit key registry — all valid keys for benefit_selections, grouped by category. No authentication required. Use this to discover which keys to pass in portfolio and renewal requests.
{
"categories": [
{
"category": "dining_credit",
"label": "Dining Credits",
"keys": ["dining", "resy_dining"]
},
{
"category": "lounge_access",
"label": "Lounge Access",
"keys": ["admirals_club", "united_club_membership"]
},
...
],
"all_keys": ["admirals_club", "airline_fee", "avis_budget", ...],
"usage": {
"benefit_selections": "Pass keys to portfolio/analyze or card/renewal-check...",
"benefit_categories_used": "Alternative: pass category names instead..."
}
}
Card Terms & Risk Data
Schumer Box data: APR, penalties, and fee terms extracted from issuer disclosures. Updated monthly. Covers 148 cards.
GET /cards/{card_id}/terms
Get APR, penalty, and fee terms for a credit card by ID.
| Field | Type | Required | Description |
|---|---|---|---|
card_id | integer (path) | Yes | Card ID (from portfolio or search results) |
GET /api/v1/cards/42/terms
{
"success": true,
"data": {
"card_id": 42,
"card_name": "Chase Sapphire Preferred",
"issuer": "Chase",
"purchase_apr": "21.49%-28.49%",
"cash_advance_apr": "29.49%",
"penalty_apr": "29.99%",
"balance_transfer_apr": "21.49%-28.49%",
"late_fee": "Up to $40",
"returned_payment_fee": "Up to $40",
"cash_advance_fee": "$10 or 5%",
"promotional_apr": "0%",
"promo_apr_months": "12",
"grace_period_days": "21",
"last_extracted_at": "2026-04-24T...",
"extraction_source": "gemini_grounding"
},
"metadata": {...}
}
GET /cards/terms
Same data as the ID-based endpoint, but resolves the card by name (fuzzy matching).
| Field | Type | Required | Description |
|---|---|---|---|
card_name | string (query) | Yes | Card name (supports fuzzy matching) |
issuer | string (query) | No | Issuer name to narrow results |
GET /api/v1/cards/terms?card_name=Chase+Sapphire+Preferred
Same response format as /cards/{card_id}/terms
Data History & Audit
Append-only change log for card data and points program valuations. Automatically populated by batch jobs — track fee increases, benefit changes, and CPP movements over time.
GET /cards/{card_id}/history
Get change history for a specific card by ID. Returns chronological diffs for any tracked field.
| Field | Type | Required | Description |
|---|---|---|---|
card_id | integer (path) | Yes | Card ID |
field | string (query) | No | Filter by field name (e.g. annual_fee, purchase_apr) |
since | string (query) | No | ISO date string (e.g. 2026-01-01) |
GET /api/v1/cards/42/history?field=annual_fee&since=2026-01-01
{
"card_id": 42,
"count": 1,
"changes": [
{
"table": "popular_cards",
"field": "annual_fee",
"old_value": "95",
"new_value": "150",
"detected_at": "2026-03-15T...",
"source": "weekly_batch_job"
}
]
}
GET /cards/history
Same data as the ID-based endpoint, but resolves the card by name (fuzzy matching).
| Field | Type | Required | Description |
|---|---|---|---|
card_name | string (query) | Yes | Card name (supports fuzzy matching) |
field | string (query) | No | Filter by field name |
since | string (query) | No | ISO date string |
GET /api/v1/cards/history?card_name=Chase+Sapphire+Preferred&since=2026-01-01
Same response format as /cards/{card_id}/history
GET /cards/changes
Get all card data changes across all cards since a given date. Useful for monitoring the card landscape for fee increases, benefit removals, or rewards structure changes.
| Field | Type | Required | Description |
|---|---|---|---|
since | string (query) | Yes | ISO date string (e.g. 2026-01-01) |
fields | string (query) | No | Comma-separated field names to filter (e.g. annual_fee,purchase_apr) |
GET /api/v1/cards/changes?since=2026-04-01&fields=annual_fee,penalty_apr
{
"since": "2026-04-01",
"count": 3,
"changes": [
{
"card_id": 42,
"table": "popular_cards",
"field": "annual_fee",
"old_value": "95",
"new_value": "150",
"detected_at": "2026-04-15T...",
"source": "weekly_batch_job"
},
...
]
}
GET /programs/{program_key}/history
Get CPP and transfer partner ratio change history for a points program. Track valuation trends over time.
| Field | Type | Required | Description |
|---|---|---|---|
program_key | string (path) | Yes | Program key (e.g. chase_ur, amex_mr) |
since | string (query) | No | ISO date string |
GET /api/v1/programs/chase_ur/history?since=2026-01-01
{
"program_key": "chase_ur",
"count": 2,
"changes": [
{
"field": "portal_cpp",
"old_value": "1.25",
"new_value": "1.50",
"detected_at": "2026-02-01T...",
"source": "transfer_partner_refresh"
},
...
]
}
Points & Redemption
Points program reference data and redemption strategy generation. Look up transfer partners, check program details, and generate AI-powered redemption playbooks.
GET /points/programs
List all verified, active points programs with portal CPP, transfer partners, and currency names.
GET /api/v1/points/programs
{
"success": true,
"data": {
"count": 11,
"programs": [
{
"program_key": "chase_ur",
"program_name": "Chase Ultimate Rewards",
"currency_name": "Ultimate Rewards points",
"portal_cpp": 1.25,
"points_expire": false,
"transfer_partners": [...]
},
...
]
}
}
GET /points/programs/{program_key}
Get a single program's details including transfer partners, portal CPP, and currency info.
| Field | Type | Required | Description |
|---|---|---|---|
program_key | string (path) | Yes | Program key (e.g. chase_ur, amex_mr, cap1_miles) |
GET /api/v1/points/programs/amex_mr
{
"success": true,
"data": {
"program_key": "amex_mr",
"program_name": "Amex Membership Rewards",
"currency_name": "Membership Rewards points",
"portal_cpp": 1.1,
"points_expire": false,
"transfer_partners": {
"airlines": ["Delta", "ANA", "Singapore Airlines", ...],
"hotels": ["Hilton", "Marriott", ...]
}
}
}
POST /portfolio/points-playbook
Generate a points redemption playbook for your cards and balances. Returns cashback earning estimates, points-at-risk warnings, and AI-generated per-program redemption strategies with transfer partner suggestions.
| Field | Type | Required | Description |
|---|---|---|---|
cards | array[string] | Yes | 1-10 card names to analyze |
point_balances | array | No | Point/miles balances: [{"program_key": "chase_ur", "balance": 70000}] |
spending | object | No | Monthly spending by category for cashback calculation |
{
"cards": [
"Chase Sapphire Reserve",
"American Express Gold Card"
],
"point_balances": [
{"program_key": "chase_ur", "balance": 70000},
{"program_key": "amex_mr", "balance": 50000}
],
"spending": {
"dining": 500, "travel": 300,
"groceries": 400
}
}
{
"success": true,
"data": {
"cashback_earning": {
"total_annual_cashback": 156.00,
"cards": ["Citi Double Cash"],
"summary": "You earn ~$156/year in cashback"
},
"points_at_risk": [
{
"program": "chase_ur",
"warning": "Cancel CSR and you lose 70K points"
}
],
"points_playbook": [
{
"program": "Chase Ultimate Rewards",
"balance": 70000,
"strategy": "Transfer to Hyatt for 2 nights...",
"best_transfer": "World of Hyatt (1:1)"
}
]
},
"metadata": {...}
}
System
GET /usage
Get your current API usage for the billing period. Returns per-endpoint breakdown, by-channel split (REST vs MCP), and rate limit info.
GET /api/v1/usage
{
"success": true,
"data": {
"period": "2026-05",
"tier": "free",
"calls_used": 127,
"calls_limit": 2000,
"calls_remaining": 1873,
"by_endpoint": {
"/api/v1/portfolio/analyze": 45,
"/api/v1/cards/compare": 32,
...
},
"by_channel": {
"rest": 95,
"mcp": 32
},
"rate_limit": {
"requests_per_minute": 60,
"monthly_limit": 2000
}
}
}