FORVUE
Know Before It Fails

Partner API Reference

Version 2.0  ·  July 9, 2026
A complete integration guide for property management platforms, insurance carriers, lenders, and IoT sensor providers connecting to the ForVue predictive maintenance intelligence platform. This document covers all 33 partner endpoints with authentication, rate limiting, webhooks, pagination, idempotency, sandbox mode, and a complete scoring engine reference.
Wise Capital, LLC
Louisville, Kentucky
wise@investwisecap.com
Confidential & Proprietary
Patent Pending USPTO 64/032,704
© 2026 Wise Capital, LLC
PARTNER API REFERENCE v1.0
DOCUMENT

Table of Contents

Part I — Getting Started
Part II — Platform Concepts
Part III — Endpoint Reference (Read)
GET /v1/pingHealth Check
GET /v1/propertiesList Properties
GET /v1/componentsScored Components
GET /v1/alertsActive Alerts
GET /v1/eventsChange Stream
Part IV — Endpoint Reference (Write)
POST /oauth/tokenOAuth Bearer Token
POST /v1/propertiesCreate Property
POST /v1/appliancesCreate Appliance
PUT /v1/appliances/{id}Update Appliance
POST /v1/service-events/bulkBulk Service Events
Part V — Reference

1Getting Started

The ForVue Partner API gives your platform programmatic access to predictive AND operational maintenance intelligence for multifamily and commercial real estate. Integrate once, and your users can see risk scores, projected failures, reserve recommendations, insurance RCV, lender-grade condition scores, diagnostic suggestions, vendor matches, and parts-availability data — derived from a proprietary multi-factor Weibull-Bayesian scoring engine with a cascade dependency model, layered with a 30-type / 169-component knowledge base calibrated against ASHRAE, HUD, and NAHB published standards. The specific factors, weights, cascade rules, and formulas are trade secrets of Wise Capital, LLC (DTSA-protected; USPTO 64/032,704).

Base URL

https://platform.investwisecap.com/api/v1

All endpoints in this reference are relative to this base. Example: /v1/properties is reached at https://platform.investwisecap.com/api/v1/properties.

What You'll Need

  1. API credentials — an API key (for simple integrations) or OAuth 2.0 client credentials (for production partners). Request via email to wise@investwisecap.com.
  2. A webhook endpoint (optional) — a publicly reachable HTTPS URL where ForVue posts real-time events (component tier changes, sensor events, service events).
  3. Partnership agreement — executed between your organization and Wise Capital, LLC. The agreement governs rate limits, billing (if applicable), data usage, and the competitive-use restrictions in Section 12.

Making Your First Call

The fastest way to verify credentials and connectivity:

# Replace fv_live_XXX with your issued API key
curl -i https://platform.investwisecap.com/api/v1/ping \
     -H "X-Api-Key: fv_live_XXX"

Successful response:

HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: "2026-04-21T00:00:00.000Z"
Content-Type: application/json

{
  "ok": true,
  "timestamp": "2026-04-20T14:30:00.000Z",
  "partner": "AppFolio"
}

If you see HTTP 401, your key is invalid. If you see HTTP 429, you've exceeded your daily rate limit (reset at midnight UTC). See Section 11 for a full error reference.

DEVELOPER SANDBOX You can develop against demo property data by appending ?sandbox=true to any list endpoint. No real operator data is returned. See Section 6.

Integration Checklist

StepWhat to BuildReference
1Store API credentials securely (env vars, secret manager). Never commit to source control.§ 2
2Wrap outbound calls with rate-limit awareness using the three response headers.§ 3
3Implement pagination for list endpoints. Never assume all data fits in one response.§ 4
4Generate unique Idempotency-Key headers for every POST that creates data.§ 5
5Set up a webhook receiver with HMAC signature verification.§ 9
6Handle all 4xx and 5xx error codes gracefully — never silent-fail on partner data.§ 11

2Authentication

ForVue supports two authentication methods. You may use either for any endpoint that requires authentication. Both produce the same access scope — your choice comes down to operational preference.

MethodBest ForExpiryRevocation
API KEYSimple server-to-server scripts, scheduled jobs, prototypes.Never (until rotated)By Wise Capital admin
OAUTH 2.0Production integrations, user-initiated flows, multi-tenant apps.1 hourBy expiry or admin

2.1 API Key Authentication

Pass your API key in the X-Api-Key request header on every call:

curl https://platform.investwisecap.com/api/v1/properties \
     -H "X-Api-Key: fv_live_7f8a9b2c3d4e5f6a7b8c9d0e1f2a3b4c"

API keys are prefixed fv_live_ followed by 48 hexadecimal characters. They never expire but can be rotated at any time by a Wise Capital administrator. When a key is rotated, the previous key is immediately invalidated.

API KEY SECURITY Treat your API key like a password. Never commit it to source control, never log it, never expose it client-side. If you suspect a key has been compromised, email wise@investwisecap.com for immediate rotation.

2.2 OAuth 2.0 Client Credentials Flow

OAuth is the preferred method for production partners. You exchange a client_id and client_secret for a short-lived bearer token, then use that token on subsequent API calls.

Step 1 — Obtain a Bearer Token

curl -X POST https://platform.investwisecap.com/api/oauth/token \
     -H "Content-Type: application/json" \
     -d '{
       "grant_type": "client_credentials",
       "client_id": "your_client_id",
       "client_secret": "your_client_secret"
     }'

Response:

{
  "access_token": "fvt_abc123def456...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read write",
  "partner": "AppFolio"
}

Step 2 — Use the Bearer Token

curl https://platform.investwisecap.com/api/v1/properties \
     -H "Authorization: Bearer fvt_abc123def456..."

Token Lifecycle

WHEN TO REFRESH Best practice: request a new token when you have less than 5 minutes of validity remaining. Don't refresh on every API call — that wastes rate-limit quota. Cache the token and its expiry timestamp.

2.3 Public Endpoints

Three endpoints do not require authentication:

3Rate Limiting

ForVue enforces three independent rate limits. The first is per-partner and per-day (your daily budget). The other two are transport-layer safeguards that apply to every request regardless of authentication, to protect Platform availability.

3.1 Per-Partner Daily Budget

Every partner is assigned a daily call budget enforced in a rolling 24-hour window from midnight UTC to midnight UTC. The default is 1,000 calls per day. Higher limits are available by agreement.

Every authenticated response includes three rate-limit headers:

HeaderTypeMeaning
X-RateLimit-LimitintegerYour daily maximum. Example: 1000.
X-RateLimit-RemainingintegerCalls remaining in the current window. Example: 847.
X-RateLimit-Resetstring (ISO 8601)UTC timestamp when the counter resets. Always the next midnight UTC.

3.2 Transport-Layer Limits (per-IP and per-user)

In addition to the per-partner daily budget, all requests to the Platform are subject to two safeguards enforced at the transport layer:

ScopeLimitResponse when exceeded
Per source IP address120 requests / minuteHTTP 429, body: {"error":"Too many requests. Please slow down."}
Per authenticated user or partner60 requests / minuteHTTP 429, body: {"error":"Rate limit exceeded. Maximum 60 requests per minute."}

Requests that trip either transport-layer limit do not count against your daily budget. Both limits are subject to change without notice; they exist to protect Platform availability and are not intended as a substitute for a properly sized commercial rate limit.

3.3 Exceeding the Daily Budget

When the remaining daily count hits zero, subsequent calls return HTTP 429 Too Many Requests:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: "2026-07-10T00:00:00.000Z"
Content-Type: application/json

{
  "error": "Daily rate limit exceeded (1000 calls/day). Resets at midnight UTC."
}

3.4 Handling Rate Limits

Best practices:

CIRCUMVENTION IS A BREACH Attempts to bypass rate limits — rotating API keys, masking source IPs, parallel requests across multiple partner accounts — are a material breach of the Partnership Agreement and subject to immediate termination.

4Pagination

All list endpoints support offset-based pagination. This is critical for partners with large portfolios — a single property may have hundreds of components, and a portfolio may have thousands of properties.

4.1 Query Parameters

ParameterTypeDefaultMaxDescription
limitinteger50200Records per page. Values above 200 are capped.
offsetinteger0Records to skip. Use to fetch subsequent pages.

4.2 Response Envelope

Every paginated endpoint returns the collection plus pagination metadata:

{
  "properties": [ // or "components", "alerts", "events", etc.
    { ... 50 records ... }
  ],
  "total": 342,
  "limit": 50,
  "offset": 0,
  "page": 1,
  "pages": 7,
  "partner": "AppFolio"
}

4.3 Walking All Pages

Example — fetch every property using pagination:

// Pseudocode
let offset = 0;
const limit = 200;
const all = [];

while (true) {
  const res = await fetch(
    `${BASE}/v1/properties?limit=${limit}&offset=${offset}`,
    { headers: { 'X-Api-Key': API_KEY } }
  ).then(r => r.json());

  all.push(...res.properties);
  if (offset + limit >= res.total) break;
  offset += limit;
}

4.4 Paginated Endpoints

The following endpoints support limit and offset:

OFFSET OVERRUN If offset exceeds total, you receive an empty collection array plus correct total and pages values. No error.

5Idempotency

Write endpoints that create resources support idempotency keys to prevent duplicate records when a request must be retried (e.g., after a timeout or network error).

5.1 The Idempotency-Key Header

Send a unique string in the Idempotency-Key request header when creating data:

curl -X POST https://platform.investwisecap.com/api/v1/appliances \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: appfolio-sync-2026-04-20-unit-3b-hvac" \
     -d '{ "property_id": "P_abc123", "type_id": "hvac_central", ... }'

5.2 Behavior

5.3 Supported Endpoints

EndpointWhy It Matters
POST /v1/propertiesAvoid duplicate property records during PMS sync.
POST /v1/appliancesAvoid duplicate appliance entries.
POST /v1/appliances/bulkBatch-safe; never re-process a batch.
POST /v1/meter-eventPrevent double-booking sensor events.
POST /v1/meter-event/smartSame; includes auto-creation of properties/appliances.
POST /v1/meter-event/smart/v2Includes webhook side-effects; idempotency critical.
POST /v1/service-events/bulkBulk service event imports.
POST /v1/property/{id}/claimsPrevent duplicate insurance claim imports.

5.4 Key Design Recommendations

CACHE STORAGE Idempotency cache is persisted in the ForVue database and survives server restarts. Entries older than 24 hours are pruned automatically.

6Sandbox Mode

Sandbox mode lets partner engineers develop and test against realistic demo data without touching any real operator's portfolio. Credentials are the same — only the data is different.

6.1 Enabling Sandbox

Append ?sandbox=true to any supported list endpoint:

curl "https://platform.investwisecap.com/api/v1/properties?sandbox=true" \
     -H "X-Api-Key: fv_live_XXX"

Only records belonging to demo properties (created via the ForVue Welcome Wizard or POST /onboarding/demo-property) are returned.

6.2 Supported Endpoints

Sandbox is a read-only filter. It does not apply to write endpoints — POST /v1/appliances with ?sandbox=true still writes to the live data store (scoped to the target property).

6.3 What You Get in Sandbox

A demo property typically contains:

EMPTY SANDBOX? If your sandbox returns empty results, no demo property exists in your account scope. Contact wise@investwisecap.com or ask an account admin to trigger demo data provisioning.

7Data Model

The ForVue platform organizes real estate intelligence into a clear four-level hierarchy. Understanding this hierarchy is essential for integration — most endpoints accept a property, appliance, or component ID as a path parameter.

7.1 Entity Hierarchy

Property (a physical address with rental units)
    │
    ├─ Unit (individual rentable unit, e.g., "Unit 3B")
    │
    └─ Appliance (major equipment at the property, optionally in a unit)
            │
            └─ Component (individual scoreable part of an appliance)
                    │
                    ├─ Service Event (maintenance record)
                    └─ Risk Snapshot (daily score history)

7.2 Core Entities

Property

A single physical property. Operators may own many properties; each property has an owner and optionally a partner reference (partner_property_id) for cross-system identification.

FieldTypeDescription
idstringPrefixed unique ID, e.g., P_abc123
namestringDisplay name (e.g., "Maple Ridge Apartments")
address, city, state, zipstringPhysical address
unit_countintegerTotal rentable units (billing basis)
year_builtintegerYear constructed (optional, improves scoring)
estimated_valuenumberOptional — enables deferred_as_pct_of_value in RCV endpoint
is_demobooleantrue for demo properties; excluded from billing
created_atstring (ISO 8601)Creation timestamp

Appliance

A major piece of equipment installed at a property (HVAC unit, water heater, boiler, elevator, etc.). Optionally tied to a specific unit.

FieldTypeDescription
idstringPrefixed unique ID, e.g., A_xyz789
property_idstringParent property
unit_idstring?Parent unit (optional — some appliances are property-wide)
type_idstringAppliance type from the Knowledge Base (see Appendix)
brand, model, serialstringManufacturer identification
brand_tierstringpremium · standard · budget — affects scoring
install_yearintegerYear installed — primary age input to scoring
usage_intensitynumber0.5 (light) to 2.0 (heavy); default 1.0
warranty_expirystring (date)Warranty end date

Component

A single scoreable part of an appliance (e.g., a water heater's anode rod, tank, or pressure relief valve). Each appliance has a deterministic set of components based on its type — created automatically when the appliance is created.

FieldTypeDescription
idstringPrefixed unique ID, e.g., C_def456
appliance_idstringParent appliance
component_def_idstringReference to Knowledge Base definition (e.g., wh_gas_anode)
install_yearintegerDefaults to parent appliance install year unless separately replaced
last_replacedstring (date)Most recent replacement; resets the age clock
last_servicedstring (date)Most recent inspection or maintenance
override_lifespaninteger?Override default Weibull lifespan (rare)

Service Event

A maintenance record: preventive maintenance, inspection, repair, replacement, emergency repair, etc. Events feed back into the scoring engine as Bayesian evidence.

FieldTypeDescription
idstringPrefixed unique ID, e.g., SE_abc123
appliance_idstringSubject of the event
component_idstring?Specific component (optional — may apply to whole appliance)
event_typestringOne of 9 event types (see below)
datestring (date)Event date (YYYY-MM-DD)
parts_cost, labor_cost, total_costnumberCost breakdown in USD
notesstringFree-form description; scanned for risk keywords
condition_afterstringgood · fair · poor (optional)

Valid event_type values:

TypeEffect on Scoring
Preventive MaintenancePositive — may lower risk if completed on at-risk components
InspectionNeutral to positive — updates confidence, provides data
Filter ChangePositive — HVAC/water specific
CleaningPositive — component specific
RepairNeutral — recent repairs add risk (repair frequency factor)
ReplacementResets age clock; captures Validation Data for accuracy tracking
Emergency RepairCaptures Validation Data; high-weight signal of failure
Warranty ClaimNeutral — informational
OtherNeutral — informational

Risk Snapshot

An immutable daily record of a component's risk score, taken at 3:00 AM UTC. Enables time-series trending via GET /v1/components/{id}/trend. Retained for 365 days.

7.3 ID Format

All resource IDs are prefixed strings, never sequential integers. Prefixes encode the resource type for debuggability:

PrefixResourceExample
P_PropertyP_abc123
U_UnitU_xyz789
A_ApplianceA_def456
C_ComponentC_ghi789
SE_Service EventSE_jkl012
CLM_Insurance ClaimCLM_mno345

8Scoring Engine

This section explains how ForVue produces risk scores so your engineers can explain the output to your users without needing to contact us. The underlying math, specific parameter values, brand multiplier tables, likelihood ratios, and cascade rules are proprietary trade secrets protected under the DTSA and are not disclosed in this document.

8.1 The Risk Score

Every component receives a risk score — a number between 0.00 and 0.99 representing the estimated cumulative probability of failure within the component's remaining predicted lifespan.

The scoring engine is a proprietary multi-factor composite Weibull-Bayesian model layered with a cascade dependency mechanism, calibrated against ASHRAE Applications Ch.38, HUD, NAHB, and RSMeans published data. Inputs include calendar age, Bayesian updates from logged service events, environmental and usage adjustments, manufacturer characteristics, and cross-component dependencies — combined under a proprietary weighting model.

The specific factors, weights, thresholds, cascade rules, and formulas are trade secrets of Wise Capital, LLC and are not published — protected under DTSA, with the broader scoring methodology covered by USPTO Provisional Patent Application 64/032,704. Scores themselves are deterministic and independently verifiable from your service-event history; the engine internals are not.

8.2 Risk Tiers

Every risk score is also classified into one of three tiers — a simplification partners can display in user interfaces without exposing the raw score:

TierScore RangeMeaning
CRITICAL>= 0.78High probability of failure within 12 months. Immediate proactive action recommended to avoid reactive costs that are typically 3–12× higher than proactive intervention.
WARNING0.52 – 0.77Elevated risk. Schedule preventive maintenance within 6 months.
GOOD< 0.52Standard monitoring. Follow routine maintenance schedules.

8.3 Confidence Intervals

Every risk score ships with a confidence rating reflecting how much data the engine had to work with:

ConfidenceMargin of ErrorProjected Range WidthTypical Cause
HIGH± 2%±4% of effective lifespanMultiple service events, observed conditions, known brand/year
MEDIUM± 3%±8% of effective lifespanSome service history or known brand
LOW± 4%±12% of effective lifespanSparse data; newly added appliance with no service events

The _score_data object returned with components includes projected_failure_range:

"projected_failure_range": {
  "earliest": 2027,
  "latest": 2029,
  "confidence_pct": 92
}

8.4 Score Refresh Cadence

Risk scores are recomputed:

Partner integrations polling more frequently than daily add no value. Use the event stream (Section 10) or webhooks (Section 9) for change notifications instead.

8.5 What the Score Is Not

SCORES ARE PROBABILISTIC, NOT DETERMINISTIC A risk score of 0.84 does not mean the component will fail. It means the cumulative probability of failure by the component's predicted lifespan endpoint is high. Components occasionally fail below the CRITICAL threshold and routinely operate past it. Scores are a prioritization tool, not a guarantee.

9Webhooks

Webhooks deliver real-time events from ForVue to your system as they happen. Configure a webhook URL during partner onboarding and your endpoint will receive signed HTTP POST requests whenever a component crosses a risk threshold, a service event is logged, or a sensor event is processed.

9.1 Request Format

Every webhook delivery is a POST request with this envelope:

POST https://your-server.com/forvue-webhook HTTP/1.1
Content-Type: application/json
User-Agent: ForVue-Webhook/1.0
X-ForVue-Signature: sha256=9a8f7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a...
X-ForVue-Delivery: WH_1713620400000_AB7X9
X-ForVue-Event: component.critical

{
  "event": "component.critical",
  "timestamp": "2026-04-20T14:30:00.000Z",
  "partner_id": "PARTNER_abc123",
  "partner": "AppFolio",
  "version": "v1",
  "data": { // event-specific payload — see Section 9.3 }
}

9.2 HMAC Signature Verification

Every delivery includes an HMAC-SHA256 signature computed from your partner's webhook_secret and the raw request body. Your webhook endpoint must verify this signature before processing any event — otherwise, any attacker who discovers your URL can send forged events.

Signature Header Format

Header name: X-ForVue-Signature
Value format: sha256=<hex-encoded HMAC-SHA256 digest>

Node.js / JavaScript Verification

const crypto = require('crypto');

function verifyForVueSignature(rawBody, signatureHeader, webhookSecret) {
  if (!signatureHeader || !signatureHeader.startsWith('sha256=')) return false;

  const expected = 'sha256=' + crypto
    .createHmac('sha256', webhookSecret)
    .update(rawBody)
    .digest('hex');

  // timingSafeEqual prevents timing attacks
  const a = Buffer.from(expected);
  const b = Buffer.from(signatureHeader);
  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
}

// Express example
app.post('/forvue-webhook',
  express.raw({ type: 'application/json' }), // raw body required
  (req, res) => {
    const rawBody = req.body.toString('utf8');
    const valid = verifyForVueSignature(
      rawBody,
      req.headers['x-forvue-signature'],
      process.env.FORVUE_WEBHOOK_SECRET
    );
    if (!valid) return res.status(401).json({ error: 'Invalid signature' });

    const event = JSON.parse(rawBody);
    // ... process event ...
    res.status(200).json({ received: true });
  }
);

Shell Verification (OpenSSL)

# Verify manually against a captured webhook body
BODY=$(cat webhook-body.json)
SIG="sha256=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$FORVUE_WEBHOOK_SECRET" -binary | xxd -p -c 256)"
[ "$SIG" = "$RECEIVED_SIGNATURE" ] && echo "valid" || echo "invalid"

Use whichever HMAC-SHA256 primitive your stack ships. The Node example above is our canonical reference; language-native constant-time-equal / timingSafeEqual comparators must be used to prevent timing side-channels.

SIGNATURE VERIFICATION IS MANDATORY ForVue will flag any partner endpoint that receives a webhook and responds 2xx without verifying the signature. Non-verifying endpoints may be disconnected from the webhook system.

9.3 Event Types

Nine event types are currently emitted. Your endpoint should implement a case statement on the event field and gracefully ignore unknown event types (ForVue may add new events without a breaking version bump).

component.critical

A component crossed the CRITICAL threshold (score ≥ 0.78). Triggered by the 3 AM daily snapshot or immediately after a smart meter event.

{
  "event": "component.critical",
  "timestamp": "2026-04-20T03:00:00.000Z",
  "partner_id": "PARTNER_abc123",
  "partner": "AppFolio",
  "version": "v1",
  "data": {
    "component_id": "C_def456",
    "component_name": "Anode Rod",
    "component_def_id": "wh_gas_anode",
    "appliance_id": "A_ghi789",
    "appliance_type": "water_heater_gas",
    "property_id": "P_abc123",
    "property_name": "Maple Ridge Apartments",
    "risk_score": 0.847,
    "risk_tier": "CRITICAL",
    "previous_tier": "WARNING",
    "confidence": "HIGH",
    "proactive_cost": 220,
    "reactive_cost": 1800
  }
}

component.warning

A component crossed the WARNING threshold (0.52 ≤ score < 0.78). Same payload shape as component.critical with risk_tier set to WARNING.

component.recovered

A component returned to GOOD from CRITICAL or WARNING — typically after a Replacement service event. Same payload; risk_tier is GOOD and previous_tier is the prior elevated tier.

service_event.created

A service event (repair, inspection, preventive maintenance, etc.) was logged for an appliance.

{
  "event": "service_event.created",
  "timestamp": "2026-04-20T14:30:00.000Z",
  "data": {
    "event_id": "SE_xyz789",
    "event_type": "Repair",
    "appliance_id": "A_ghi789",
    "appliance_type": "water_heater_gas",
    "property_id": "P_abc123",
    "property_name": "Maple Ridge Apartments",
    "total_cost": 265,
    "date": "2026-04-20"
  }
}

property.created

A new property was created. Fires for all creation paths including partner API writes and auto-creation from smart meter events.

{
  "event": "property.created",
  "data": {
    "property_id": "P_abc123",
    "address": "123 Main St",
    "city": "Louisville",
    "state": "KY",
    "source": "sensor_event"
  }
}

appliance.created

A new appliance was added to a property.

{
  "event": "appliance.created",
  "data": {
    "appliance_id": "A_ghi789",
    "type_id": "hvac_central",
    "property_id": "P_abc123"
  }
}

sensor.received

A raw sensor event was processed via POST /v1/meter-event. Fired for basic (non-smart) meter events.

sensor.smart

A smart sensor event was processed via POST /v1/meter-event/smart/v2, including auto-creation of missing property/appliance records and re-scoring of affected components.

{
  "event": "sensor.smart",
  "data": {
    "event_id": "PE_klm456",
    "event_type": "Replacement",
    "property_id": "P_abc123",
    "appliance_id": "A_ghi789",
    "risk_summary": {
      "components_scored": 6,
      "critical_count": 1,
      "warning_count": 2
    }
  }
}

sensor.smart.processed

Legacy callback envelope used by the v1 smart meter callback flow. New integrations should use sensor.smart instead.

webhook.test

Emitted when an admin triggers a manual test from the ForVue dashboard. Useful for verifying your endpoint is reachable and your signature verification is working.

9.4 Response Requirements

9.5 Retry Logic

If your endpoint fails to respond 2xx within 8 seconds, ForVue retries with exponential backoff:

AttemptDelayCumulative
1Immediate0s
2+5 seconds5s
3+30 seconds35s

After 3 failed attempts, the delivery is marked as failed but logged in the ForVue delivery log. Admins can manually resend failed deliveries via POST /admin/webhook-deliveries/{id}/resend.

9.6 Delivery Log

Every webhook attempt — successful or failed — is recorded with:

Partners can request delivery log exports by emailing wise@investwisecap.com.

9.7 Configuring Your Webhook URL

Webhook URL, secret rotation, and event type filters are configured per-partner by a Wise Capital administrator. Email wise@investwisecap.com with:

10Event Stream

If webhooks aren't practical for your architecture (firewall constraints, no public endpoint, preference for pull over push), the event stream endpoint provides a polling-based alternative. Query it periodically to get every change since your last sync.

10.1 Endpoint

GET /v1/events?since=2026-04-15T00:00:00Z&limit=100&offset=0

10.2 Parameters

ParamTypeRequiredDescription
sincestring (ISO 8601)RequiredReturns events after this timestamp. Example: 2026-04-15T00:00:00Z
limitintegerOptionalRecords per page. Default: 50. Max: 200.
offsetintegerOptionalRecords to skip. Default: 0.

10.3 Entity Types Returned

Event TypeSourceWhen Returned
property.createdProperties collectionProperty created_at > since
appliance.createdAppliances collectionAppliance created_at > since
service_event.createdService events collectionEvent created_at > since
component.criticalComponents (live scoring)Always included if currently CRITICAL
component.warningComponents (live scoring)Always included if currently WARNING
NOTE ON CURRENT-STATE EVENTS component.critical and component.warning events are included regardless of the since timestamp. They represent the current state of at-risk components, not a historical change. This means the event stream doubles as an "active alerts" query.

10.4 Response

{
  "events": [
    {
      "type": "service_event.created",
      "timestamp": "2026-04-20T14:30:00.000Z",
      "data": {
        "id": "SE_xyz789",
        "event_type": "Repair",
        "appliance_id": "A_ghi789",
        "total_cost": 265,
        "date": "2026-04-20"
      }
    },
    {
      "type": "component.critical",
      "timestamp": "2026-04-20T18:00:00.000Z",
      "data": {
        "id": "C_def456",
        "component_name": "wh_gas_anode",
        "risk_score": 0.832,
        "risk_tier": "CRITICAL",
        "property_id": "P_abc123"
      }
    }
  ],
  "total": 42,
  "limit": 100,
  "offset": 0,
  "page": 1,
  "pages": 1,
  "since": "2026-04-15T00:00:00Z",
  "partner": "AppFolio"
}

10.5 Sync Pattern

  1. On first sync: call with since= set to 30 days ago (or your desired lookback)
  2. Store the latest timestamp from the response
  3. On subsequent syncs: call with since= set to your last stored timestamp
  4. Walk pages until events array is empty or offset + limit >= total
  5. Process each event by type, deduplicate by data.id

Recommended polling interval: every 15 minutes for near-real-time, hourly for daily-sync use cases. Risk scores only update at 3 AM UTC, so more frequent polling adds no scoring value.

11Error Handling

All errors return a JSON body with an error field. Partners should handle errors by HTTP status code and use the error string for logging and debugging — not for conditional logic (error strings may change without notice).

11.1 Standard Error Codes

StatusMeaningExample errorAction
400Bad Request — missing or invalid parameters"name, address, state required"Fix request body/params. Check required fields.
401Unauthorized — invalid or missing credentials"API key required. Pass via X-Api-Key header."Check API key or refresh OAuth token.
401OAuth token expired"Invalid or expired OAuth token. Re-authenticate at POST /oauth/token"Request a new token.
404Not Found — resource doesn't exist"Property not found"Verify the ID. Resource may have been deleted.
409Conflict — resource already exists"Demo property already exists"Use the existing resource or delete first.
429Rate Limited — daily call budget exceeded"Daily rate limit exceeded (1000 calls/day). Resets at midnight UTC."Wait until X-RateLimit-Reset. See § 3.
500Internal Server Error"Internal server error"Retry with backoff. If persistent, contact support.

11.2 Error Response Format

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "property_id, type_id, install_year required"
}

11.3 Bulk Endpoint Errors

Bulk write endpoints (/v1/appliances/bulk, /v1/service-events/bulk, /v1/property/{id}/claims) return partial success. Some records may succeed while others fail:

HTTP/1.1 201 Created

{
  "created": 8,
  "errors": 2,
  "events": [ /* 8 successfully created records */ ],
  "error_details": [
    { "index": 3, "error": "Appliance not found: A_invalid_id" },
    { "index": 7, "error": "event_type and date required" }
  ]
}

Always check both created and errors. If errors > 0, inspect error_details for per-record failure reasons and retry or fix those records.

11.4 Retry Recommendations

StatusRetryable?Strategy
400NoFix request and resend.
401Yes (after re-auth)If API key: contact Wise Capital. If OAuth: request new token.
404NoResource deleted or never existed.
429Yes (after wait)Wait until X-RateLimit-Reset timestamp.
500YesExponential backoff: 1s, 2s, 4s, 8s, max 60s. Max 5 retries.
502/503/504YesSame backoff. ForVue may be restarting (typically < 5 seconds).

Part III — Endpoint Reference (Read)

This section documents every read endpoint in the Partner API. Each entry includes method, path, authentication, parameters, response schema, a working curl example, and error cases specific to that endpoint.

GET /v1/ping API KEY or OAuth

Health check. Returns a 200 if your credentials are valid and ForVue is operational. Use this endpoint as a connectivity test during integration and as an ongoing heartbeat check.

Request

curl https://platform.investwisecap.com/api/v1/ping \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "ok": true,
  "timestamp": "2026-04-20T14:30:00.000Z",
  "partner": "AppFolio"
}

Response Fields

FieldTypeDescription
okbooleanAlways true on success
timestampstring (ISO 8601)Server time at request
partnerstringYour partner company name

Errors

  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
GET /v1/openapi.json PUBLIC (no auth)

OpenAPI 3.0 specification. Returns the full machine-readable API spec. Load this into Postman, Insomnia, Stoplight, or any OpenAPI-compatible tooling to auto-generate client SDKs and test harnesses.

Request

curl https://platform.investwisecap.com/api/v1/openapi.json

Response 200

{
  "openapi": "3.0.3",
  "info": {
    "title": "ForVue Partner API",
    "version": "1.0.0",
    "description": "Predictive maintenance intelligence..."
  },
  "servers": [ { "url": "/v1" } ],
  "security": [ { "apiKey": [] }, { "oauth2": [] } ],
  "paths": { /* all 33 endpoints described */ }
}
USE CASE The OpenAPI spec is authoritative. If a detail in this PDF ever conflicts with openapi.json, the JSON wins. Programmatic integrations should always consume the live spec.
GET /v1/auth/methods PUBLIC (no auth)

Authentication method discovery. Returns a list of supported authentication methods and their configuration details. Useful for SDKs that want to auto-detect whether a given partner should use API keys or OAuth.

Request

curl https://platform.investwisecap.com/api/v1/auth/methods

Response 200

{
  "methods": [
    {
      "type": "api_key",
      "header": "X-Api-Key",
      "description": "Static API key — simple, no expiry"
    },
    {
      "type": "oauth2",
      "grant": "client_credentials",
      "token_endpoint": "/oauth/token",
      "description": "Bearer token — expires in 1 hour, preferred for production"
    }
  ],
  "docs": "Contact wise@investwisecap.com for credentials"
}
GET /v1/properties API KEY or OAuth PAGINATED SANDBOX

List all properties. Returns a paginated list of properties accessible to your partner scope. Use this as the entry point for any integration that needs to enumerate a customer's portfolio.

Parameters

ParamTypeDefaultDescription
limitinteger50Records per page (max 200)
offsetinteger0Records to skip
sandboxstringPass true to return only demo properties

Request

curl "https://platform.investwisecap.com/api/v1/properties?limit=50" \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "properties": [
    {
      "id": "P_abc123",
      "name": "Maple Ridge Apartments",
      "address": "123 Main St",
      "city": "Louisville",
      "state": "KY",
      "zip": "40202",
      "unit_count": 24,
      "created_at": "2026-03-15T10:00:00.000Z"
    }
  ],
  "total": 142,
  "limit": 50,
  "offset": 0,
  "page": 1,
  "pages": 3,
  "partner": "AppFolio"
}

Errors

  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
GET /v1/portfolio/summary API KEY or OAuth PAGINATED SANDBOX

Portfolio-wide rollup. Returns every property with a risk summary, financial rollup, and appliance/component counts in a single call. Designed for dashboard displays where you need the portfolio overview without per-property round trips.

Parameters

ParamTypeDefaultDescription
limitinteger50Records per page
offsetinteger0Records to skip
sandboxstringtrue for demo properties only

Request

curl https://platform.investwisecap.com/api/v1/portfolio/summary \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "portfolio": [
    {
      "property_id": "P_abc123",
      "name": "Maple Ridge Apartments",
      "address": "123 Main St",
      "city": "Louisville",
      "state": "KY",
      "unit_count": 24,
      "appliances": 8,
      "components": 52,
      "critical": 3,
      "warning": 7,
      "good": 42,
      "overall_rating": "POOR",
      "total_deferred_maintenance": 14500,
      "total_reactive_exposure": 89200,
      "deferred_per_door": 604
    }
  ],
  "total": 142,
  "limit": 50,
  "offset": 0,
  "totals": {
    "properties": 142,
    "appliances": 1138,
    "components": 7402,
    "critical": 47,
    "warning": 184,
    "good": 7171,
    "total_deferred": 1840000,
    "total_reactive": 12650000
  },
  "partner": "AppFolio"
}
PRIMARY DASHBOARD ENDPOINT This is the single most efficient call for rendering a portfolio view. Prefer this over enumerating /v1/properties and then calling /v1/property/{id}/summary for each.

Errors

  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
GET /v1/property/{id}/summary API KEY or OAuth

Property-level summary. Returns risk tier breakdown, financial totals, deferred maintenance, reactive exposure, and recommended monthly reserve for a single property. Use this for a property detail page.

Path Parameters

ParamTypeDescription
idstringProperty ID (e.g., P_abc123)

Request

curl https://platform.investwisecap.com/api/v1/property/P_abc123/summary \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "property": {
    "id": "P_abc123",
    "name": "Maple Ridge Apartments",
    "address": "123 Main St",
    "city": "Louisville",
    "state": "KY",
    "unit_count": 24
  },
  "counts": {
    "appliances": 8,
    "components": 52,
    "service_events": 14
  },
  "risk": {
    "critical": 3,
    "warning": 7,
    "good": 42,
    "overall_rating": "POOR"
  },
  "financials": {
    "total_deferred_maintenance": 14500,
    "total_reactive_exposure": 89200,
    "deferred_per_door": 604,
    "recommended_monthly_reserve_per_unit": 25
  },
  "assessed_at": "2026-04-20T14:30:00.000Z",
  "partner": "AppFolio"
}

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found or not accessible
  • 429 — Rate limit exceeded
GET /v1/property/{id}/report API KEY or OAuth

Comprehensive property report. Returns the full scoring breakdown: property info, per-appliance analysis with components grouped by risk tier, system category rollups, and financial projections. This is the data backing a Bank Origination or CNA report.

Path Parameters

ParamTypeDescription
idstringProperty ID

Request

curl https://platform.investwisecap.com/api/v1/property/P_abc123/report \
     -H "X-Api-Key: fv_live_XXX"

Response 200 (abridged)

{
  "property": { /* full property record */ },
  "overall": {
    "rating": "POOR",
    "nci_equivalent": 72,
    "components_assessed": 52
  },
  "categories": {
    "water_heater_gas": { "critical": 1, "warning": 2, "good": 3, "deferred": 2200 },
    "hvac_central": { "critical": 1, "warning": 3, "good": 8, "deferred": 5800 }
  },
  "critical": [
    {
      "component_id": "C_def456",
      "component_name": "Anode Rod",
      "appliance_type": "water_heater_gas",
      "risk_score": 0.847,
      "confidence": "HIGH",
      "age_years": 12,
      "projected_failure_year": 2026,
      "proactive_cost": 220,
      "reactive_cost": 1800
    }
  ],
  "warning": [ /* array of WARNING components */ ],
  "good": [ /* array of GOOD components */ ],
  "financials": {
    "total_deferred": 14500,
    "total_reactive_exposure": 89200,
    "deferred_per_door": 604,
    "estimated_savings_if_acted": 74700,
    "recommended_monthly_reserve_per_unit": 25
  },
  "assessed_at": "2026-04-20T14:30:00.000Z",
  "partner": "AppFolio"
}
REPORT BACKING This is the richest read endpoint. Every field surfaced here can be consumed by downstream reports: Bank Origination, CNA Report, Insurance Policy Inception, Deal Analyzer.

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
GET /v1/property/{id}/forecast API KEY or OAuth

30/60/90-day failure forecast. Returns components grouped into three time windows based on predicted failure likelihood. Designed for scheduling preventive maintenance crews and budgeting short-term capex.

Path Parameters

ParamTypeDescription
idstringProperty ID

Request

curl https://platform.investwisecap.com/api/v1/property/P_abc123/forecast \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "property_id": "P_abc123",
  "name": "Maple Ridge Apartments",
  "forecast": {
    "window_30_days": {
      "label": "Immediate — Act Within 30 Days",
      "component_count": 3,
      "proactive_cost": 850,
      "emergency_cost_if_ignored": 7200,
      "savings_potential": 6350,
      "components": [ /* ... */ ]
    },
    "window_60_days": {
      "label": "Near-Term — Schedule Within 60 Days",
      "component_count": 5,
      "proactive_cost": 1400,
      "emergency_cost_if_ignored": 9800,
      "savings_potential": 8400,
      "components": [ /* ... */ ]
    },
    "window_90_days": {
      "label": "Short-Term — Plan Within 90 Days",
      "component_count": 6,
      "proactive_cost": 2100,
      "emergency_cost_if_ignored": 12300,
      "savings_potential": 10200,
      "components": [ /* ... */ ]
    }
  },
  "generated_at": "2026-04-20T14:30:00.000Z",
  "partner": "AppFolio"
}

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
GET /v1/property/{id}/reserve API KEY or OAuth

Reserve fund recommendations. Returns four scheduling options (12-month, 24-month, 36-month, 10-year) for capital reserves. Designed for bank underwriting and HUD CNA filings — gives lenders and auditors a range of reserve strategies, each with monthly and annual figures per unit and property-wide.

Path Parameters

ParamTypeDescription
idstringProperty ID

Request

curl https://platform.investwisecap.com/api/v1/property/P_abc123/reserve \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "property_id": "P_abc123",
  "name": "Maple Ridge Apartments",
  "unit_count": 24,
  "total_deferred": 14500,
  "reserves": {
    "12_month": {
      "label": "Aggressive — Address All Deferred Within 1 Year",
      "per_unit_per_month": 50,
      "per_unit_per_year": 600,
      "property_per_month": 1200
    },
    "24_month": {
      "label": "Standard — Address All Deferred Within 2 Years",
      "per_unit_per_month": 25,
      "per_unit_per_year": 300,
      "property_per_month": 600
    },
    "36_month": {
      "label": "Conservative — Address All Deferred Within 3 Years",
      "per_unit_per_month": 17,
      "per_unit_per_year": 204,
      "property_per_month": 408
    },
    "10_year_full_replacement": {
      "label": "Long-Term — Full Replacement Fund Over 10 Years",
      "per_unit_per_month": 310,
      "per_unit_per_year": 3720,
      "property_per_month": 7440
    }
  },
  "generated_at": "2026-04-20T14:30:00.000Z",
  "partner": "AppFolue"
}

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
GET /v1/property/{id}/condition-score API KEY or OAuth

Single lender-friendly condition score. Returns a 1-100 numeric score with an A-F letter grade and an NSPIRE-style rating (GOOD / FAIR / FAIL — HUD's standardized inspection scale that replaced UPCS in 2023). Banks use this field directly in their underwriting workflow. One number, one grade — no interpretation required.

Path Parameters

ParamTypeDescription
idstringProperty ID

Request

curl https://platform.investwisecap.com/api/v1/property/P_abc123/condition-score \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "property_id": "P_abc123",
  "name": "Maple Ridge Apartments",
  "condition_score": 72,
  "grade": "C",
  "rating": "FAIL",
  "components_assessed": 52,
  "critical": 3,
  "warning": 7,
  "methodology": "ForVue Weibull-Bayesian composite score mapped to HUD NSPIRE-equivalent rating scale (0-100)",
  "assessed_at": "2026-04-20T14:30:00.000Z"
}

Grade Mapping

ScoreGradeRating
90–100AGOOD
80–89BGOOD or FAIR
70–79CFAIR or FAIL
60–69DFAIL
0–59FFAIL
DESIGNED FOR LENDERS A bank underwriter doesn't want to read 52 component scores. They want one number to put in their spreadsheet. This endpoint gives them that — backed by the full analysis but packaged for their workflow.

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
GET /v1/property/{id}/rcv API KEY or OAuth

Replacement Cost Valuation for insurance. Returns total replacement cost by system category, per-unit RCV, critical and warning exposure, and (when estimated_value is set on the property) deferred maintenance as a percentage of property value. Insurance carriers use this for coverage adequacy and claim reserve estimates.

Path Parameters

ParamTypeDescription
idstringProperty ID

Request

curl https://platform.investwisecap.com/api/v1/property/P_abc123/rcv \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "property_id": "P_abc123",
  "name": "Maple Ridge Apartments",
  "unit_count": 24,
  "total_replacement_cost": 89200,
  "rcv_per_unit": 3717,
  "critical_exposure": 7200,
  "warning_exposure": 9800,
  "systems": [
    { "system": "hvac_central", "total_rcv": 32000, "components": 16, "critical": 1, "warning": 3 },
    { "system": "water_heater_gas", "total_rcv": 18500, "components": 12, "critical": 1, "warning": 2 },
    { "system": "refrigerator", "total_rcv": 14200, "components": 8, "critical": 0, "warning": 1 }
  ],
  "estimated_value": 4200000,
  "deferred_as_pct_of_value": "0.3%",
  "assessed_at": "2026-04-20T14:30:00.000Z"
}

When deferred_as_pct_of_value Is Null

If the property record has no estimated_value field set, deferred_as_pct_of_value is returned as null. Set estimated_value on the property via PUT /v1/properties/{id} to populate this field.

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
GET /v1/property/{id}/compliance API KEY or OAuth

Mandatory inspection tracker. Returns compliance items (annual boiler inspections, elevator inspections, fire suppression certifications, etc.) with due dates sourced from NFPA 25, ASME A17.1, NEC, and state-level regulatory frameworks. Shows overdue, due-soon, upcoming, and OK status.

Path Parameters

ParamTypeDescription
idstringProperty ID

Request

curl https://platform.investwisecap.com/api/v1/property/P_abc123/compliance \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "property_id": "P_abc123",
  "name": "Maple Ridge Apartments",
  "compliance_items": [
    {
      "appliance_id": "A_elev01",
      "appliance_type": "elevator",
      "brand": "Otis",
      "inspection_type": "Annual Certification",
      "authority": "ASME A17.1",
      "mandatory": true,
      "interval_months": 12,
      "last_inspection": "2025-03-10",
      "due_date": "2026-03-10",
      "days_until_due": -41,
      "status": "OVERDUE"
    },
    {
      "appliance_id": "A_boil01",
      "appliance_type": "boiler",
      "inspection_type": "Annual Safety Inspection",
      "authority": "State boiler code",
      "mandatory": true,
      "interval_months": 12,
      "due_date": "2026-05-15",
      "days_until_due": 25,
      "status": "DUE_SOON"
    }
  ],
  "overdue": 1,
  "partner": "AppFolio"
}

Status Values

StatusWindow
OVERDUEdays_until_due < 0
DUE_SOON0 to 30 days
UPCOMING31 to 90 days
OK91+ days

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
GET /v1/property/{id}/claims API KEY or OAuth PAGINATED

List insurance claims for a property. Returns every insurance claim attached to this property, sorted by date of loss (newest first). Each claim records its type, date, amount, carrier, and the scoring impact multiplier it currently contributes.

Path Parameters

ParamTypeDescription
idstringProperty ID

Query Parameters

ParamTypeDefaultDescription
limitinteger50Records per page
offsetinteger0Records to skip

Request

curl https://platform.investwisecap.com/api/v1/property/P_abc123/claims \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "claims": [
    {
      "id": "CLM_abc123",
      "property_id": "P_abc123",
      "claim_type": "water_damage",
      "date_of_loss": "2024-09-15",
      "claim_number": "CLM-2024-0412",
      "carrier": "State Farm",
      "amount_paid": 4200,
      "description": "Water heater rupture flooded unit 3B",
      "status": "closed",
      "scoring_impact": 1.5,
      "created_at": "2024-10-01T10:00:00.000Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0,
  "property_id": "P_abc123",
  "partner": "AppFolio"
}

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
GET /v1/property/{id}/claims/impact API KEY or OAuth

Claims scoring impact with recency decay. For each claim on a property, returns the base likelihood ratio, the currently-effective likelihood ratio (after recency decay), the claim's age in years, and which appliance systems are affected. Use this to explain to underwriters exactly how much weight each claim carries in the risk score.

Path Parameters

ParamTypeDescription
idstringProperty ID

Request

curl https://platform.investwisecap.com/api/v1/property/P_abc123/claims/impact \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "property_id": "P_abc123",
  "name": "Maple Ridge Apartments",
  "total_claims": 2,
  "active_claims": 1,
  "expired_claims": 1,
  "claims": [
    {
      "claim_id": "CLM_abc123",
      "claim_type": "water_damage",
      "label": "Water Damage / Flooding",
      "date_of_loss": "2024-09-15",
      "age_years": 1.6,
      "base_likelihood_ratio": 1.5,
      "effective_likelihood_ratio": 1.34,
      "decay_remaining_years": 3.4,
      "status": "active_scoring",
      "affected_systems": [ "water_heater_gas", "plumbing_system" ],
      "affected_components_count": 11
    },
    {
      "claim_id": "CLM_def456",
      "claim_type": "fire_electrical",
      "age_years": 6.2,
      "base_likelihood_ratio": 1.4,
      "effective_likelihood_ratio": 1.0,
      "decay_remaining_years": 0,
      "status": "expired_no_impact"
    }
  ],
  "methodology": {
    "version": "1.0",
    "recency_decay": { "decay_years": 5 },
    "max_claims_scored": 3
  },
  "partner": "AppFolio"
}
WHY THIS MATTERS FOR INSURANCE Underwriters want to know exactly how claim history affects the risk assessment. This endpoint gives them an auditable view: claim by claim, what multiplier it contributed, when it will expire, and which systems it touches.

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
GET /v1/components API KEY or OAuth PAGINATED SANDBOX

List scored components. Returns components with current risk tier, risk score, and basic identifying metadata. Supports filtering by property, appliance, or risk tier. Useful for building tables of "everything at risk" across a portfolio or drilling into a specific appliance.

Query Parameters

ParamTypeDefaultDescription
property_idstringLimit to components at a specific property
appliance_idstringLimit to components of a specific appliance
tierstringCRITICAL · WARNING · GOOD
limitinteger50Records per page (max 200)
offsetinteger0Records to skip
sandboxstringtrue for demo data only

Request

curl "https://platform.investwisecap.com/api/v1/components?tier=CRITICAL" \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "components": [
    {
      "id": "C_def456",
      "component_name": "Anode Rod",
      "component_def_id": "wh_gas_anode",
      "appliance_id": "A_ghi789",
      "appliance_type": "water_heater_gas",
      "property_id": "P_abc123",
      "property_name": "Maple Ridge Apartments",
      "risk_score": 0.847,
      "risk_tier": "CRITICAL",
      "confidence": "HIGH",
      "age_years": 12,
      "projected_failure_year": 2026
    }
  ],
  "total": 47,
  "limit": 50,
  "offset": 0,
  "partner": "AppFolio"
}
COST FIELDS proactive_cost and reactive_cost are not included by default. Use GET /v1/property/{id}/report or /v1/property/{id}/rcv when you need financial figures.

Errors

  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
GET /v1/components/{id}/history API KEY or OAuth

Service event history for a single component. Returns every service event attached to this component (preventive maintenance, repairs, replacements, inspections) with dates, costs, technicians, and notes. Useful for auditing maintenance history before underwriting or due diligence.

Path Parameters

ParamTypeDescription
idstringComponent ID (e.g., C_def456)

Request

curl https://platform.investwisecap.com/api/v1/components/C_def456/history \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "component": {
    "id": "C_def456",
    "component_name": "Anode Rod",
    "appliance_id": "A_ghi789",
    "appliance_type": "water_heater_gas",
    "install_year": 2014,
    "last_replaced": null,
    "last_serviced": "2025-09-10"
  },
  "events": [
    {
      "id": "SE_001",
      "event_type": "Inspection",
      "date": "2025-09-10",
      "technician": "Mike Torres",
      "total_cost": 95,
      "notes": "Minor corrosion observed. Schedule replacement within 6 months.",
      "condition_after": "fair"
    }
  ],
  "total_events": 1,
  "partner": "AppFolio"
}

Errors

  • 401 — Missing or invalid credentials
  • 404 — Component not found
  • 429 — Rate limit exceeded
GET /v1/components/{id}/trend API KEY or OAuth PAGINATED

Daily risk score time series. Returns the component's risk score for each day it has been tracked (daily snapshot at 3 AM UTC). Retained for 365 days. Use this to plot a trend chart or detect sharp risk-score increases that may signal a cascading failure.

Path Parameters

ParamTypeDescription
idstringComponent ID

Query Parameters

ParamTypeDefaultDescription
limitinteger50Data points per page (max 200)
offsetinteger0Data points to skip

Request

curl "https://platform.investwisecap.com/api/v1/components/C_def456/trend?limit=90" \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "component_id": "C_def456",
  "trend": [
    { "date": "2026-01-20", "risk_score": 0.724, "risk_tier": "WARNING" },
    { "date": "2026-01-21", "risk_score": 0.728, "risk_tier": "WARNING" },
    { "date": "2026-02-15", "risk_score": 0.781, "risk_tier": "CRITICAL" },
    { "date": "2026-04-20", "risk_score": 0.847, "risk_tier": "CRITICAL" }
  ],
  "total": 90,
  "limit": 90,
  "offset": 0,
  "partner": "AppFolio"
}

Errors

  • 401 — Missing or invalid credentials
  • 404 — Component not found
  • 429 — Rate limit exceeded
GET /v1/alerts API KEY or OAuth PAGINATED SANDBOX

Active CRITICAL and WARNING components. Returns a single consolidated list of every at-risk component in the portfolio, sorted by risk score descending. The most direct query for "what needs attention right now" use cases.

Query Parameters

ParamTypeDefaultDescription
property_idstringLimit to alerts for one property
limitinteger50Records per page (max 200)
offsetinteger0Records to skip
sandboxstringtrue for demo data only

Request

curl https://platform.investwisecap.com/api/v1/alerts \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "alerts": [
    {
      "component_id": "C_def456",
      "component_name": "wh_gas_anode",
      "appliance_type": "water_heater_gas",
      "property_id": "P_abc123",
      "property_name": "Maple Ridge Apartments",
      "property_address": "123 Main St",
      "risk_score": 0.847,
      "risk_tier": "CRITICAL"
    }
  ],
  "total": 47,
  "limit": 50,
  "offset": 0,
  "critical_count": 12,
  "warning_count": 35,
  "partner": "AppFolio"
}

Errors

  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
GET /v1/events API KEY or OAuth PAGINATED

Change event stream (polling alternative to webhooks). See Section 10 for the full usage pattern and returned event types.

Query Parameters

ParamTypeRequiredDescription
sincestring (ISO 8601)RequiredReturns events after this timestamp
limitintegerOptionalDefault 50, max 200
offsetintegerOptionalDefault 0

Request

curl "https://platform.investwisecap.com/api/v1/events?since=2026-04-15T00:00:00Z" \
     -H "X-Api-Key: fv_live_XXX"

Errors

  • 400 — Missing since or invalid timestamp format
  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
GET /v1/appliances/{id}/photos API KEY or OAuth

Data plate photos for an appliance. Returns URLs to every photo captured for this appliance (brand/model/serial label photos uploaded during walk-throughs and photos attached to service events). Useful for insurance documentation, underwriting support, and visual audits.

Path Parameters

ParamTypeDescription
idstringAppliance ID

Request

curl https://platform.investwisecap.com/api/v1/appliances/A_ghi789/photos \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{
  "appliance_id": "A_ghi789",
  "type": "water_heater_gas",
  "brand": "Rheem",
  "model": "XG50T06EC36U1",
  "service_event_photos": [
    {
      "filename": "SE_001_1726920000000.jpg",
      "original_name": "data-plate.jpg",
      "url": "/api/uploads/SE_001_1726920000000.jpg",
      "uploaded_at": "2025-09-10T14:00:00.000Z",
      "service_event_id": "SE_001",
      "event_type": "Inspection",
      "event_date": "2025-09-10"
    }
  ],
  "appliance_photos": [],
  "total": 1
}
AUTH NOTE Photo URLs require the same authentication as the API. When embedding them, proxy through your server to pass the X-Api-Key header — never include credentials in an <img src> attribute.

Errors

  • 401 — Missing or invalid credentials
  • 404 — Appliance not found
  • 429 — Rate limit exceeded

Part IV — Endpoint Reference (Write)

Write endpoints create or modify resources. All write endpoints consume application/json request bodies. All support the Idempotency-Key header where noted. Write operations count against your daily rate limit.

POST /oauth/token PUBLIC (client credentials)

Exchange client credentials for a bearer token. This is the OAuth 2.0 client credentials flow. The issued token is valid for 1 hour and grants the same access scope as an API key.

Request Body

FieldTypeRequiredDescription
grant_typestringRequiredMust be "client_credentials"
client_idstringRequiredYour OAuth client ID
client_secretstringRequiredYour OAuth client secret

Request

curl -X POST https://platform.investwisecap.com/api/oauth/token \
     -H "Content-Type: application/json" \
     -d '{"grant_type":"client_credentials","client_id":"your_id","client_secret":"your_secret"}'

Response 200

{
  "access_token": "fvt_7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read write",
  "partner": "AppFolio"
}

Errors

  • 400grant_type is not client_credentials, or missing fields
  • 401 — Invalid client_id or client_secret
POST /v1/properties API KEY or OAuth IDEMPOTENT

Create a property. Registers a new property in the ForVue system. Units are auto-generated from unit_count. Use partner_property_id to store your system's ID for cross-referencing.

Request Body

FieldTypeRequiredDescription
namestringRequiredDisplay name
addressstringRequiredStreet address
statestringRequiredUS state abbreviation (e.g., KY)
citystringOptionalCity name
zipstringOptionalZIP code (used for EDI climate scoring)
unit_countintegerOptionalNumber of rental units (auto-creates unit records)
year_builtintegerOptionalConstruction year
notesstringOptionalFree-form notes
partner_property_idstringOptionalYour external system ID for cross-reference

Request

curl -X POST https://platform.investwisecap.com/api/v1/properties \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: appfolio-prop-12345-create" \
     -d '{
       "name": "Riverside Commons",
       "address": "456 River Rd",
       "city": "Louisville",
       "state": "KY",
       "zip": "40202",
       "unit_count": 16,
       "partner_property_id": "AF-PROP-12345"
     }'

Response 201

{
  "id": "P_xyz789",
  "name": "Riverside Commons",
  "address": "456 River Rd",
  "city": "Louisville",
  "state": "KY",
  "zip": "40202",
  "unit_count": 16,
  "partner_property_id": "AF-PROP-12345",
  "created_at": "2026-04-20T14:30:00.000Z"
}

Errors

  • 400 — Missing required fields (name, address, state)
  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
PUT /v1/properties/{id} API KEY or OAuth

Update a property. Merges the provided fields into the existing property record. Unspecified fields remain unchanged.

Request Body

Any field from the create endpoint. All fields are optional on update.

Request

curl -X PUT https://platform.investwisecap.com/api/v1/properties/P_xyz789 \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -d '{"estimated_value": 3800000, "notes": "Updated from AppFolio sync"}'

Response 200

Returns the full updated property object.

Errors

  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
POST /v1/appliances API KEY or OAuth IDEMPOTENT

Create an appliance. Adds a single appliance to a property. Components are automatically generated from the Knowledge Base based on type_id — no manual component creation needed. Scoring begins immediately.

Request Body

FieldTypeRequiredDescription
property_idstringRequiredParent property
type_idstringRequiredAppliance type from KB (see Appendix)
install_yearintegerRequiredYear appliance was installed
unit_numberstringOptionalUnit identifier (matched to existing unit record)
brandstringOptionalManufacturer name (matched to KB brand tiers)
modelstringOptionalModel number
serialstringOptionalSerial number
brand_tierstringOptionalpremium · standard · budget (default: standard)
usage_intensitynumberOptional0.5–2.0 (default: 1.0)
notesstringOptionalFree-form notes
partner_appliance_idstringOptionalYour external system ID

Request

curl -X POST https://platform.investwisecap.com/api/v1/appliances \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: appfolio-appl-unit3-hvac" \
     -d '{
       "property_id": "P_abc123",
       "type_id": "hvac_central",
       "install_year": 2016,
       "brand": "Carrier",
       "brand_tier": "premium",
       "unit_number": "3",
       "partner_appliance_id": "AF-EQUIP-789"
     }'

Response 201

{
  "appliance": {
    "id": "A_new123",
    "property_id": "P_abc123",
    "type_id": "hvac_central",
    "brand": "Carrier",
    "install_year": 2016,
    "brand_tier": "premium",
    "created_at": "2026-04-20T14:30:00.000Z"
  },
  "components": [
    { "id": "C_001", "component_def_id": "hvac_compressor" },
    { "id": "C_002", "component_def_id": "hvac_evap_coil" },
    { "id": "C_003", "component_def_id": "hvac_cond_coil" }
  ]
}
COMPONENTS AUTO-CREATED You never create components manually. When you add an appliance, ForVue automatically creates the correct component set from the Knowledge Base (e.g., HVAC Central → 8 components including compressor, evaporator coil, condenser coil, blower motor, heat exchanger, capacitor, thermostat, refrigerant lines).

Errors

  • 400 — Missing required fields (property_id, type_id, install_year)
  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
PUT /v1/appliances/{id} API KEY or OAuth

Update an appliance. Merges provided fields into the existing record. Useful for correcting brand, model, or install year after initial import. Scores recalculate automatically on the next scoring pass.

Request

curl -X PUT https://platform.investwisecap.com/api/v1/appliances/A_new123 \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -d '{"brand": "Carrier Infinity", "model": "24ACC636A003"}'

Response 200

Returns the full updated appliance object.

Errors

  • 401 — Missing or invalid credentials
  • 404 — Appliance not found
  • 429 — Rate limit exceeded
DELETE /v1/appliances/{id} API KEY or OAuth

Delete an appliance. Permanently removes an appliance and all its components, risk snapshots, and associated data. This action is irreversible.

Request

curl -X DELETE https://platform.investwisecap.com/api/v1/appliances/A_new123 \
     -H "X-Api-Key: fv_live_XXX"

Response 200

{ "ok": true }
IRREVERSIBLE Deletion cascades to all components, risk snapshots, and service events for this appliance. Consider updating instead of deleting in most sync scenarios.

Errors

  • 401 — Missing or invalid credentials
  • 404 — Appliance not found
  • 429 — Rate limit exceeded
POST /v1/appliances/bulk API KEY or OAuth IDEMPOTENT

Bulk-create appliances for a single property. Accepts up to 100 appliances per call. Partial success is supported — successful records are created and failed records are returned with error details so you can fix and retry.

Request Body

FieldTypeRequiredDescription
property_idstringRequiredTarget property (applies to all appliances in batch)
appliancesarrayRequiredArray of appliance objects (max 100)

Request

curl -X POST https://platform.investwisecap.com/api/v1/appliances/bulk \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: appfolio-bulk-prop-abc123-2026-04-20" \
     -d '{
       "property_id": "P_abc123",
       "appliances": [
         {"type_id":"hvac_central","brand":"Carrier","install_year":2018,"unit_number":"1"},
         {"type_id":"water_heater_gas","brand":"Rheem","install_year":2015,"unit_number":"1"},
         {"type_id":"refrigerator","brand":"LG","install_year":2020,"unit_number":"1"}
       ]
     }'

Response 201

{
  "created": 3,
  "errors": 0,
  "appliances": [
    { "id": "A_001", "type_id": "hvac_central" },
    { "id": "A_002", "type_id": "water_heater_gas" },
    { "id": "A_003", "type_id": "refrigerator" }
  ],
  "error_details": []
}

Partial Success Response

{
  "created": 2,
  "errors": 1,
  "appliances": [ /* 2 created records */ ],
  "error_details": [
    { "index": 1, "error": "type_id required" }
  ]
}
FASTEST WAY TO SYNC During initial onboarding or nightly syncs, prefer /appliances/bulk over many individual POST /v1/appliances calls. One bulk call uses one rate-limit quota slot; 100 individual calls use 100.

Errors

  • 400 — Missing property_id or appliances array; array exceeds 100
  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
PUT /v1/properties/bulk API KEY or OAuth

Bulk-update properties. Accepts up to 50 property updates per call. Each entry must include an id; remaining fields are merged into the existing record. Unrecognized IDs are returned as errors.

Request Body

FieldTypeRequiredDescription
propertiesarrayRequiredArray of property update objects (max 50)

Each object in properties must have:

  • id (required) — the property to update
  • Any subset of property fields to merge

Request

curl -X PUT https://platform.investwisecap.com/api/v1/properties/bulk \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -d '{
       "properties": [
         {"id":"P_abc123","estimated_value":4200000},
         {"id":"P_def456","unit_count":32,"estimated_value":6500000}
       ]
     }'

Response 200

{
  "updated": 2,
  "errors": 0,
  "properties": [ /* 2 updated records */ ],
  "error_details": []
}

Errors

  • 400 — Missing properties array; array exceeds 50
  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
POST /v1/service-events/bulk API KEY or OAuth IDEMPOTENT

Bulk-import service events. Accepts up to 100 service events per call. Essential for syncing historical work-order data from property management software. Events fire the service_event.created webhook. Events that reset a component's age clock (event_type: "Replacement") trigger immediate re-scoring.

Request Body

FieldTypeRequiredDescription
eventsarrayRequiredArray of service event objects (max 100)

Each event object requires:

FieldTypeRequiredDescription
appliance_idstringRequiredTarget appliance
event_typestringRequiredSee Section 7.2 for valid values
datestring (YYYY-MM-DD)RequiredEvent date
component_idstringOptionalSpecific component (scopes event to one part)
technicianstringOptionalTechnician or vendor name
parts_costnumberOptionalParts cost in USD
labor_costnumberOptionalLabor cost in USD
notesstringOptionalFree-form notes (scanned for risk keywords)
condition_afterstringOptionalgood · fair · poor

Request

curl -X POST https://platform.investwisecap.com/api/v1/service-events/bulk \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: appfolio-workorders-2026-04-batch1" \
     -d '{
       "events": [
         {
           "appliance_id": "A_ghi789",
           "event_type": "Preventive Maintenance",
           "date": "2026-03-15",
           "technician": "ABC Plumbing",
           "parts_cost": 85, "labor_cost": 210,
           "notes": "Annual water heater flush and anode inspection"
         },
         {
           "appliance_id": "A_new123",
           "event_type": "Repair",
           "date": "2026-04-02",
           "parts_cost": 0, "labor_cost": 150,
           "notes": "HVAC blower motor capacitor replaced"
         }
       ]
     }'

Response 201

{
  "created": 2,
  "errors": 0,
  "events": [
    { "id": "SE_new001", "event_type": "Preventive Maintenance", "total_cost": 295 },
    { "id": "SE_new002", "event_type": "Repair", "total_cost": 150 }
  ],
  "error_details": []
}
REPLAYING HISTORY IMPROVES SCORES Historical service events — especially Replacement, Preventive Maintenance, and Inspection — improve scoring accuracy by providing Bayesian evidence and condition observations. Importing 3+ years of work orders is a meaningful accuracy gain.

Errors

  • 400 — Missing events array; array exceeds 100
  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
POST /v1/property/{id}/claims API KEY or OAuth IDEMPOTENT

Import insurance claims for a property. Accepts a batch of claims that feed into the Bayesian scoring engine as evidence of elevated system-specific risk. Recency decay applies: claims older than 5 years contribute no scoring impact.

Path Parameters

ParamTypeDescription
idstringProperty ID

Request Body

FieldTypeRequiredDescription
claimsarrayRequiredArray of claim objects

Each claim object requires:

FieldTypeRequiredDescription
claim_typestringRequiredOne of: water_damage, fire_electrical, hvac_mechanical, roof_weather, appliance_liability, general_property
date_of_lossstring (YYYY-MM-DD)RequiredDate the loss occurred
claim_numberstringOptionalCarrier's claim number
carrierstringOptionalInsurance carrier name
amount_paidnumberOptionalPaid amount in USD
descriptionstringOptionalFree-form description
statusstringOptionalopen · closed (default: closed)

Request

curl -X POST https://platform.investwisecap.com/api/v1/property/P_abc123/claims \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: statefarm-import-P_abc123-batch3" \
     -d '{
       "claims": [
         {
           "claim_type": "water_damage",
           "date_of_loss": "2024-09-15",
           "claim_number": "CLM-2024-0412",
           "carrier": "State Farm",
           "amount_paid": 4200,
           "description": "Water heater tank rupture, unit 3B flooded",
           "status": "closed"
         }
       ]
     }'

Response 201

{
  "created": 1,
  "errors": 0,
  "claims": [
    {
      "id": "CLM_new001",
      "claim_type": "water_damage",
      "date_of_loss": "2024-09-15",
      "scoring_impact": 1.5,
      "created_at": "2026-04-20T14:30:00.000Z"
    }
  ],
  "error_details": []
}
ACCURACY WARRANT By submitting claims data, the importing partner warrants accuracy and legal authority to share the data, per Terms of Service §4.6 and §6.7. ForVue does not independently verify claims. Never submit speculative or unverified claim data — it skews scoring.

Errors

  • 400 — Missing claims array or invalid claim_type
  • 401 — Missing or invalid credentials
  • 404 — Property not found
  • 429 — Rate limit exceeded
POST /v1/meter-event API KEY or OAuth IDEMPOTENT

Submit a raw sensor or meter event. The simplest IoT ingestion endpoint — records the event and triggers re-scoring of the affected appliance's components. Use when you already know the property_id and appliance_id.

Request Body

FieldTypeRequiredDescription
event_typestringRequiredOne of the 9 service event types, or a sensor-specific type (e.g., "Leak Detected")
property_idstringOptional*Target property (required if no address)
appliance_idstringOptionalTarget appliance (if known)
addressstringOptional*Property address (required if no property_id)
sensor_valuenumberOptionalRaw reading from sensor
unitstringOptionalMeasurement unit (e.g., "PSI", "°F", "gallons")
notesstringOptionalFree-form description from the sensor or installer
partner_property_idstringOptionalYour external ID for cross-reference

Request

curl -X POST https://platform.investwisecap.com/api/v1/meter-event \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: sensor-device-A7F2-event-1713620400" \
     -d '{
       "property_id": "P_abc123",
       "appliance_id": "A_ghi789",
       "event_type": "Pressure Spike",
       "sensor_value": 145,
       "unit": "PSI",
       "notes": "Pressure sensor reading exceeded safe threshold"
     }'

Response 201

{
  "event_id": "PE_001",
  "property_id": "P_abc123",
  "appliance_id": "A_ghi789",
  "event_type": "Pressure Spike",
  "recorded_at": "2026-04-20T14:30:00.000Z"
}

Errors

  • 400 — Missing event_type or neither property_id nor address provided
  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
POST /v1/meter-event/smart API KEY or OAuth IDEMPOTENT

Smart meter event with auto-creation. The full IoT ingestion flow — if the target property or appliance doesn't exist, ForVue creates them from the address and appliance metadata you provide. This means a sensor can be installed first and register itself on first read. Returns an immediate risk summary after re-scoring.

Request Body

FieldTypeRequiredDescription
addressstringRequiredProperty address — used to locate or create the property
statestringRequiredUS state abbreviation
event_typestringRequiredEvent type (service event or sensor-specific)
city, zipstringOptionalSupplementary address fields (improve EDI scoring if included)
unit_countintegerOptionalUnit count if a new property is being created
unit_numberstringOptionalSpecific unit for the appliance
appliance_type_idstringOptionalKB appliance type (auto-creates appliance if not found)
appliance_brandstringOptionalBrand (fuels auto-create)
appliance_install_yearintegerOptionalInstall year (fuels auto-create)
sensor_value, unit, notesvariousOptionalSensor metadata (same as basic meter event)
partner_property_id, partner_appliance_idstringOptionalYour external IDs

Request

curl -X POST https://platform.investwisecap.com/api/v1/meter-event/smart \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: sensor-XYZ123-reading-2026-04-20T14:30" \
     -d '{
       "address": "789 Oak Ave",
       "city": "Louisville",
       "state": "KY",
       "zip": "40203",
       "unit_count": 12,
       "unit_number": "2",
       "appliance_type_id": "water_heater_gas",
       "appliance_brand": "Rheem",
       "appliance_install_year": 2018,
       "event_type": "Leak Detected",
       "sensor_value": 1,
       "unit": "binary",
       "notes": "Moisture sensor triggered under water heater"
     }'

Response 201

{
  "event_id": "PE_002",
  "property": {
    "id": "P_auto001",
    "address": "789 Oak Ave",
    "was_created": true
  },
  "appliance": {
    "id": "A_auto002",
    "type_id": "water_heater_gas",
    "was_created": true
  },
  "risk_summary": {
    "components_scored": 6,
    "critical_count": 2,
    "warning_count": 2,
    "good_count": 2
  },
  "recorded_at": "2026-04-20T14:30:00.000Z"
}
WHEN TO USE Use the smart variant when sensors deploy before properties are registered in ForVue. The event itself bootstraps the property and appliance records. Ideal for IoT vendors whose installers work faster than operator onboarding.

Errors

  • 400 — Missing address, state, or event_type
  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded
POST /v1/meter-event/smart/v2 API KEY or OAuth IDEMPOTENT

Smart meter v2 — adds callbacks and webhooks. Identical to /v1/meter-event/smart but additionally: (a) fires sensor.smart, property.created, appliance.created, and component-tier webhooks to all subscribed partners; (b) optionally invokes a one-time callback URL supplied in the request.

Additional Request Fields

FieldTypeRequiredDescription
callback_urlstringOptionalOne-time HTTPS URL that receives the response payload after processing

The callback is signed using the same HMAC-SHA256 scheme as webhooks (see Section 9). The callback fires asynchronously; the HTTP response is returned immediately.

Request

curl -X POST https://platform.investwisecap.com/api/v1/meter-event/smart/v2 \
     -H "X-Api-Key: fv_live_XXX" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: sensor-XYZ123-reading-v2-2026-04-20" \
     -d '{
       "address": "789 Oak Ave",
       "state": "KY",
       "event_type": "Leak Detected",
       "appliance_type_id": "water_heater_gas",
       "appliance_install_year": 2018,
       "callback_url": "https://sensors.partner.com/forvue-ack/XYZ123"
     }'

Response 201

Same shape as /v1/meter-event/smart. Same payload is also POSTed to callback_url (when provided) and broadcast via webhooks.

WEBHOOK FAN-OUT A single smart v2 call can trigger up to 4 webhook events (sensor.smart, property.created, appliance.created, and per-component component.critical/component.warning events). Design your webhook receiver to dedupe by event_id + component_id.

Errors

  • 400 — Missing required fields
  • 401 — Missing or invalid credentials
  • 429 — Rate limit exceeded

12Security & Competitive Use

This section exists because ForVue's scoring engine, Knowledge Base, brand-tier tables, likelihood-ratio mappings, and cascade rules are the result of years of calibration against ASHRAE, HUD, NAHB, NFPA, ISO, IBHS, and manufacturer data. They are a material trade secret and a core competitive advantage. Partners who gain access to the API accept specific obligations to protect this information.

12.1 Data Protection Obligations

As an API Partner, you agree to:

12.2 Restrictions on Data Use

Per the Partnership Agreement and Terms of Service §6.8, you may not:

12.3 No Competitive Use (2-Year Survival)

MATERIAL COVENANT No API Partner, its affiliates, or any entity under common ownership or control may use access to the Platform, its data, its methodology, or any knowledge gained through the API partnership to develop, market, sell, or operate a product or service that competes with ForVue's predictive maintenance intelligence capabilities. This restriction survives termination of the Partnership Agreement for a period of two (2) years.

A "competing product or service" includes, without limitation: any software that produces appliance-level or component-level failure probability scores, any system that generates reserve recommendations or Capital Needs Assessments derived from predictive failure modeling, and any integration that replicates ForVue's Weibull-Bayesian methodology on real estate or facility data.

12.4 Monitoring and Enforcement

ForVue retains logs of every authenticated API call including timestamp, partner identity, endpoint, response time, and response status. These logs are used for:

Suspicious access patterns — including but not limited to systematic pagination across all properties, repeated fetches of the same component, or unusual geographic distribution of source IPs — trigger automatic alerts to the Wise Capital security team. Persistent violations result in immediate credential revocation.

12.5 Termination & Data Deletion

Upon termination of your Partnership Agreement (for any reason):

12.6 Intellectual Property Notices

Reports generated through the API (Bank Origination, Insurance Policy Inception, HUD CNA, Deal Analysis) include ForVue branding, patent notice (USPTO App. 64/032,704), and methodology citation. Partners distributing these Reports to third parties must preserve these notices intact. You may not remove attribution to Wise Capital or present Reports as your own work product.

13Appendix & Contact

13.1 Appliance Type Reference

Valid values for type_id when creating appliances. The Knowledge Base ships with 30 appliance types covering 169 components today; the full set of supported type_ids is listed below. The KB itself (component lifespans, manufacturer service bulletin lookups, error-code library, parts catalog) is updated in place; the public type_id list is stable.

type_idDisplay NameSystem Category
hvac_centralCentral HVACHVAC
hvac_heat_pumpHeat PumpHVAC
hvac_mini_splitMini-Split / Ductless HVACHVAC
water_heater_gasGas Water HeaterPlumbing
water_heater_electricElectric Water HeaterPlumbing
water_heater_tanklessTankless Water HeaterPlumbing
boilerBoilerHVAC
wall_furnaceWall FurnaceHVAC
electric_baseboardElectric Baseboard HeaterHVAC
refrigeratorRefrigeratorAppliance
washerClothes WasherAppliance
dryerClothes DryerAppliance
dishwasherDishwasherAppliance
oven_rangeOven / RangeAppliance
microwaveMicrowaveAppliance
garbage_disposalGarbage DisposalPlumbing
sump_pumpSump PumpPlumbing
plumbing_systemPlumbing SystemPlumbing
electrical_panelElectrical PanelElectrical
gfci_outletsGFCI OutletsElectrical
smoke_detectorSmoke / CO DetectorSafety
fire_suppressionFire Suppression SystemSafety
elevatorElevatorMechanical
pool_equipmentPool / Spa EquipmentAmenity
roofRoofStructure
garage_doorGarage DoorMechanical
water_softenerWater Softener / FiltrationPlumbing
window_acWindow AC UnitHVAC
ductworkDuctwork SystemHVAC

Additional types may be added in future Knowledge Base versions. Always check GET /kb/appliance-types (available via admin endpoints) for the current authoritative list.

13.2 Claim Type Reference

claim_typeDescriptionAffected SystemsBase LR
water_damagePlumbing leaks, burst pipes, appliance leaksPlumbing, water heaters, washer1.50
fire_electricalElectrical fires, panel failures, wiringElectrical panel, dryer, HVAC1.45
hvac_mechanicalHVAC system failures, compressor lossHVAC, heat pump, boiler1.35
roof_weatherStorm damage, hail, wind, leaks from roofRoof, attic, ceiling damage1.40
appliance_liabilityAppliance-caused damage or injuryAll major appliances1.25
general_propertyStructural, fixture, or other property damageAll systems (weak signal)1.15

Likelihood ratios decay linearly from the base value to 1.0 over 5 years from the date of loss. Only the 3 most recent claims per property contribute to scoring.

13.3 Event Type Quick Reference

event_typeEffect on ScoringWebhooks Fired
Preventive MaintenanceMay lower risk on at-risk componentsservice_event.created
InspectionNeutral; improves confidenceservice_event.created
Filter ChangePositive (HVAC/water specific)service_event.created
CleaningPositiveservice_event.created
RepairAdds recent-repair risk factorservice_event.created
ReplacementResets age clock; re-scoresservice_event.created, possible component.recovered
Emergency RepairHigh-weight failure signalservice_event.created, possible tier changes
Warranty ClaimNeutral; informationalservice_event.created
OtherNeutral; informationalservice_event.created

13.4 Document & API Versioning

This document is version 2.0 of the reference (July 9, 2026), describing ForVue Partner API v1. Future versions will:

The authoritative machine-readable spec is at GET /v1/openapi.json. If any detail in this reference conflicts with the live OpenAPI spec, the spec wins.

13.4.1 Changelog — v1.0 (April 2026) → v2.0 (July 9, 2026)

BREAKING RESPONSE-SHAPE CHANGE — NUMERIC AND BIGINT FIELDS As of July 9, 2026, response bodies return PostgreSQL NUMERIC, DECIMAL, BIGINT, and INT8 fields as JSON numbers, not JSON strings. This applies to every dollar amount, risk score, unit count, and count field returned by any /v1 endpoint. If your integration parses these fields with parseFloat() or parseInt(), no change is required. If your integration compares any of these fields to string literals (e.g. value === "2.50") or concatenates them expecting string semantics, update to number semantics before consuming v2 responses. Verify with a call to any endpoint returning a monetary field (for example GET /v1/property/{id}/reserve).

Other v1.0 → v2.0 changes:

13.5 Support & Contact

ReasonContactExpected Response
Credentials, onboarding, partnership termswise@investwisecap.comWithin 2 business days
API bug reports or unexpected behaviorwise@investwisecap.comWithin 1 business day
Suspected credential compromisewise@investwisecap.comWithin 24 hours — escalate urgent
Webhook delivery issueswise@investwisecap.comWithin 1 business day
Rate limit increase requestswise@investwisecap.comBusiness agreement required

13.6 Document Control

FieldValue
DocumentForVue Partner API Reference
Version2.0
EffectiveJuly 9, 2026
PublisherWise Capital, LLC · Louisville, Kentucky
PatentUSPTO Application 64/032,704 (pending)
Copyright© 2026 Wise Capital, LLC. All rights reserved.
ClassificationConfidential & Proprietary — for authorized API Partners only
END OF DOCUMENT This document is provided to API Partners under the terms of an executed Partnership Agreement. Distribution outside the Partner's integration team requires written permission from Wise Capital. The information herein is confidential and protected by trade secret, copyright, and patent law.