Skip to main content
8 min read

Destinations

The canonical schema doesn’t know what your CRM property is called or how long the value can be. Destinations are per-org routing rules that take a field your enrichment produced — canonical or custom — and land it in a specific CRM property with the constraints that property demands.

What makes something a destination

A destination answers one question: where does this field land in your CRM? The value itself is produced during enrichment — by the canonical pipeline or by your custom field instructions. The destination is the pass-through that routes it to the property you name.

Destinations don’t fetch new evidence and don’t add an LLM step. They route what enrichment has already produced — and the landed value is constrained to fit (max-chars, must-be-integer, must-match-enum). One value per enrichment per destination, cached against the config version.

Routes from

Exactly one source field: an org custom field (source_custom_field) or a canonical enrichment field (source_canonical_field).

Writes to

halo.enrichment_destination_values. Each row carries the composed value, its citations, the LLM cost, and the validation outcome.

Validates against

max_chars, must_be_integer, must_match_enum — applied to the routed value before it lands.

One mode: route

Every destination is a mode: routepass-through. When a matching enrichment completes, the named source field’s value is validated against the destination’s constraints and landed in the CRM property — no extra LLM call, no extra cost beyond the enrichment itself. If the shape of the value should change, change the custom field’s instructions; the destination just carries it.

The shape of a destination value

Cached destination values carry the same provenance contract as source: citations, cost, and the inputs the value was produced from.

{
  "config_id": 17,
  "config_name": "outbound_angle",
  "config_version": 1,
  "applies_to": "company",
  "crm_platform": "hubspot",
  "crm_property": "abm_outbound_angle",
  "value": "Cooper Parry's recent push into AI-enabled audit and the new Manchester hub make them a fit for our pre-IPO compliance motion. Lead with the partner team rotation, not the engineering hire.",
  "validation": {
    "ok": true,
    "constraint": "max_chars: 240",
    "value_length": 217
  },
  "composed_from": {
    "source_blocks": ["identity", "leadership_team_synthesis", "size_growth_health"],
    "events": [],
    "research_angles": []
  },
  "citations": [
    "https://www.cooperparry.com/about/recent-news",
    "https://www.linkedin.com/company/cooper-parry/posts"
  ],
  "resolved_at": "2026-05-14T09:23:17Z"
}

Working with destinations

# List for the org (org comes from your API key / token)
curl https://api.abm.dev/api/v2/destinations \
  -H 'X-API-Key: YOUR_API_KEY'

# Create one — route a produced field to a CRM property
curl -X POST https://api.abm.dev/api/v2/destinations \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "entity_type": "company",
    "crm_platform": "hubspot",
    "crm_property": "abm_icp_fit_score",
    "mode": "route",
    "source_custom_field": "icp_fit_score",
    "output_constraints": { "must_be_integer": [0, 100] }
  }'

# Read cached values for an enrichment
curl https://api.abm.dev/api/v2/enrichments/{enrichment_id}/destinations \
  -H 'X-API-Key: YOUR_API_KEY'

Keep reading