Developers

Partner API

Build your own rate shopping and lead capture on top of rates.now. Two calls: fetch priced quotes for a borrower scenario, then submit the lead for the quote they chose.

Overview

A partner account on rates.now has an API key, an affiliate record for attribution, and a list of the lenders it may price and route leads to. Every call is server-to-server from your backend. Do not call the API from the browser: the key would be exposed, and your domain is not on our CORS allowlist.

  1. Call GET /api/rates with the borrower's scenario. You get one entry per lender with priced quotes.
  2. Show the quotes in your UI. Keep the entry's lenderId and the quote object the borrower selects.
  3. Capture the borrower's contact details on your site.
  4. Call POST /api/leads with the contact details, the lenderId, the selected quote and the scenario.
  5. rates.now stores the lead, credits it to your affiliate, and delivers it to the lender's CRM through BankingBridge.
Base URL. https://rates.now. All responses are JSON.

Authentication

Send your key in the x-api-key header on every request. There is no session, cookie or OAuth flow.

x-api-key: YOUR_KEY

The key is shown once when it is created. Only a hash is stored, so a lost key cannot be recovered. Ask your rates.now contact to deactivate it and issue a new one. A key carries the scope of the account that owns it, so every key you hold prices the same lenders and attributes leads to the same affiliate.

Keep it secret. Store the key in your server's secret store. Never ship it in client-side code, mobile apps or public repositories.

Lender visibility

Your account has a lender allowlist. GET /api/rates returns only those lenders, and POST /api/leads accepts only their lenderIdvalues. Some of them may be brands that do not appear on rates.now itself. A lead for any other lender is refused with 403 lender_not_available.

Lender ids are stable. Cache the id to name mapping from the rates response if you need it elsewhere, but always submit the id you received for the quote the borrower picked.

GET /api/rates

Returns priced quotes for one borrower scenario. Quotes are pre-generated and cached per scenario bucket, so the call is fast and the figures match what the lender quoted for that bucket.

Query parameters

NameTypeDescription
loanTyperequiredstringconventional, va, fha, usda, jumbo or arm.
loanTermrequiredintegerYears: 30, 20, 15 or 10.
loanAmountrequiredintegerLoan amount in whole dollars.
downPaymentintegerDown payment in whole dollars. Sets the loan-to-value bucket. Default 0.
propertyTyperequiredstringsingle_family_home, multi_tenant_home, condominium, townhome or manufactured_home.
propertyUserequiredstringprimary_home, second_home or rental_home.
creditScorerequiredintegerBorrower credit score. It is bucketed to 800, 780, 760, 740, 720, 700, 680, 660, 640, 620 or 500.
statestringTwo-letter state code. One of state or zipCode is required.
zipCodestringFive-digit ZIP. One of state or zipCode is required. The state is derived from it when state is absent.
loanPurposestringpurchase or refinance. Default purchase.
includeVAbooleantrue to include VA products. Send it with loanType=va.
vaFundingFeeTypestringfirst_time, second_time or exempt. Changes the VA funding fee in the payment figures.
includeFHAbooleantrue to include FHA products.
includeUSDAbooleantrue to include USDA products.
pointsnumberTarget discount points. The closest priced quote per product is returned.

Example request

curl "https://rates.now/api/rates?loanType=va&includeVA=true&loanTerm=30&loanAmount=450000&downPayment=0&propertyType=single_family_home&propertyUse=primary_home&creditScore=740&zipCode=78201" \
  -H "x-api-key: YOUR_KEY"

Example response

{
  "rates": [
    {
      "lenderId": 3,
      "brandId": "2033626",
      "lenderName": "Armed Forces Bank",
      "logo": "https://.../logo.png",
      "appLink": "https://...",
      "responseData": [
        {
          "productName": "VA 30 Yr Fixed",
          "rate": 5.875,
          "apr": 6.112,
          "pts": 0,
          "price": 100,
          "loanTerm": 30,
          "loanType": "VA",
          "lockPeriod": 30,
          "principalAndInterest": 2662,
          "monthlyMI": 0,
          "closingCost": 0,
          "quote_id": 58954412,
          "hash": "ee9c558834813caa8fb28d3b31b8be02"
        }
      ]
    }
  ],
  "metadata": {
    "scenarioHash": "8b41e76bca65c8c8",
    "isJumbo": false,
    "derivedState": "TX",
    "requestedLoanTypes": ["va"],
    "pricingRequestId": 2956
  }
}

Reading the response

  • rates has one entry per visible lender that has quotes for the scenario. A lender with no quotes is omitted. An empty array is a valid answer.
  • responseData lists the lender's quotes. rate and apr are percentages. pts is points as a percentage of the loan. principalAndInterest and monthlyMI are monthly dollars.
  • metadata.pricingRequestId identifies this pricing call. Send it back on the lead.
  • metadata.derivedState is set when the state came from the ZIP code. metadata.isJumbo is true when the amount is above the conforming limit.
  • Quotes expire. Fetch fresh rates when the borrower returns rather than reusing a cached response for more than a few minutes.

POST /api/leads

Submits one borrower to one lender. The lead is stored, attributed to your affiliate, and delivered to the lender. Submit one request per lender when a borrower chooses to be shared with several, with the same submissionId and the matching shareCount on each.

Body fields

NameTypeDescription
namerequiredstringBorrower full name.
emailrequiredstringBorrower email.
phonerequiredstringBorrower phone, digits only.
lenderIdrequiredintegerThe lenderId from the rates response the borrower selected. Omit it only to let rates.now pick a lender from your allowlist.
selectedRateRawDataobjectThe rate item the borrower selected, copied verbatim from responseData. Sent to the lender for traceability.
scenarioDatarequiredobjectThe borrower's scenario. See the keys below. It fills the lender's lead details.
pricingRequestIdintegermetadata.pricingRequestId from the rates response. Links the lead to the quote it came from.
sourceUrlstringThe page the borrower submitted from.
shareCountintegerHow many lenders receive this submission. 1 means exclusive. Default 1.
submissionIdstringYour id for one borrower submission, up to 64 characters. Send the same value on every lead that belongs to it.
attributionobjectFlat object of strings, numbers or booleans: campaign ids, cost per lead, placement. Stored on the lead and forwarded to the lender in the lead details.

scenarioData keys

Use the same values the borrower priced with. These fill the lender's lead details, so the loan officer sees the scenario behind the quote.

NameTypeDescription
loanAmountrequiredintegerLoan amount in whole dollars.
downPaymentrequiredintegerDown payment in whole dollars. 0 for a zero-down VA or USDA loan.
staterequiredstringTwo-letter state code.
zipCoderequiredstringFive-digit ZIP.
creditScorerequiredintegerBorrower credit score.
loanTyperequiredstringSame values as the rates call.
loanPurposerequiredstringpurchase or refinance.
propertyUserequiredstringprimary_home, second_home or rental_home.
propertyTypestringSame values as the rates call.
propertyValueintegerPurchase price or current value. Default loanAmount plus downPayment.
militaryEligiblestringyes or no. yes marks the lead as VA eligible.
firstTimeHomebuyerstringyes or no.
va_funding_feestringfirst_time, second_time or exempt.
current_interest_ratenumberRefinance only: the rate on the existing loan.
cashOutintegerRefinance only: cash-out amount.

Example request

curl -X POST https://rates.now/api/leads \
  -H "x-api-key: YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "name": "Jordan Rivera",
    "email": "jordan@example.com",
    "phone": "5125550142",
    "lenderId": 3,
    "selectedRateRawData": { "...the responseData item the borrower picked..." },
    "scenarioData": {
      "loanAmount": 450000, "downPayment": 0, "state": "TX", "zipCode": "78201",
      "creditScore": 740, "loanType": "va", "loanPurpose": "purchase",
      "propertyUse": "primary_home", "militaryEligible": "yes"
    },
    "pricingRequestId": 2956,
    "sourceUrl": "https://partner.example/va-rates",
    "shareCount": 1,
    "submissionId": "sub_8f3a2c",
    "attribution": { "campaign_id": "va-q4", "cost_per_lead": 7, "placement": "rates-widget" }
  }'

Response 201

{
  "message": "Lead created successfully",
  "lead": {
    "id": 4821,
    "lenderId": 3,
    "affiliateId": 12,
    "pricingRequestId": 2956,
    "shareCount": 1,
    "status": "new",
    "attribution": { "campaign_id": "va-q4", "cost_per_lead": 7, "placement": "rates-widget" },
    "bbLeadResponse": { "lead_id": 991203 }
  }
}

lead.id is the rates.now lead id. bbLeadResponse.lead_id is the lender-side id once the lead is delivered. Keep both for support questions.

Refused lead

{
  "message": "This lender is not available to the caller.",
  "code": "lender_not_available"
}
Attribution. Anything you put in attribution is stored on the lead exactly as sent and forwarded to the lender inside the lead details. Use it for campaign ids, cost per lead, placements or your own lead id. Keys named utm_source, utm_medium, utm_campaign, utm_term and utm_content also populate the lead's UTM fields in reporting.

Errors

Every error is JSON with a message. Some carry a stable code.

StatusCodeWhen
400—A required parameter or field is missing or malformed. The body carries a message, and for leads a per-field errors object.
401—No x-api-key header, or the key is unknown or inactive.
403lender_not_availableThe lenderId on a lead is outside your account's lender allowlist.
422lender_state_not_coveredThe lender does not take leads in the borrower's state.
500—Something failed on our side. Retry with the same submissionId.

Go-live checklist

  1. Confirm the lenders in your allowlist with your rates.now contact.
  2. Price a scenario for each loan type you plan to show and check the quotes render in your UI.
  3. Submit a test lead and confirm the 201 response carries your attribution keys.
  4. Ask your rates.now contact to confirm the test lead arrived in the lender's CRM, then delete it.
  5. Store the key in your secret store and remove it from any test scripts.

Questions, new lenders or a replacement key: contact the rates.now team that set up your account.

varates.now and rates.now are not mortgage lenders or brokers. We are a loan education and comparison network that helps Veterans and military families understand their VA home loan benefits and compare offers from multiple VA-approved lenders side by side. We do not originate loans, make credit decisions, or issue approvals. All rates, fees, terms, and loan decisions are provided solely by participating lenders.

varates.now and rates.now are not affiliated with the U.S. Department of Veterans Affairs (VA), the Department of Defense (DoD), or any government agency. Information on these sites is provided for educational purposes only and should not be considered legal, financial, or tax advice. Official VA resources are available at va.gov.

How we make money

rates.now is an independent, advertising-supported publisher and comparison service. We are compensated in exchange for placement of sponsored products and services, or by you clicking on certain links posted on our site. Therefore, this compensation may impact how, where and in what order products appear within listing categories, except where prohibited by law for our mortgage, home equity and other home lending products. Other factors, such as our own proprietary website rules and whether a product is offered in your area or at your self-selected credit score range, can also impact how and where products appear on this site. While we strive to provide a wide range of offers, rates.now does not include information about every financial or credit product or service.

Made with by BankingBridge
Copyright © BankingBridge 2026