# Events Source: https://docs.camo.ag/developers/embed-sdk/events Send and receive events with the CamoAg Embedded Map JavaScript events are emitted using JavaScript's [Window: postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) method. ## Receiving Events ```javascript theme={null} window.addEventListener('message', event => { // Restrict the event listener to only respond to intended sources. if (event.origin !== 'https:///embedded/map') return; console.log(event.data); }); ``` ## Available Incoming Events ### `parcel:viewed` Emitted for any parcel details selected from the Parcels map layer. ```typescript theme={null} { "event_type": string, "payload": GeoJSON Feature } ``` Example: ```json theme={null} { "event_type": "parcel:viewed", "payload": { "type": "Feature", "id": "15009bee-5713-4338-9d8a-600b7b598ff1", "properties": { "acres": 40.0, "assessor_parcel_number": "1106400003", "county": "DeKalb", "county_geoid": "17037", "county_long_name": "DeKalb County", "id": "15009bee-5713-4338-9d8a-600b7b598ff1", "path": "us/il/dekalb/1106400003", "state": "IL" }, "geometry": { "coordinates": [ [ [-88.812051, 41.8852985], [-88.81603249999999, 41.8852845], [-88.82182399999999, 41.8852645], [-88.821843, 41.8816315], [-88.8218615, 41.878105999999995], [-88.820219, 41.878108], [-88.81206499999999, 41.878118], [-88.812051, 41.8852985] ] ], "type": "Polygon" } } } ``` ### `parcel:collection_changed` Emitted for any change in the selected parcels. ```typescript theme={null} { "event_type": string, "payload": GeoJSON FeatureCollection } ``` Example: ```json theme={null} { "event_type": "parcel:collection_changed", "payload": { "type": "FeatureCollection", "features": [ { "type": "Feature", "id": "e57c840b-3bf6-4a6e-b6c6-9a3222eb4b9f", "properties": { "acres": 157.19, "assessor_parcel_number": "121209300002", "county": "Livingston", "county_geoid": "17105", "county_long_name": "Livingston County", "id": "e57c840b-3bf6-4a6e-b6c6-9a3222eb4b9f", "path": "us/il/livingston/121209300002", "state": "IL" }, "geometry": { "coordinates": [ [ [-88.314281, 40.9991505], [-88.314353, 41.000961], [-88.3239505, 41.0007995], [-88.32368149999999, 40.993614], [-88.31693399999999, 40.993708999999996], [-88.3169585, 40.9947105], [-88.31574499999999, 40.994727499999996], [-88.3157205, 40.993725999999995], [-88.3140675, 40.9937495], [-88.314281, 40.9991505] ] ], "type": "Polygon" } } ] } } ``` ### `farm_sale:viewed` Emitted for any farm sale selected from the Farm Sales map layer. ```typescript theme={null} { "event_type": string, "payload": GeoJSON Feature } ``` Example: ```json theme={null} { "event_type": "farm_sale:viewed", "payload": { "type": "Feature", "id": 4389254, "properties": { "id": 4389254, "gross_acres": 200, "county": "Livingston", "state": "Illinois", "county_geoid": "17105", "sale_type": "auction" }, "geometry": { "coordinates": [-88.708, 41.0451], "type": "Point" } } } ``` ## Sending Events The embedded map will react to events that you post into its `contentWindow`. Always pass your CamoAg embed origin as the `targetOrigin` so the message can only be received by the intended iframe. ```javascript theme={null} const embeddedMap = document.getElementById('embeddedMap'); embeddedMap.contentWindow.postMessage( { event_type: 'parcel:collection_remove_by_id', payload: { id: '15009bee-5713-4338-9d8a-600b7b598ff1' }, }, 'https://', ); ``` ## Available Outgoing Events ### `parcel:collection_remove_by_id` Removes a single parcel from the selected collection. The `id` matches the `properties.id` of a parcel feature previously returned by [`parcel:collection_changed`](#parcelcollection_changed). ```typescript theme={null} { "event_type": string, "payload": { "id": string } } ``` Example: ```json theme={null} { "event_type": "parcel:collection_remove_by_id", "payload": { "id": "15009bee-5713-4338-9d8a-600b7b598ff1" } } ``` After the parcel is removed, the embedded map emits an updated [`parcel:collection_changed`](#parcelcollection_changed) event reflecting the new selection. ### `parcel:collection_remove_all` Clears every parcel from the selected collection. ```typescript theme={null} { "event_type": string } ``` Example: ```json theme={null} { "event_type": "parcel:collection_remove_all" } ``` After the collection is cleared, the embedded map emits an updated [`parcel:collection_changed`](#parcelcollection_changed) event with an empty `features` array. # Example: Embedded Farm Map Source: https://docs.camo.ag/developers/embed-sdk/farm-example See an example of a CamoAg embedded farm map You can now embed a CamoAg farm map on your website or application using our new embed SDK. This allows you to share interactive maps of your farm with anyone, even if they don't have a CamoAg account. On our farm details page: 1. Click the **Share** button 2. Click **Embed Farm Map** 3. Copy the provided embed code and paste it into your website or application to display the interactive farm map. A live example of a CamoAg embedded farm map. Use the controls below to change the aspect ratio and width, then select **Update map size** to re-render the map. Embedded farm maps must have a viewport that is at least 200px by 200px. If the map displays controls, it must be large enough to fully display the controls without shrinking the viewport below the minimum size. We recommend 16:9 maps be at least 480 pixels wide and 270 pixels tall. # Example: Embedded Plat Map Source: https://docs.camo.ag/developers/embed-sdk/plat-map-example See the CamoAg Embedded Map in action Go to our demo site [**appraisal.ag**](https://appraisal.ag) to see an example of the embedded map experience. Open your browser console to see payloads for [parcel:viewed](/developers/embed-sdk/events#parcelviewed) and [parcel:collection\_changed](/developers/embed-sdk/events#parcelcollection_changed) events. # Setup Source: https://docs.camo.ag/developers/embed-sdk/setup Set up the CamoAg Embed SDK ## Fetch Secret The first step is to obtain your embed secret. 1. Go to your CamoAg Account Settings > Embed 2. Copy your embed secret by clicking the "View" button ## Embed Vanity Domain CamoAg uses cookies to manage authentication sessions. When the platform is embedded in iframes, browsers like Safari treat these cookies as third-party cookies. Because Safari applies strict privacy rules by default, it blocks these cookies—resulting in users being unable to access CamoAg content within the iframe. Vanity domains allow Safari to treat authentication cookies as first-party thereby enabling reliable login and session handling inside iframes. E.g. `camoag-embed.example.com` is embedded within `example.com` * Embed domains must have 3 or more parts. E.g. `camoag-example.com` is not a valid embed domain. * The top level domain of the embed domain must match the embedding page to support first-party cookies. E.g. `example.camoag-embed.com` may run into third-party cookie issues. 1. In CamoAg, navigate to **Account Settings > Embed**. 2. In the **Embed Domain** field: * Enter your domain (e.g., `camoag.myapp.com`) 3. Click **Save** to apply the configuration. 1. Reach out to CamoAg support with the vanity domain you configured in step 1. 2. CamoAg will provide DNS records to add to your domain's DNS configuration. 3. Notify CamoAg support once the DNS records have been added. CamoAg will verify the configuration and enable the domain for use. ## Generate Signed URL A unique signed embed URL must be generated for each new embed session. The signed URL must be used within 5 minutes of generation. The easiest way to generate a signed embed URL is to use the following API endpoint: ``` POST https:///api/v5/auth/embed/build_signed_url ``` ### Request Body ```json theme={null} { "embed_secret": "123451234512345", "content_path": "/embedded/map", "external_id": "Abc123" } ``` **Generate signed embed URLs server-side only** The embed secret must never be exposed in client-side code (including frontend HTML and JavaScript code). For this reason, all signed URLs must be generated server-side using code running in a trusted backend environment. #### Parameters ##### `embed_secret` Your embed secret key used to sign the request. ##### `content_path` The iframe will redirect to this URL after the session is verified. The embedded map can be customized by adding URL query parameters. See [Configurable Map Defaults](/developers/embed-sdk/setup#configurable-map-defaults) for available options. Example: ```json theme={null} { "content_path": "/embedded/map" } ``` #### `external_id` A required, unique user identifier. This is a string containing up to 100 characters. A new user will be created if one does not already exist with this identifier. Example: ```json theme={null} { "external_id": "Abc123" } ``` ### Response Body Using the example Request Body above, this is an example response: ```json theme={null} { "signed_embed_url":"https://camoag-embed.example.com/api/v5/auth/embed/login?content_path=/embedded/map&external_id=Abc123&nonce=ad5b227d5ed3464bab5377ee20912694&signature=RT554uJ2_BXnmGNiqNB2u7ASVuvWeLk_yOkLzNq3ixA%3D×tamp=1764174111" } ``` ## Implementation Simply assign your signed embed URL to the iframe's `src` attribute. The session will be authenticated and the map will redirect to the value of `content_path`. ```html theme={null}