Public
BAM Property Enrichment API proxy endpoints
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

bam-api

Property-enrichment proxies for BAM (Building Asset Management). Separate project from Guardian OS golden path — do not entangle.

Three independent HTTP endpoints, one per enrichment source. CORS open (*) because called from the Lovable BAM frontend.

Endpoints

enrich-contact.ts — EnformionGO Contact Enrich

POST https://guardianengr--9e338dd61b8e11f1967a42dde27851f2.web.val.run

Waterfall: Contact Enrich → swap first/last (FL NAL format: LASTNAME FIRSTNAME) → Address ID → re-enrich with corrected name. Returns the first successful match with matchMethod set to contact_enrich | contact_enrich_swapped | address_id_then_enrich | address_id_only | no_match.

Request:

{ "firstName": "JOHN", "lastName": "SMITH", "addressLine1": "123 MAIN ST", "addressLine2": "FORT MYERS FL 33901", "parcelId": "12-34-45-..." }

Response (match):

{ "person": { "emails": [...], "phones": [...], ... }, "matchMethod": "contact_enrich", "parcelId": "12-34-45-...", "identityScore": 95 }

Auth: EnformionGO uses custom galaxy-ap-name + galaxy-ap-password headers (NOT Bearer).

validate-email.ts — QuickEmailVerification

POST https://guardianengr--9e5731461b8e11f181dc42dde27851f2.web.val.run

Request: { "email": "user@example.com" }

Response:

{ "email": "user@example.com", "result": "valid | invalid | unknown", "safe_to_send": "true", // STRING, not boolean "accept_all": "false", "disposable": "false", "role": "false", "free": "false", "reason": "accepted_email", "domain": "example.com", "remaining_credits": "12345" }

CRITICAL: All boolean-like QEV fields are returned as strings ("true" / "false"). Frontend must compare string-wise.

verify-phone.ts — Telnyx Number Lookup

POST https://guardianengr--9f9ffb461b8e11f189d442dde27851f2.web.val.run

Request: { "phone": "2395551234" } (any format — normalized to E.164 internally)

Response:

{ "phone": "+12395551234", "lineType": "mobile | landline | voip | unknown", "carrier": "T-Mobile USA", "valid": true, "callerName": "SMITH JOHN", "nationalFormat": "(239) 555-1234", "portedStatus": "ported | not_ported | ...", "city": "Fort Myers", "state": "FL" }

Line-type classification: checks portability.line_type first (most reliable), falls back to carrier.type.

Environment variables

VarUsed by
ENFORMION_AP_NAMEenrich-contact
ENFORMION_AP_PASSWORDenrich-contact
QEV_API_KEYvalidate-email
TELNYX_API_KEYverify-phone

CORS pattern

All three endpoints manually set CORS_HEADERS on every response (including errors). This overrides Val.town defaults — any header here means no default CORS is added. Keep consistent across endpoints.

Cost considerations

  • EnformionGO: charges per Contact/Enrich call — waterfall can cost 3x (step1 + step2 swap + step3 re-enrich). Cache results aggressively in BAM frontend.
  • QEV: credit-based, returns 402 on exhaustion and 429 on rate limit.
  • Telnyx: per-lookup billing.

Companion vals (out of scope for Guardian OS refactors per val-refactoring-index.md): bam-backfill, bam-entity-detect, bam-golden-path-check, bam-martin-test.