APN Sync — Field Mapping
This page documents the complete bidirectional mapping between HubSpot deal properties and AWS Partner Central opportunity fields.
Field ownership
HubSpot owns — FlowState reads this field from HubSpot and writes it to APN. Inbound APN events never overwrite this field on the HubSpot side.
AWS owns — FlowState reads this field from APN inbound events and writes it to HubSpot. Outbound sync never sends a value for this field to APN.
Both can update — either side can update this field. When both sides have been changed since the last sync, FlowState sets apn_sync_status = conflict and surfaces a conflict for manual resolution. closedate, apn_mrr, and apn_postal_code are all genuinely dual-owned this way: the partner edits them to drive APN, and AWS revises them on its own side (a re-forecast spend, an address correction, a date the AWS reviewer pushed out). A synced baseline (the last value both sides agreed on) tells one side’s edit apart from a real two-sided conflict, so neither an AWS revision nor a pending partner edit is ever silently clobbered — see Conflicts & resolution.
Native amount is never written by AWS. apn_mrr is the field that mirrors AWS’s expected-spend figure in both directions; your deal’s native amount property is your own CRM value and an inbound APN event never touches it, under any circumstances.
Watched (reported via a deal-timeline note) — a small set of fields AWS is known to
change after the opportunity already exists. Every AWS-side change to one of these
produces a note — whether or not FlowState also wrote the value into the deal. A
dual-owned field (apn_mrr, apn_postal_code, closedate) IS written when the
three-way merge above sides with AWS, and the note says so (“updated on your deal, no
action needed”); a HubSpot-owned field is never written (AWS is not the system of record
for the partner’s own CRM data — same rule as LifeCycle.Stage advancing on the AWS
side, which never moves the HubSpot dealstage either) and the note says that instead
(“left as AWS’s own data — your call”). See “AWS-side changes reported via note” below
for the full list and the reasoning behind each one.
Standard HubSpot deal properties
These standard properties exist in HubSpot without any custom provisioning.
| HubSpot property | HubSpot type | APN field | Ownership | Notes |
|---|---|---|---|---|
dealname | Text | Project.Title | HubSpot owns | Required for APN submission. |
closedate | Date | LifeCycle.TargetCloseDate | Both can update | ISO 8601 date format. Conflict-detected. |
dealstage | Dropdown | LifeCycle.Stage | Both can update | Mapped via stage configuration (see below). Conflict-detected. |
| (contacts association) | Association | Customer.Contacts[] | — not currently synced | Not yet live: FlowState does not currently send contacts on the APN opportunity, regardless of what’s associated with the deal in HubSpot. |
Custom properties in the flowstate_apn group
These 10 properties are provisioned by FlowState in your HubSpot portal. Nine fields this
table used to list — apn_partner_need, apn_use_case, apn_delivery_model,
apn_sales_activity, apn_state_region, apn_client_industry, apn_client_country,
apn_currency and apn_submission_type — are gone: they moved to the FlowState card’s
“AWS deal fields” form, backed by FlowState’s own store rather than a HubSpot property. The
mapping for those nine fields (still keyed by the same names) is documented in “Fields
moved off HubSpot properties” further down, since the HubSpot property column no longer
applies to them.
| HubSpot property | HubSpot type | APN field | Ownership |
|---|---|---|---|
apn_sync_with_aws_enabled | Boolean | — (gate, not synced) | HubSpot owns |
apn_opportunity_id | Text | Opportunity.Id | AWS owns (mirror, write-once) |
apn_sync_status | Dropdown | — (FlowState status) | FlowState writes |
apn_review_status | Dropdown | LifeCycle.ReviewStatus | AWS owns (mirror) |
apn_lifecycle_stage | Dropdown | LifeCycle.Stage echo | AWS owns (inbound mirror only) |
apn_closed_lost_reason | Dropdown | LifeCycle.ClosedLostReason | HubSpot owns |
apn_business_problem | Multi-line text | Project.CustomerBusinessProblem | HubSpot owns |
apn_postal_code | Text | Customer.Account.Address.PostalCode | Both can update — also watched; see below |
apn_aws_account_id | Text | Customer.Account.AwsAccountId | HubSpot owns (accepted through on an Approved opp only when the proposed Stage is Launched) |
apn_mrr | Number | ExpectedCustomerSpend.Amount (Monthly) | Both can update — also watched; see below |
| (none — derived) | — | ExpectedCustomerSpend.Frequency | Always Monthly; AWS accepts no other value, so the mapper sets it. Not a HubSpot property. |
apn_postal_code and apn_mrr are the only two of the original nine rep-authored,
non-status fields that stayed provisioned: both are genuinely dual-owned (AWS revises
them directly — a re-forecast spend, an address correction — and FlowState mirrors that
revision straight into the HubSpot property), so nothing else can absorb that live
write-back the way apn_fields absorbed the other nine, HubSpot-owned-only fields.
The AWS account manager, sales rep, partner sales manager, and AWS’s own next step are
not provisioned as HubSpot properties — FlowState tracks them internally for change
detection only, and the HubSpot card reads the same data live to render them. AWS’s own
next step still posts a deal-timeline note on each change (see “Next step mapping” below).
The last sync error is likewise not provisioned as a property (the retired
apn_sync_last_error) — it is read live from the deal’s sync state via the card’s
syncError field.
Fields moved off HubSpot properties
These nine fields are rep-authored on the FlowState card’s “AWS deal fields” form instead
of a HubSpot dropdown or checkbox. The mapping to their APN field is unchanged — only
where the value lives changed, from a HubSpot property to the apn_fields map.
| Card field key | APN field | Ownership | Notes |
|---|---|---|---|
apn_partner_need | PrimaryNeedsFromAws[] | HubSpot owns | — |
apn_use_case | Project.CustomerUseCase | HubSpot owns | Also watched; see below. |
apn_delivery_model | Project.DeliveryModels[] | HubSpot owns | Also watched; see below. |
apn_sales_activity | Project.SalesActivities[] | HubSpot owns | Also watched; see below. |
apn_state_region | Customer.Account.Address.StateOrRegion | HubSpot owns | — |
apn_client_industry | Customer.Account.Industry | HubSpot owns | Also watched; see below. Inferred by FlowState where it can be: the deal’s own value, then the associated company’s industry, then an AI-inferred guess. The first two count only on exact membership of AWS’s enum — HubSpot’s industry picklist and AWS’s are unrelated vocabularies, so a company value is never mapped onto it. The card shows a rep-authored select field only when all three come up empty. |
apn_client_country | Customer.Account.Address.CountryCode | HubSpot owns | Card shows this read-only, derived live from the associated HubSpot company. |
apn_currency | ExpectedCustomerSpend.CurrencyCode | HubSpot owns | — |
apn_submission_type | AwsSubmission.{InvolvementType,Visibility} | HubSpot owns | Read at submit time by the outbound writer, not part of the Opportunity payload itself. |
An opportunity accepted from AWS still pre-populates all nine on deal creation — into FlowState’s own store, not a HubSpot property.
Next step mapping
A “next step” travels in each direction, and neither ever overwrites the other:
| Direction | Carrier | APN field |
|---|---|---|
| HubSpot → AWS | hs_next_step (native “Next step” property) | LifeCycle.NextSteps |
| AWS → HubSpot | Deal-timeline note (no property) | AwsOpportunityLifeCycle.NextSteps |
hs_next_step is a native HubSpot property — FlowState does not provision it, since HubSpot already ships it. FlowState sends its value to APN’s LifeCycle.NextSteps only when it changed, because AWS’s NextStepsHistory caps at 50 entries and appends one per write; an unchanged value never reaches the wire. AWS also caps LifeCycle.NextSteps at 255 characters — an over-length value is refused outright (never truncated) and a note tells the rep how much to cut, so the rep’s own words are never altered. A next step edited while AWS holds the opportunity locked for review is held and re-sent once the opp unlocks, with a note saying so.
AWS’s own next step (AwsOpportunityLifeCycle.NextSteps, read-only — there is no partner write API for it) is no longer mirrored onto a HubSpot property; FlowState tracks it internally for change detection only. It still posts one deal-timeline note per change — so the HubSpot timeline itself is the history, and AWS’s NextStepsHistory list is not separately mirrored — and the HubSpot card reads the current value live.
AWS-owned fields (mirrored to HubSpot, not editable in HubSpot)
These fields are written by AWS Partner Central and reflected back to HubSpot by the inbound handler. Editing them in HubSpot has no effect — they will be overwritten on the next inbound event.
| APN field | Mirrored to HubSpot as | Description |
|---|---|---|
LifeCycle.ReviewStatus | apn_review_status | Current review status from AWS (Pending Submission, Submitted, In review, Approved, Rejected, Action Required). |
LifeCycle.ReviewComments | not a property — HubSpot deal-timeline note | Included in the deal-timeline note posted on Action Required and Rejected (alongside ClosedLostReason for Rejected); never mirrored to a HubSpot property. Also independently watched — see below — for the case where AWS adds or edits comments without a review-status transition (e.g. while the opp stays In review). |
Opportunity.Id | apn_opportunity_id | Assigned by AWS on first submission. Write-once in HubSpot. |
| Engagement metadata | (not in HubSpot) | Engagement invitation IDs and statuses are stored in FlowState only; not written to HubSpot properties. |
AWS-side changes reported via note
A small set of fields AWS is known to change on the opportunity after it already exists. Every change to one of these produces ONE deal-timeline note — whether or not FlowState also wrote the value into the deal. The note splits changed fields into two groups:
- Updated on your deal — a dual-owned field (
apn_mrr,apn_postal_code,closedate) where the three-way merge (above) sided with AWS this round. No action is needed; the value is already on the deal. - Left as AWS’s own data — either a HubSpot-owned field FlowState never writes at all
(same rule as
LifeCycle.Stageadvancing on the AWS side, which never moves your HubSpotdealstageeither — it only posts a note inviting you to align it), or a dual-owned field where a pending edit on your side meant the merge declined to overwrite it this round. Adopting it into your own deal properties is your call.
| APN field | Written to the deal? | Why it’s watched |
|---|---|---|
LifeCycle.TargetCloseDate (closedate) | Yes, when AWS wins the three-way merge | The original both-owned mirror; previously synced silently with no note, which read as the deal changing for no visible reason. |
Project.ExpectedCustomerSpend.Amount (apn_mrr) | Yes, when AWS wins the three-way merge | AWS re-forecasts the expected monthly spend during co-sell review. |
Customer.Account.Address.PostalCode (apn_postal_code) | Yes, when AWS wins the three-way merge | The partner’s own address correction and AWS’s can race the same way closedate can. |
LifeCycle.ReviewComments | No — notes-only | AWS-authored review feedback — never sent outbound to APN (see the field-owner comment on LC_UPDATE_STRIP) — that can change independent of a ReviewStatus transition. |
Project.CustomerUseCase (apn_use_case) | No — notes-only | Observed changed by AWS after HubSpot deal creation. |
Project.SalesActivities (apn_sales_activity) | No — notes-only | Observed changed by AWS after HubSpot deal creation. |
Project.DeliveryModels (apn_delivery_model) | No — notes-only | Observed changed by AWS after HubSpot deal creation. |
Customer.Account.Industry (apn_client_industry) | No — notes-only | Observed changed by AWS after HubSpot deal creation. |
The four notes-only Project/Customer.Account fields are HubSpot-owned for the
outbound direction (you are the intended author) — they are copied ONCE, at deal-creation
time, from whatever the opportunity holds then, into the apn_fields store rather than a
HubSpot property (see “Fields moved off HubSpot properties” above). There is no ongoing
mirror for them, so an AWS edit made afterward was previously invisible; the note above is
how you now find out about it.
LifeCycle.Stage and LifeCycle.ReviewStatus are deliberately NOT in this list — they
already have their own dedicated notes (stage-change note, review-status note); watching
them here too would duplicate the same event.
The note’s exact wording (one bullet per changed field, using the field’s HubSpot label; either group may be empty and is omitted when it is):
🔄 AWS Partner Central — AWS updated this opportunity
On the co-sell opportunity (ID: <opp id>), AWS changed:
Updated on your deal. No action is needed:
• APN Monthly Recurring Revenue: 10000 → 20000
• Close Date: 2026-08-20 → 2026-08-25
Left as AWS's own data — adopting these into your own deal properties, if you want them,
is your call:
• APN Use Case: Analytics → DatabaseThe note only appears when a watched field’s value actually differs from what FlowState last observed on this opportunity — never on an unchanged reconcile (which runs on every inbound event), and never on the very first time a field is observed (that observation only establishes the baseline, so a value already copied into HubSpot at deal creation is never misreported as something AWS “just changed”). Which group a dual-owned field lands in reflects what the three-way merge actually decided this round — not a guess: see “Field ownership” above for how the merge itself works.
Excluded, and why:
LifeCycle.ClosedLostReason— HubSpot-owned: you set this, and it is sent outbound to APN. There is no evidence AWS originates this field.LifeCycle.NextStepsHistory— a list of historical entries, not a single value; a meaningful “old → new” diff needs its own design, not this mechanism.- Remaining identity fields (company name/website, AWS account ID, state/region, country, primary needs) — no evidence AWS edits these after creation.
Deal stage mapping
The HubSpot dealstage property maps to APN’s LifeCycle.Stage enumeration. APN accepts exactly seven stage values: Prospect, Qualified, Technical Validation, Business Validation, Committed, Launched, Closed Lost.
Stage mapping is configured per pipeline in Settings → Integrations → APN → Stage Mapping. The UI shows each pipeline with its stages and a dropdown to assign an APN stage to each HubSpot stage.
You can also configure it via the MCP tools:
get_apn_stage_mapping() # view current mapping + all pipelines
set_apn_stage_mapping(pipelines: {"pipeline_id": {"stage_id": "Qualified"}})
clear_apn_stage_mapping(pipeline_id: "pipeline_id") # remove mapping for one pipelineFail-closed: if a deal’s pipeline + stage has no mapping configured, the sync engine does NOT send it to APN. The deal is flagged with STAGE_UNMAPPED in its sync state, and you see a “configure mapping” prompt on that deal in the UI. Once the mapping is filled in, the deal will re-sync automatically on the next HubSpot webhook event.
There is no mapping applied automatically — per the fail-closed rule above, every pipeline stage must be configured explicitly before deals in it will sync. An example mapping for the standard HubSpot pipeline (using APN’s actual seven-value enum):
| HubSpot stage (internal value) | APN LifeCycle.Stage |
|---|---|
appointmentscheduled | Prospect |
qualifiedtobuy | Qualified |
presentationscheduled | Technical Validation |
decisionmakerboughtin | Business Validation |
contractsent | Committed |
closedwon | Launched |
closedlost | Closed Lost |