NachoCrunch Developer Portal

AI-powered mortgage rate sheet ingestion & pricing engine — API v0.2.0

Overview

NachoCrunch is an AI-native mortgage pricing platform. The API is organized into three families:

Authentication

API Key (header: X-API-Key)

All pricing and ingestion endpoints require an API key. Issue keys via the admin dashboard or the Keys API.

curl https://app.nachocrunch.com/api/v1/pricing/investors \
  -H "X-API-Key: nck_live_XXXXXXXXXXXXXXXX"

Tenant header (optional)

Multi-tenant deployments accept X-Tenant-Id on internal routes. Defaults to the API key's bound tenant.

Rate Limits

ScopeLimitHeaders
Public rate quote (per IP)10 / minute429 on breach
Pricing (per API key)600 / minute, 60k / dayX-RateLimit-Remaining
Bulk pricing (per API key)5k scenarios / request413 when exceeded
Agent chat (per tenant)120 / minuteBurst smoothing

Webhooks

NachoCrunch fires HMAC-signed webhooks for every meaningful state change. Configure endpoints via POST /api/v1/admin/internal/webhooks.

Signature verification

import hmac, hashlib

def verify(raw_body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

Event families

Key Endpoints

POST/api/v1/pricing/best-executionFind best pricing across investors
POST/api/v1/pricing/naturalPlain-English pricing query
GET/api/v1/pricing/investorsList available investors
POST/api/v1/pricing/bulkPrice up to 5k scenarios in one request
POST/api/v1/public/rate-quotesConsumer-facing quote (anonymous)
POST/api/v1/admin/internal/agent/chatConversational pricing agent
POST/api/v1/admin/internal/lock-requests/lockSubmit a lock request
POST/api/v1/admin/internal/mi-rate-cards/quoteMI premium quote
GET/api/v1/admin/internal/searchGlobal search
GET/api/v1/admin/internal/reportsList operator reports
POST/api/v1/admin/internal/delivery/poolsCreate a delivery pool
POST/api/v1/ingest/uploadUpload a rate sheet for ingestion

Code Examples

Best-Execution Pricing

curl -X POST https://app.nachocrunch.com/api/v1/pricing/best-execution \
  -H "X-API-Key: $NACHOCRUNCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "loan_type": "conventional",
    "loan_amount": 500000,
    "rate_pct": 6.5,
    "lock_days": 30,
    "fico_score": 760,
    "ltv_pct": 80,
    "property_type": "single_family",
    "occupancy": "primary",
    "loan_purpose": "purchase",
    "state": "CA"
  }'
import os, httpx

resp = httpx.post(
    "https://app.nachocrunch.com/api/v1/pricing/best-execution",
    headers={"X-API-Key": os.environ["NACHOCRUNCH_API_KEY"]},
    json={
        "loan_type": "conventional",
        "loan_amount": 500000,
        "rate_pct": 6.5,
        "lock_days": 30,
        "fico_score": 760,
        "ltv_pct": 80,
        "property_type": "single_family",
        "occupancy": "primary",
        "loan_purpose": "purchase",
        "state": "CA",
    },
    timeout=30,
)
resp.raise_for_status()
for r in resp.json()["results"][:5]:
    print(r["investor_name"], r["net_price"])
const res = await fetch(
  "https://app.nachocrunch.com/api/v1/pricing/best-execution",
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.NACHOCRUNCH_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      loan_type: "conventional",
      loan_amount: 500000,
      rate_pct: 6.5,
      lock_days: 30,
      fico_score: 760,
      ltv_pct: 80,
      property_type: "single_family",
      occupancy: "primary",
      loan_purpose: "purchase",
      state: "CA",
    }),
  }
);
const data = await res.json();
console.log(data.results.slice(0, 5));

Agent Chat

curl -X POST https://app.nachocrunch.com/api/v1/admin/internal/agent/chat \
  -H "X-API-Key: $NACHOCRUNCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Best price on a 760/80/$500k conventional purchase in CA?"}'

Public Rate Quote

import httpx

resp = httpx.post(
    "https://app.nachocrunch.com/api/v1/public/rate-quotes",
    json={
        "scenario": {
            "fico": 760, "ltv": 80, "loan_amount": 500000,
            "loan_purpose": "purchase", "property_type": "single_family",
            "occupancy": "primary", "state": "CA",
        },
        "borrower_email": "jane@example.com",
        "lead_source": "website",
    },
)
quote = resp.json()
print("Share link:", f"https://app.nachocrunch.com/q/{quote['quote_token']}")

Versioning

Every response includes the X-API-Version header (currently 0.2.0). Breaking changes ship as new path prefixes (/api/v2/*); minor additions are backward compatible.

Error Envelope

All errors return a consistent JSON shape:

{
  "error": "service_unavailable",
  "detail": "A backend service is currently unavailable."
}