# Honda Incentives & APR API (`johnmcdoanld/honda-incentives-apr-api`) Actor

U.S. Honda incentive data as JSON: ZIP-based new-car APR, lease and cash offers, plus supported HondaTrue CPO programs. Includes source timestamps, disclosures, model matching and explicit coverage status.

- **URL**: https://apify.com/johnmcdoanld/honda-incentives-apr-api.md
- **Developed by:** [John McDonald](https://apify.com/johnmcdoanld) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Honda Incentives & APR API

Structured U.S. Honda new-vehicle incentives by ZIP, plus supported HondaTrue CPO programs from official Honda/HondaTrue sources. HondaTrue sources are not ZIP-filtered; the requested ZIP does not establish nationwide eligibility. Get APR tiers, new-vehicle leases, cash and conditional assistance as JSON, with source URLs, retrieval timestamps and full disclosures.

Use it to give shopping agents and applications consistent incentive data without maintaining separate Honda page/API integrations. Exact model filtering, explicit ambiguity and source-coverage status make the results usable through an API or the Apify console.

### What it returns

- New-vehicle APR, lease and officially available cash/loyalty/conquest/conditional programs.
- HondaTrue Certified APR, HondaTrue Used APR, and supported HondaTrue Certified military/graduate assistance.
- One normalized row per APR/term tier, preserving the different qualifying rates and terms.
- Official vehicle/program identifiers, legal text, expiration, ZIP/geography and source provenance.
- A separate STATUS record explaining matching, ambiguity and source completeness.

Coverage is limited to supported official sources; dealer-specific offers and HondaTrue Certified leasing are not included. This is an independent data tool, not affiliated with or endorsed by Honda. Review Honda and participating dealer terms before a transaction.

### Quick start

In the Apify console, enter a U.S. ZIP and run the Actor. Optional condition, model year and model fields narrow the results. For a specific new vehicle:

```json
{
  "zip": "60601",
  "vehicleCondition": "new",
  "modelYear": 2026,
  "model": "Accord Sedan"
}
```

After completion, open **Incentive rows** for the dataset and **Run status and source coverage** for STATUS. Read both: a successful Apify run can still require model clarification or contain explicitly incomplete source coverage. API callers should use the complete examples below; dataset-only integrations omit STATUS.

### Read rows and STATUS in Python or JavaScript

Public Actor: [`johnmcdoanld/honda-incentives-apr-api`](https://apify.com/johnmcdoanld/honda-incentives-apr-api), ID `4W5DZzdoNiFjbpoZm`.

First run the Actor in the console or use [Start a run](#api-usage) below, then save the returned run ID. Set `APIFY_TOKEN` securely in your environment and `APIFY_RUN_ID` to that completed run's ID. These examples only read that existing run, so troubleshooting does not start another billable run. No client packages are required.

Both examples read STATUS, reject failed/interrupted runs, partial coverage and ambiguous models, paginate all rows, and check the published row count. A missing STATUS or failed request raises an error. To accept partial coverage intentionally, add handling that shows `failedSourceFeeds` to your users; do not simply remove the guard. For `ambiguous_model`, choose a returned candidate before starting a new run.

**Python 3** — save as `read_run.py`, then run `python3 read_run.py`:

```python
"""Python 3. Reads an existing run; never starts a billable Actor run."""
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen

token = os.environ["APIFY_TOKEN"]
run_id = os.environ["APIFY_RUN_ID"]


def get_json(path):
    request = Request(
        f"https://api.apify.com/v2/{path}",
        headers={"Authorization": f"Bearer {token}"},
    )
    with urlopen(request, timeout=70) as response:
        return json.load(response)


run = get_json(f"actor-runs/{quote(run_id, safe='')}")["data"]
## Missing STATUS is an error, never evidence of zero offers.
status = get_json(f"key-value-stores/{run['defaultKeyValueStoreId']}/records/STATUS")
if run["status"] != "SUCCEEDED" or status["status"] not in ("success", "no_offers"):
    raise RuntimeError(json.dumps({"runId": run_id, "platformStatus": run["status"], "status": status}))

offers = []
offset = 0
while True:
    page = get_json(f"datasets/{run['defaultDatasetId']}/items?format=json&limit=1000&offset={offset}")
    offers.extend(page)
    if len(page) < 1000:
        break
    offset += 1000
if len(offers) != status["outputRowCount"]:
    raise RuntimeError("Dataset/STATUS row count mismatch; results are incomplete")
print(json.dumps({"runId": run_id, "status": status, "offers": offers}, indent=2))
```

**Node.js 22+** — save as `read-run.mjs`, then run `node read-run.mjs`:

```javascript
// Node.js 22+. Reads an existing run; never starts a billable Actor run.
const token = process.env.APIFY_TOKEN;
const runId = process.env.APIFY_RUN_ID;
if (!token || !runId) throw new Error('Set APIFY_TOKEN and APIFY_RUN_ID');

async function getJson(path) {
    const response = await fetch(`https://api.apify.com/v2/${path}`, {
        headers: { Authorization: `Bearer ${token}` },
        signal: AbortSignal.timeout(70_000),
    });
    if (!response.ok) throw new Error(`Apify HTTP ${response.status}; results unavailable`);
    return response.json();
}

const run = (await getJson(`actor-runs/${encodeURIComponent(runId)}`)).data;
// Missing STATUS is an error, never evidence of zero offers.
const status = await getJson(`key-value-stores/${run.defaultKeyValueStoreId}/records/STATUS`);
if (run.status !== 'SUCCEEDED' || !['success', 'no_offers'].includes(status.status)) {
    throw new Error(JSON.stringify({ runId, platformStatus: run.status, status }));
}

const offers = [];
for (let offset = 0; ; offset += 1000) {
    const page = await getJson(`datasets/${run.defaultDatasetId}/items?format=json&limit=1000&offset=${offset}`);
    offers.push(...page);
    if (page.length < 1000) break;
}
if (offers.length !== status.outputRowCount) {
    throw new Error('Dataset/STATUS row count mismatch; results are incomplete');
}
console.log(JSON.stringify({ runId, status, offers }, null, 2));
```

### Freshness and billing units

The Actor retrieves supported official sources on each run; it does not serve cached offers. `retrievedAt` records when the source response was received, not when Honda last updated its programs. Date-only start/end bounds are evaluated inclusively using the retrieval date in UTC. Missing dates stay unknown and are flagged in `normalizationWarnings`. Read every source's timestamp in `STATUS.sources[].documents`; the summary timestamp is not a freshness guarantee for all sources. Saved datasets remain historical snapshots and do not update themselves.

Current public pricing is **$1 per 1,000 dataset rows plus $0.00005 per start at the default 1 GB, costs included**. The start event scales with memory (one event per GB, minimum one). One APR program can expand into several result rows, so rows are not unique programs or vehicles. At the default memory, a completed 160-row run corresponds to $0.16005 in listed event charges; a run with no rows can still incur the start event. This explains the existing pricing and does not change it.

### Inputs

| Field | Required | Meaning |
| --- | --- | --- |
| `zip` | Yes | Five-digit U.S. ZIP **string**, including leading zeros such as `02108`. Checked against a bundled ZIP directory. Numbers, ZIP+4 and unknown ZIPs are rejected. |
| `vehicleCondition` | No | `new` selects new vehicles; `cpo` selects supported HondaTrue incentives. Omit to query both source families. |
| `modelYear` | No | Exact model year as an integer. Omit to include all supported applicable years. |
| `model` | No | Official Honda model label or unambiguous source-backed representation. Safe case/spacing/punctuation differences and a leading Honda name are normalized. Ambiguous names return candidates without guessing. Leave blank by omitting the field. |
| `allowPartialResults` | No | Boolean, default **false**. Allows incomplete combined new+CPO responses if a family fails. New-only and CPO-only requests remain strict even when set to true. |

Model stays a string for agents/API callers, rather than a fixed list that can become outdated. Empty strings, null optional inputs, unknown fields and unsupported manufacturer selectors are rejected. Unknown but well-formed models can return `no_offers`.

### Output

The dataset contains only normalized incentive rows. Unknown or unavailable nullable values remain `null`; they are not replaced with estimates. STATUS is stored separately in the run’s default key-value store.

| Field | Meaning |
| --- | --- |
| `manufacturer` | Always `Honda`. |
| `vehicleCondition` | `new` or `cpo`, classified from authoritative source evidence. |
| `certificationTier` | `HondaTrue Certified` or `HondaTrue Used` for supported CPO rows; null for new vehicles. |
| `sourceFeed` | `honda_new` or `hondatrue_cpo`, identifying the source family. |
| `sourceIdentifiers` | Original program/model IDs or page-section identifiers. Individual unavailable values may be null. |
| `sourceRegion` | Raw source region code/type when supplied; otherwise null. No Region A/B mapping is inferred. |
| `modelYear` | Source model year; null when unavailable or universal. |
| `model` | Source model identity; null when unavailable or universal. |
| `trim` | Source trim; null when unavailable or universal. |
| `programType` | `apr`, `lease`, `cash` or `other`. Unmapped program semantics remain `other`. |
| `apr` | Structured APR percentage, e.g. `3.99`, not a decimal fraction; null when unavailable/not applicable. |
| `termMonths` | Exact term in months; null when the source supplies a range or no exact term. |
| `termMonthsMin` | Source minimum term bound, or null if unavailable. |
| `termMonthsMax` | Source maximum term bound, or null if unavailable. |
| `cashAmount` | Monetary program benefit in USD, or null. Conditional sales credit/cap-cost/down-payment assistance is not unrestricted customer cash; read eligibility. |
| `monthlyPayment` | Structured lease monthly payment in USD, or null. |
| `dueAtSigning` | Structured lease amount due at signing in USD, or null. |
| `eligibility` | Complete unique source disclosures, including qualification and stacking restrictions; null if absent. Not a buyer eligibility decision. |
| `expirationDate` | Official date-only end date (`YYYY-MM-DD`), or null if absent. |
| `zip` | Requested, validated ZIP. It does not prove buyer residency. |
| `geography` | Exact recognized restriction text, nullable `allowedStates`/`excludedStates`, and `appliesToRequestedZip: true/false/null`; null when no recognized clause is available. |
| `rawProgramName` | Original Honda program name. |
| `sourceUrl` | Official source URL for this row. |
| `sourceType` | `official_oem`, describing data origin, not an endorsement. |
| `retrievedAt` | UTC ISO timestamp of this row’s source retrieval. |
| `sourceOfferId` | Original offer ID, or a namespaced page identifier when no backend ID exists. |
| `financeTier` | Zero-based APR tier index, or null for non-tier rows. |
| `isUniversal` | Whether official source evidence identifies a universal program. Does not establish applicability to every filtered vehicle. |
| `normalizationWarnings` | Array describing missing values or source limitations; empty when none were recorded. |

One Honda finance program may produce several rows. Keep `apr` together with `termMonthsMin`/`termMonthsMax`; do not silently choose the lowest rate. `sourceFeed`, `sourceOfferId` and `financeTier` distinguish program tiers within a run. Unknown geography stays unknown; offers explicitly excluded by the ZIP’s state are omitted and audited in STATUS.

### Example requests

**Exact new vehicle**

```json
{"zip":"60601","vehicleCondition":"new","modelYear":2026,"model":"Accord Sedan"}
```

**Safe formatting normalization**

```json
{"zip":"60601","vehicleCondition":"new","modelYear":2026,"model":"CRV"}
```

`CR-V`, `CRV`, `Cr V` and `Honda CRV` can resolve to the same authoritative identity. This does not merge `CR-V` with `CR-V Hybrid`.

**Supported HondaTrue CPO**

```json
{"zip":"60601","vehicleCondition":"cpo"}
```

**Combined new + CPO, strict by default**

```json
{"zip":"60601"}
```

**Combined, with partial-source opt-in**

```json
{"zip":"60601","allowPartialResults":true}
```

**Ambiguous model**

```json
{"zip":"60601","vehicleCondition":"new","modelYear":2026,"model":"Accord"}
```

The Actor does not guess between Accord Sedan and Accord Hybrid. Candidates depend on the selected sources and model year.

### Example incentive record

Dated example captured October 6, 2026 (America/Chicago), with its UTC retrieval timestamp. Rates and expiration are historical examples, not a promise of a currently available offer. Full eligibility text is retained.

```json
{
  "manufacturer": "Honda",
  "vehicleCondition": "new",
  "certificationTier": null,
  "sourceFeed": "honda_new",
  "sourceIdentifiers": {
    "id": "a1hUT000001IlG1YAK-CY1F4TJW",
    "modelId": "CY1F4TJW",
    "eShoppingId": "a1hUT000001IlG1YAK",
    "ahmSalesProgramId": "HP-68X"
  },
  "sourceRegion": null,
  "modelYear": 2026,
  "model": "Accord Sedan",
  "trim": "SE",
  "programType": "apr",
  "apr": 3.99,
  "termMonths": null,
  "termMonthsMin": 24,
  "termMonthsMax": 60,
  "cashAmount": null,
  "monthlyPayment": null,
  "dueAtSigning": null,
  "eligibility": "For well-qualified buyers. Example: 10% down payment. 60 months financing at $18.41/month per $1,000 financed.\n\nAvailable on approved credit through Honda Financial Services, 3.99% APR for up to 60 months on select new and unregistered 2026 Honda Accord Sedan models through 11/2/2026, for well-qualified buyers. Excludes Hybrid models. Not all buyers will qualify. Higher financing rates apply for buyers with lower credit ratings. Actual down payment may vary. Dealer participation may affect actual payment. Dealer sets actual prices. See participating dealers for details.",
  "expirationDate": "2026-11-02",
  "zip": "60601",
  "geography": null,
  "rawProgramName": "2026 Accord Sedan Special APR",
  "sourceUrl": "https://automobiles.honda.com/platform/api/v1/specials?zipCode=60601",
  "sourceType": "official_oem",
  "retrievedAt": "2026-10-07T01:37:27.075Z",
  "sourceOfferId": "a1hUT000001IlG1YAK-CY1F4TJW",
  "financeTier": 0,
  "isUniversal": false,
  "normalizationWarnings": []
}
```

### Run status and reliability

Dataset rows answer “which incentives matched?”; STATUS answers “what happened, and which requested sources were available?” Apify’s platform run status is distinct from the Actor’s STATUS record.

| `STATUS.status` | Meaning |
| --- | --- |
| `success` | Selected source coverage succeeded and matching normalized rows were returned. |
| `no_offers` | Selected sources were evaluated successfully, but no matching normalized incentive rows were found. |
| `ambiguous_model` | The supplied model maps to multiple authoritative candidates. No rows are published; the Actor refuses to guess. |
| `partial_success` | Opt-in combined request: a selected family failed and another family validated. Returned coverage is incomplete. Rows can be empty if surviving matches are absent or ambiguous. |

These four statuses complete successfully at the Apify platform level. Invalid input, source/retrieval failures, parsing/normalization failures or runtime/storage failures can fail the run. Under the default strict policy, a selected-family failure prevents dataset publication. A failed run is not evidence of zero offers.

Programmatic consumers should inspect:

- `selectedSourceFeeds`, `successfulSourceFeeds`, `failedSourceFeeds` for requested/available/missing coverage.
- `resultStatus` for matching within successful coverage: `success`, `no_offers` or `ambiguous_model`.
- `modelResolution`, when a model was supplied, for candidates, outcome and source/year provenance.
- `outputRowCount` for the number of published rows.

`STATUS.sources` lists attempted families. Successful outcomes include source URLs, retrieval times, endpoint-level `documents` and counts; failed outcomes include safe classified errors and omit unknown offer counts. Raw source-record/program counts differ from expanded APR-row counts. Geography exclusion counts/audit are independent of source failures. Strict runs stop on the first failed family, so later selected families may be unattempted.

### Model resolution

Formatting normalization is separate from choosing a model. Exact official identities take precedence; unique authoritative aliases may resolve. No fuzzy typo correction is applied. Selected vehicle condition and model year narrow candidates first. Distinct gas/Hybrid or body-style identities remain distinct when Honda exposes them separately.

Example ambiguity STATUS excerpt; future catalogs/years may produce different candidates:

```json
{
  "status": "ambiguous_model",
  "resultStatus": "ambiguous_model",
  "modelResolution": {
    "normalizedInput": "accord",
    "candidates": ["Accord Hybrid", "Accord Sedan"],
    "outcome": "ambiguous",
    "partialSourceCoverage": false
  },
  "outputRowCount": 0
}
```

Choose or ask for a candidate and submit a new request. An unknown label is not silently substituted with another Honda model.

### New vs HondaTrue CPO

| Capability | New vehicles | Supported HondaTrue CPO |
| --- | --- | --- |
| APR | Structured rates and term tiers | HondaTrue Certified and HondaTrue Used |
| Lease | Structured new-vehicle lease fields when supplied | Not currently supported, including HondaTrue Certified leasing |
| Cash/conditional programs | Officially available cash, loyalty/conquest and conditional assistance | Supported HondaTrue Certified military/graduate assistance |
| Military and Graduate | Conditional Honda Financial Services benefits where applicable | Separate conditional HondaTrue Certified benefits; HondaTrue Used excluded by current savings terms |
| Model/year filtering | Official model/ID applicability | Source-enumerated applicability only; universal savings without enumerated IDs are omitted when model/year is filtered |

Amounts, expiration and eligibility come from their own official programs and can change. New and CPO assistance values/provenance remain separate. HondaTrue Certified+ is a legacy/discontinued program and is not a supported tier.

New offers are requested by ZIP. Sampled HondaTrue sources are not ZIP-filtered and returned the same advertised programs for tested ZIPs; the requested ZIP does not establish nationwide eligibility. Raw region codes are preserved without invented mappings.

### Partial results

`allowPartialResults` is **off by default**. When both families are selected, setting it to true allows validated data from a surviving family if another fails. Each family must validate fully: CPO requires its backend and page; new-vehicle filtering requires its model configuration. No stale data or fabricated failed-source rows are substituted.

Example STATUS excerpt illustrating a new-source outage, not a guarantee of which source will be available:

```json
{
  "status": "partial_success",
  "resultStatus": "success",
  "selectedSourceFeeds": ["honda_new", "hondatrue_cpo"],
  "successfulSourceFeeds": ["hondatrue_cpo"],
  "failedSourceFeeds": ["honda_new"]
}
```

`partial_success` means returned rows were normalized from validated successful source coverage; the response is incomplete relative to the original request. Never treat it as complete coverage. Disclose `failedSourceFeeds` or retry. If surviving coverage is ambiguous or has no matches, `resultStatus` says so and top-level status remains `partial_success`. Model resolution uses only surviving catalogs and sets `modelResolution.partialSourceCoverage=true`.

If both selected families fail, the run fails. Explicit new-only/CPO-only requests remain strict, even with opt-in. Partial mode does not mask input or storage/runtime failures.

### Data provenance

Each row preserves its official source URL, retrieval timestamp, original program name and source offer/page identifier. Backend IDs and page-section provenance remain distinguishable. The Actor normalizes authoritative OEM data; it does not invent rates, cash amounts, lease payments or buyer eligibility.

Where retrieved, the run’s default key-value store preserves:

| Record | Contents |
| --- | --- |
| `STATUS` | Run outcome, source coverage, model resolution and counts. |
| `RAW_OFFERS` | Official new-vehicle response and provenance. |
| `RAW_CONFIGURATION` | Official model configuration when filtering needs it. |
| `RAW_CPO_OFFERS` | Official HondaTrue backend response and provenance. |
| `RAW_CPO_PAGE` | Official HondaTrue offers-page content and provenance. |
| `SOURCE_FAILURES` | Safe structured source-family failure diagnostics when failures occur. |

Records for sources not selected or responses never received may be absent. A raw document can remain available even if its family later fails validation. Source URLs: [new Honda specials](https://automobiles.honda.com/platform/api/v1/specials?zipCode=60601), [HondaTrue backend](https://www.hondacertified.com/handlers/find-specials-by-filter-handler.ashx), [HondaTrue offers page](https://www.hondacertified.com/special-offers).

### API usage

For AI agents and applications:

1. Submit ZIP plus optional condition/year/model and partial-source preference.
2. Wait for the Actor run to finish.
3. Read normalized dataset rows.
4. Read STATUS, including coverage and `resultStatus`.
5. For ambiguity, select or ask for one returned candidate and rerun.
6. For partial coverage, disclose the missing feeds or retry; never silently present it as complete.

Use the run-ID workflow below so both outputs can be read. The verified API slug is `johnmcdoanld~honda-incentives-apr-api`; preserve that username spelling. Replace token/run/storage placeholders with your own values and keep tokens private. Starting a run invokes the listed billing; polling and output retrieval do not start another run.

Start a run:

```sh
curl --fail-with-body --request POST \
  'https://api.apify.com/v2/actors/johnmcdoanld~honda-incentives-apr-api/runs' \
  --header 'Authorization: Bearer <APIFY_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{"zip":"60601"}'
```

Read `data.id` from the response, then wait for completion. Repeat this request if the returned `data.status` is still transitional; `waitForFinish=60` waits up to 60 seconds per request:

```sh
curl --fail-with-body \
  'https://api.apify.com/v2/actor-runs/<RUN_ID>?waitForFinish=60' \
  --header 'Authorization: Bearer <APIFY_TOKEN>'
```

After completion, use `data.defaultDatasetId` and `data.defaultKeyValueStoreId` from the run object:

```sh
curl --fail-with-body \
  'https://api.apify.com/v2/datasets/<DEFAULT_DATASET_ID>/items?format=json&limit=1000&offset=0' \
  --header 'Authorization: Bearer <APIFY_TOKEN>'

curl --fail-with-body \
  'https://api.apify.com/v2/key-value-stores/<DEFAULT_KEY_VALUE_STORE_ID>/records/STATUS' \
  --header 'Authorization: Bearer <APIFY_TOKEN>'
```

The dataset endpoint returns an array; paginate with `offset`/`limit` if needed. The STATUS endpoint returns the JSON record directly. Check both the platform run status and STATUS: `SUCCEEDED` alone does not prove complete source coverage or a resolved model. For a failed run, inspect available STATUS/diagnostics instead of interpreting an empty dataset as no offers; a platform interruption can prevent STATUS from being written.

Apify also supports `POST /v2/actors/johnmcdoanld~honda-incentives-apr-api/run-sync-get-dataset-items`, which returns dataset items directly and has a 300-second synchronous response limit (HTTP 408 if exceeded). That response does not include this Actor’s STATUS record, so the asynchronous run-ID workflow is preferred for agents needing coverage and ambiguity information. The generic `/run-sync` endpoint defaults to a KVS record named `OUTPUT`, which this Actor does not write; the output schema provides links and does not create that record. Use the run-ID workflow above to retrieve both outputs.

Endpoint syntax and Bearer authentication were checked against official Apify docs on October 7, 2026: [authentication](https://docs.apify.com/api/v2), [start a run](https://docs.apify.com/api/v2/act-runs-post), [get/wait for a run](https://docs.apify.com/api/v2/actor-run-get), [dataset items](https://docs.apify.com/api/v2/dataset-items-get), [KVS record](https://docs.apify.com/api/v2/key-value-store-record-get), [synchronous dataset endpoint](https://docs.apify.com/api/v2/act-run-sync-get-dataset-items-post).

### Known limitations

- Honda U.S. only; supported manufacturer programs, not every incentive or dealer-specific offer.
- ZIP-aware source requests and explicit legal geography do not establish buyer residence, credit approval or eligibility. Unknown geographic restrictions remain in legal text; no Region A/B mapping is inferred.
- HondaTrue Certified leasing is not currently normalized. CPO model/year coverage is limited to confidently supported source applicability.
- Honda can change program values, expiration, source structure or availability. Review timestamps, warnings and current official/dealer terms.
- Partial responses are explicitly incomplete. Retrieval retries can delay results; a successful family does not make unavailable-source data known.

For local setup, architecture and validation commands, see [Engineering](docs/ENGINEERING.md). The current [verification log](docs/VERIFICATION.md) and [short backlog](docs/BACKLOG.md) track phase-one readiness. Detailed source research and historical validation evidence are in [RESEARCH.md](RESEARCH.md); reusable store copy is in [Marketplace](docs/MARKETPLACE.md).

# Actor input Schema

## `zip` (type: `string`):

Required five-digit U.S. ZIP code as text, including leading zeros (for example 02108). Checked against a ZIP directory. ZIP+4 and numeric inputs are not supported.

## `vehicleCondition` (type: `string`):

Choose new for new vehicles or cpo for supported HondaTrue Certified/HondaTrue Used offers. Omit to query both. HondaTrue leasing is not supported. Some CPO assistance appears only when model and year are omitted, because Honda does not list applicable vehicles.

## `modelYear` (type: `integer`):

Optional exact model year as a whole number. Omit to include all supported applicable years. A year filter may omit programs for which Honda does not specify applicable vehicles.

## `model` (type: `string`):

Optional Honda model name. Safe case, spaces, punctuation and a leading Honda name are normalized (for example CRV or Honda CRV). Exact official identities remain distinct. Ambiguous names such as Accord return candidates in STATUS and no rows; the Actor does not guess or correct typos. Omit for all supported models.

## `allowPartialResults` (type: `boolean`):

Allow partial results if one of the selected Honda source families is temporarily unavailable. Disabled by default. Applies only when both new and CPO are selected; single-source requests stay strict. Inspect STATUS.failedSourceFeeds and disclose missing coverage.

## Actor input object example

```json
{
  "zip": "60601",
  "allowPartialResults": false
}
```

# Actor output Schema

## `offers` (type: `string`):

Normalized supported offers as dataset items. One Honda APR program may produce multiple term/rate-tier rows. Nullable missing values remain null. Read STATUS before treating coverage as complete.

## `status` (type: `string`):

Run-level STATUS JSON: success, no_offers, ambiguous_model, partial_success or a classified failure. Inspect selectedSourceFeeds, successfulSourceFeeds, failedSourceFeeds, resultStatus, modelResolution and outputRowCount where present.

## `rawOffers` (type: `string`):

Stored official Honda new-vehicle response with source URL, HTTP status and retrieval timestamp; body is the original response text. May be absent if not selected or retrieval failed.

## `rawCpoOffers` (type: `string`):

Stored official HondaTrue backend response and provenance. Can remain available even if the CPO family later fails page validation. May be absent when not retrieved.

## `rawCpoPage` (type: `string`):

Stored official HondaTrue page content and provenance for supported page-derived programs. May be absent if CPO was not selected or retrieval failed.

## `sourceFailures` (type: `string`):

Safe classified failure diagnostics identifying the failed source family and official URL. No placeholder incentive rows or unknown offer counts. This record may be absent when no family failed.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "zip": "60601"
};

// Run the Actor and wait for it to finish
const run = await client.actor("johnmcdoanld/honda-incentives-apr-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "zip": "60601" }

# Run the Actor and wait for it to finish
run = client.actor("johnmcdoanld/honda-incentives-apr-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "zip": "60601"
}' |
apify call johnmcdoanld/honda-incentives-apr-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,johnmcdoanld/honda-incentives-apr-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4W5DZzdoNiFjbpoZm/builds/1lotn92yqRr7hO0eM/openapi.json
