Create Address Lookup integration
This article will show how to create an address lookup integration using ArcGIS
ArcGIS allows us to search for addresses for free, but once we save an address into our database, we need to consume a credit, which is a paid-for service.
Description
ArcGIS exposes several REST baseAPIs. We will be configuring two integrations, one to search for the address and one for fetching the address and consuming a credit.
1: The search API
The suggest api provided by ArcGIS allows us to search for an address:
https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest
The Integration Record
From within the ProcessFactorial Portal, browse to the Integrations Tab and click New Integration
Fill in the following details
| Field | Purpose | Example Value |
|---|---|---|
| Name | A friendly name to identify this integration | Digital Journey Address Lookup - Search Addresses |
| Description | A one paragraph description on this integration | Look up addresses via ArcGIS |
| Triggered By | Whether this integration will be triggered by Factorial Form, Factorial Flow or an external system | ProcessFactorial Forms |
| Message Exchange Pattern | Because we want to call an API and receive data back, set this to Two Way | Two Way |
| Outbound Integration Business Object | Not used for Factorial Form, so leave blank | |
| Integration Verb | GET, PUT, POST, DELETE, etc | GET |
| Integration Type | Because this is a synchronous integration that expects a response: | UnqueuedSync |
| Base URL | Fixed Value and "https://geocode.arcgis.com" | |
| Path | Fixed Value and "/arcgis/rest/services/World/GeocodeServer/suggest" | |
| Headers | No headers are needed for this specific integration | |
| Query Parameters | Some of these parameters are pre-configured (Type = Value) and others are dynamic (Type = Digital Journey Form) | see #Query Parameters for Search API |
Query Parameters for Search API
| Name | Data Type | Type | Value | Comments |
|---|---|---|---|---|
| f | String | Fixed Value | pjson | Default value required by ArcGIS |
| category | String | Fixed Value | Address | Default value required by ArcGIS |
| maxSuggestions | String | Fixed Value | 10 | Default value required by ArcGIS. Specifies how many addresses to return during the search. 10 is an optimal number |
| text | String | Form | search | This field will be dynamically updated on the Digital Journey form. The label 'search' is the name of the parameter that we will use on the [[NPO Public Wiki/Terminology/Form Event]] |
| sourceCountry | String | Form | country | This field will be dynamically updated on the Digital Journey form The label 'country' is the name of the parameter that we will use on the [[NPO Public Wiki/Terminology/Form Event]] |

Inbound Mapping
The inbound mapping will determine what we do with the response that comes back from the ArcGIS services. The mapping record is how we tell the system where to find the data in the response ^44acd6
After creating the Integration record above, go to the Mapping tab and click New Mapping and fill in the following details:
| Field | Purpose | Example Value |
|---|---|---|
| Name | A friendly name to identify this integration | Inbound mapping for ArcGIS Address Integration - Search Addresses |
| Description | A one paragraph description on this integration | Inbound mapping for ArcGIS Address Integration - Search Addresses |
| Direction | Whether this is the inbound (from external service, such as ArcGIS into your website) or outbound mapping (from your website out to the external service) | Inbound |
Tree View
Click on the created mapping to open up the tree view. The tree structure allows you to map data from the API response to the corresponding attributes in the integration. Click on Add Child Table to define the hierarchical mapping based on the response structure.
Fill in the following details:
| Field | Description | Example Value |
|---|---|---|
| Name | Name used to reference the Child Table Object | Suggestions Property |
| Description | A short description of the Child Table | Suggestions Property |
| Data Table Name | The array within the api response containing the suggested address data | suggestions |
| Integration Object Name | The Integration object that represents the api response | responses |
| Create Node on Data Availability toggle | Enable to create a nested array only if valid data exists | disabled |
| JSON Type | Whether the root JSON object is an array or an object | Array |

Once the Child Table has been created, click on the + button next to Fields to add fields to the table. Primarily we are interested in mapping the text and the magicKey attributes of the response for which we'll create two fields.
Fill in the following details for the each of the respective fields:
| Field | Description | Example values |
|---|---|---|
| Integration Property Name | The name of the integration property to map the attribute to | 1. value 2. key |
| Condition on Data Availability | Enable the toggle to create the field only when valid data is present | enabled |
| Value Type | Denotes the type of field value. Choose from Form, Form PlaceHolder and Fixed Value | Form |
| Value | The respective key of the value in the data table | 1. text 2. magicKey |

Outbound Mapping
The outbound mapping will determine what we send to the ArcGIS services. In this particular example, we're not sending anything in the request, but the mapping record is still required, even though it doesn't have any mappings ^2da4ac
After creating the Integration record above, go to the Mapping tab and click New Mapping and fill in the following details:
| Field | Purpose | Example Value |
|---|---|---|
| Name | A friendly name to identify this integration | Outbound mapping for ArcGIS Address Integration - Search Addresses |
| Description | A one paragraph description on this integration | Outbound mapping for ArcGIS Address Integration - Search Addresses |
| Direction | Whether this is the inbound (from external service, such as ArcGIS into your website) or outbound mapping (from your website out to the external service) | Outbound |
| There is no additional tree structure needed for this mapping |
2: The Save Address API
The findAddressCandidates api provided by ArcGIS returns the full address object in its parts, such as line 1, line 2 and city, and consumes a paid-for credit from ArcGIS
https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates
Creating the Integration record
From within the ProcessFactorial Portal, browse to the Integrations Tab and click New Integration
Fill in the following details
| Field | Purpose | Example Value |
|---|---|---|
| Name | A friendly name to identify this integration | Digital Journey Address Lookup - Save Addresses |
| Description | A one paragraph description on this integration | Fetch single address details to save. Also consume quota |
| Triggered By | Whether this integration will be triggered by Factorial Form, Factorial Flow or an external system | ProcessFactorial Forms |
| Message Exchange Pattern | Because we want to call an API and receive data back, set this to Two Way | Two Way |
| Outbound Integration Business Object | Not used for Factorial Form, so leave blank | |
| Integration Verb | GET, PUT, POST, DELETE, etc | GET |
| Integration Type | Because this is a synchronous integration that expects a response: | UnqueuedSync |
| Base URL | Fixed Value and "https://geocode.arcgis.com" | |
| Path | Fixed Value and "/arcgis/rest/services/World/GeocodeServer/findAddressCandidates" | |
| Headers | No headers are needed for this specific integration | |
| Query Parameters | Some of these parameters are pre-configured (Type = Value) and others are dynamic (Type = Digital Journey Form) | see #Query Parameters for Save Address API |
| #### Query Parameters for Save Address API |
| Name | Data Type | Type | Value | Comments |
|---|---|---|---|---|
| f | String | Value | pjson | Default value required by ArcGIS |
| outFields | String | Value | Address,District,City,SubRegion,Region,Postal,Country | List of fields to be returned in the repsonse |
| maxLocations | String | Value | 1 | Maximum number of locations to be returned in the response |
| langCode | String | Value | EN | Language for the returned results |
| magicKey | String | DigitalJourneyForm | key | This field will be dynamically updated on the Digital Journey form. The label 'key' is the name of the parameter that we will use on the [[NPO Public Wiki/Terminology/Form Event]] |

Inbound Mapping
After creating the Integration record above, go to the Mapping tab and click New Mapping and fill in the following details:
| Field | Purpose | Example Value |
|---|---|---|
| Name | A friendly name to identify this integration | ArcGIS response to Digital Journey form mapping for ArcGIS Address Integration |
| Description | A one paragraph description on this integration | Inbound (into NPO) mapping for ArcGIS Address Integration |
| Direction | Whether this is the inbound (from external service, such as ArcGIS into your website) or outbound mapping (from your website out to the external service) | Inbound |
Tree View
Click on Add Child Table to map the tree structure of the response from the API
Fill in the following details:
| Field | Description | Example Value |
|---|---|---|
| Name | Name used to reference the Child Table Object | Candidates Property |
| Description | A short description of the Child Table | Candidates Property |
| Data Table Name | The array within the api response containing the suggested address data | candidates |
| Integration Object Name | The Integration object that represents the api response | responses |
| Create Node on Data Availability toggle | Enable to create a nested array only if valid data exists | disabled |
| JSON Type | Whether the root JSON object is an array or an object | Array |
Once the Child Table has been created. click on the + button next to Fields to add fields to the table.
Fill in the following details to add the address field:
| Field | Description | Example values |
|---|---|---|
| Integration Property Name | The name of the integration property to map the attribute to | address |
| Condition on Data Availability | Enable the toggle to create the field only when valid data is present | enabled |
| Value Type | Denotes the type of field value. Choose from Form, Form PlaceHolder and Fixed Value | Form |
| Value | The respective key of the value in the data table | address |

Create a nested Child Table within the Candidates Property table to store the attributes properties
Fill in the following details:
| Field | Description | Example Value |
|---|---|---|
| Name | Name used to reference the Child Table Object | Attributes Property |
| Description | A short description of the Child Table | Attributes Property |
| Data Table Name | The array within the api response containing the suggested address data | attributes |
| Integration Object Name | The Integration object that represents the api response | blank |
| Create Node on Data Availability toggle | Enable to create a nested array only if valid data exists | disabled |
| JSON Type | Whether the root JSON object is an array or an object | Object |

Create fields in the Attributes Property child table
Fill in the following details for each of the 7 respective fields to be created.
| Field | Description | Example values |
|---|---|---|
| Integration Property Name | The name of the integration property to map the attribute to | 1. line1 2. city 3. country 4. district 5. postcode 6. subregion 7. region |
| Condition on Data Availability | Enable the toggle to create the field only when valid data is present | enabled (for all fields) |
| Value Type | Denotes the type of field value. Choose from Form, Form PlaceHolder and Fixed Value | Form (for all fields) |
| Value | The respective key of the value in the data table | 1. Address 2. City 3. Country 4. District 5. Postal 6. SubRegion 7. Region |
![]() |
Add another child table nested in the Candidates Property table for storing lat/long property. Fill in the following details:
| Field | Description | Example Value |
|---|---|---|
| Name | Name used to reference the Child Table Object | Lat/Long Property |
| Description | A short description of the Child Table | Lat/Long Property |
| Data Table Name | The array within the api response containing the suggested address data | location |
| Integration Object Name | The Integration object representing the api response | blank |
| Create Node on Data Availability toggle | Enable to create a nested array only if valid data exists | disabled |
| JSON Type | Whether the root JSON object is an array or an object | Object |

Add longitude and latitude fields to the Lat/Long Property table. Fill in the following details for the respective fields:
| Field | Description | Example values |
|---|---|---|
| Integration Property Name | The name of the integration property to map the attribute to | 1. longitude 2. latitude |
| Condition on Data Availability | Enable the toggle to create the field only when valid data is present | enabled (for both) |
| Value Type | Denotes the type of field value. Choose from Form, Form PlaceHolder and Fixed Value | Form (for both) |
| Value | The respective key of the value in the data table | 1. x 2. y |

We have successfully mapped the tree structure for the integration.
Outbound Mapping
The outbound mapping will determine what we send to the ArcGIS services. In this particular example, we're not sending anything in the request, but the mapping record is still required, even though it doesn't have any mappings
After creating the Integration record above, go to the Mapping tab and click New Mapping and fill in the following details:
| Field | Purpose | Example Value |
|---|---|---|
| Name | A friendly name to identify this integration | Website request to ArcGIS mapping for ArcGIS Address Integration |
| Description | A one paragraph description on this integration | Outbound (out of NPO) mapping for ArcGIS Address Integration |
| Direction | Whether this is the inbound (from external service, such as ArcGIS into your website) or outbound mapping (from your website out to the external service) | Outbound |
| There is no additional tree structure needed for this mapping |
3. Raw JSON
Below are the actual request and responses sent and received at each stage of the examples above. These are here for reference only
1. The search API
This example shows the details of the #1 The search API
Step 1: Calling the ProcessFactorial Integration Engine
The first step is an external service, such as the ProcessFactorial Forms, calling the ProcessFactorial Integration Engine API. While this is typically called from another ProcessFactorial component, such as Forms or Flows, it can be called from other external services as well
cURL
Import the following into Postman to get the full request. Note that the Authorization header would have expired, so a fresh one will be needed
curl 'http://localhost:7231/api/dem/integrate' \
-H 'Accept: */*' \
-H 'Accept-Language: en-GB,en;q=0.9,en-US;q=0.8' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkhTMjNiN0RvN1RjYVUxUm9MSHdwSXEyNFZZZyJ9.eyJhdWQiOiIxYzllMzlhYS04ZWEwLTQxYTAtOWRlZC04YmI3ODA3MDU4MjEiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vMDYzZmY2YjYtODQ0Yy00ZGRmLThlNDUtYjcyYjNmYjk3MTRixxxxxxxx' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/json' \
-H 'Origin: http://localhost:5173' \
-H 'Pragma: no-cache' \
-H 'Referer: http://localhost:5173/' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-site' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0' \
-H 'demToken: Qs3WogQhBCS5dbTtPRFngm1pUbi158ktFHffTksf3ZspZI96X0vV0YKc2C8tSzCRGSn4GtBPrXefmJMtntR/voAr4IvK8GLvGhxtBgrStnLlHQEdCMPT6vUZMN+waXebYontG4dWzB7YgCyH/8R+6nlfAv1ZPiKxz3xMwbv7yRJ9JhaSIrYpILZ29NrfxdrJgA9DsI/tgD23fKLXJ36gMDcLowemYgB7EKp4loor8egiXFgK5zMvDzFUsffd6MCKacJqjQzFnVsYweJiFdOKXGRAit6aur3F8pFT8bUrC49x0fyxGO0GtIKuUyB5PiHSchS7hXRCgtKnQvCF9Ai3fbUiVb4UxyEm6PYTMqJV+GIEpaZeHPoTIk0+jNnrv8RDj9r+Vp6Cbr7RAtLYbScZocRMOONTTG3gycKP8umGzqy5+dsHyTJ5mglYywXPE0Y44QG/VwHYhS6uqjrF0TcXNc8oJLIb8Wkc+AEn5+I+Yqz0aWXN31y9bOyNcCPti8K4lvVQf0VNf0uhye21uvd0ug==' \
-H 'sec-ch-ua: "Chromium";v="140", "Not=A?Brand";v="24", "Microsoft Edge";v="140"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Windows"' \
--data-raw '{"integrationId":"aaaa2a43-bcac-49ca-96e2-2a1ccbac9004_aaaa2a43-bcac-49ca-96e2-2a1ccbac9005_aaaa2a43-bcac-49ca-96e2-2a1ccbac9006","data":{"OutputAction":"DataSet","IntegrationCategory":"Integrate","QueryStringValues":[{"Key":"search","SourceId":"50000000-1000-0000-0000-000000000002","DataType":"String","Value":"main"},{"Key":"country","SourceId":"50000000-1000-0000-0000-000000000001.npo_iso2code","DataType":"String","Value":"NZ"}]}}'
Request Path
Request Query String
Request Headers
authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkhTMjNiN0RvN1RjYVUxUm9MSHdwSXEyNFZZZyJ9.eyJhdWQiOiIxYzllMzlhYS04ZWEwLTQxYTAtOWRlZC04YmI3ODA3MDU4MjEiLCJpc3MiOiJodHRwczovLxxxxxxxxx
Request Body
{
"data": {
"IntegrationCategory": "Integrate",
"OutputAction": "DataSet",
"QueryStringValues": [
{
"DataType": "String",
"Key": "search",
"SourceId": "50000000-1000-0000-0000-000000000002",
"Value": "main"
},
{
"DataType": "String",
"Key": "country",
"SourceId": "50000000-1000-0000-0000-000000000001.npo_iso2code",
"Value": "NZ"
}
]
},
"integrationId": "aaaa2a43-bcac-49ca-96e2-2a1ccbac9004_aaaa2a43-bcac-49ca-96e2-2a1ccbac9005_aaaa2a43-bcac-49ca-96e2-2a1ccbac9006"
}
Response Body
The response body is returned after the Integration Engine has completed all its internal integration calls, which can be either a single integration to an external API or a series of integrations with an Integration Workflow In other words, this is the very final response of the entire sequence of integrations and is the actual response returned back to the original sender.
{
"content": {
"id": "aaaa2a43-bcac-49ca-96e2-2a1ccbac9004_aaaa2a43-bcac-49ca-96e2-2a1ccbac9005_aaaa2a43-bcac-49ca-96e2-2a1ccbac9006_1.0.0.0",
"isActive": true,
"jsonPropertyName": "responses",
"keyFieldName": "key",
"referenceRecordsJSON": "{\"responses\":[{\"value\":\"Main Drain Road, Glen Oroua, Manawatu-Wanganui, 4473, NZL\",\"key\":\"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NjAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ=\"},{\"value\":\"Main Drain Road, Glen Oroua, Manawatu-Wanganui, 4477, NZL\",\"key\":\"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ=\"},{\"value\":\"Main Drain Road, Rangiotu, Manawatu-Wanganui, 4477, NZL\",\"key\":\"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzczMzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ=\"},{\"value\":\"Main Drive, Massey University, Palmerston North, Manawatu-Wanganui, 4472, NZL\",\"key\":\"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3Nzg0NTIjbG5nPTQxI2xicz0xMDk6OTEzNjY3NjAjbG49V29ybGQ=\"},{\"value\":\"Main Highway Entry, Ōtaki, Wellington, 5512, NZL\",\"key\":\"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE4MDcwMTEjbG5nPTQxI2xicz0xMDk6OTEzNjExMjAjbG49V29ybGQ=\"},{\"value\":\"Main Highway Exit, Ōtaki, Wellington, 5512, NZL\",\"key\":\"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE4MDY5MzIjbG5nPTQxI2xicz0xMDk6OTEzNjExMjEjbG49V29ybGQ=\"},{\"value\":\"Main Highway, Ellerslie, Auckland, 1051, NZL\",\"key\":\"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NDQ5ODQjbG5nPTQxI2xicz0xMDk6OTEzNjY3ODAjbG49V29ybGQ=\"},{\"value\":\"Main Highway, Ellerslie, Auckland, 1060, NZL\",\"key\":\"dHA9NCN0dj04NmU1NWE1MSNubT1NYWluIEhpZ2h3YXksIEVsbGVyc2xpZSwgQXVja2xhbmQsIDEwNjAsIE5aTCNzYz1OWiNsbmc9NDEjbG49V29ybGQ=\"},{\"value\":\"Main Highway, Ellerslie, Auckland, 1061, NZL\",\"key\":\"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NDUwNjAjbG5nPTQxI2xicz0xMDk6OTEzNjY3ODAjbG49V29ybGQ=\"},{\"value\":\"Main Highway, Mount Wellington, Auckland, 1060, NZL\",\"key\":\"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NTA4NTkjbG5nPTQxI2xicz0xMDk6OTEzNjY3ODAjbG49V29ybGQ=\"}]}",
"valueFieldName": "value"
},
"errors": [
],
"message": "Ok",
"warnings": [
]
}
The data in the referenceRecordsJSON property can then be parsed and consumed:
{
"responses": [
{
"key": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NjAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ=",
"value": "Main Drain Road, Glen Oroua, Manawatu-Wanganui, 4473, NZL"
},
{
"key": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ=",
"value": "Main Drain Road, Glen Oroua, Manawatu-Wanganui, 4477, NZL"
},
{
"key": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzczMzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ=",
"value": "Main Drain Road, Rangiotu, Manawatu-Wanganui, 4477, NZL"
},
{
"key": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3Nzg0NTIjbG5nPTQxI2xicz0xMDk6OTEzNjY3NjAjbG49V29ybGQ=",
"value": "Main Drive, Massey University, Palmerston North, Manawatu-Wanganui, 4472, NZL"
},
{
"key": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE4MDcwMTEjbG5nPTQxI2xicz0xMDk6OTEzNjExMjAjbG49V29ybGQ=",
"value": "Main Highway Entry, Ōtaki, Wellington, 5512, NZL"
},
{
"key": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE4MDY5MzIjbG5nPTQxI2xicz0xMDk6OTEzNjExMjEjbG49V29ybGQ=",
"value": "Main Highway Exit, Ōtaki, Wellington, 5512, NZL"
},
{
"key": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NDQ5ODQjbG5nPTQxI2xicz0xMDk6OTEzNjY3ODAjbG49V29ybGQ=",
"value": "Main Highway, Ellerslie, Auckland, 1051, NZL"
},
{
"key": "dHA9NCN0dj04NmU1NWE1MSNubT1NYWluIEhpZ2h3YXksIEVsbGVyc2xpZSwgQXVja2xhbmQsIDEwNjAsIE5aTCNzYz1OWiNsbmc9NDEjbG49V29ybGQ=",
"value": "Main Highway, Ellerslie, Auckland, 1060, NZL"
},
{
"key": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NDUwNjAjbG5nPTQxI2xicz0xMDk6OTEzNjY3ODAjbG49V29ybGQ=",
"value": "Main Highway, Ellerslie, Auckland, 1061, NZL"
},
{
"key": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NTA4NTkjbG5nPTQxI2xicz0xMDk6OTEzNjY3ODAjbG49V29ybGQ=",
"value": "Main Highway, Mount Wellington, Auckland, 1060, NZL"
}
]
}
Step 2: ProcessFactorial Integration Engine calling the ArcGIS Search API
This step is the actual internal call made by the Integration Engine to ArcGIS after any request mapping has taken place to convert the ProcessFactorial formats into the ArcGIS formats.
Notice how the response mapping from Step 1 above maps to the response mapping below.
cURL
Import the following into Postman to get the full request. Note that the Authorization header would have expired, so a fresh one will be needed
curl --location 'https://geocode.arcgis.com:443/arcgis/rest/services/World/GeocodeServer/suggest?f=pjson&category=Address&maxSuggestions=10&text=main&sourceCountry=NZ'
Request Path
https://geocode.arcgis.com:443/arcgis/rest/services/World/GeocodeServer/suggest?f=pjson&category=Address&maxSuggestions=10&text=main&sourceCountry=NZ
Request Query String
Request Headers
Request Body
Response Body
The raw response body is returned by the ArcGIS Search API, prior to being converted into the #Response Body that is consumed by the original sender.
{
"suggestions": [
{
"isCollection": false,
"magicKey": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NjAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ=",
"text": "Main Drain Road, Glen Oroua, Manawatu-Wanganui, 4473, NZL"
},
{
"isCollection": false,
"magicKey": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ=",
"text": "Main Drain Road, Glen Oroua, Manawatu-Wanganui, 4477, NZL"
},
{
"isCollection": false,
"magicKey": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzczMzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ=",
"text": "Main Drain Road, Rangiotu, Manawatu-Wanganui, 4477, NZL"
},
{
"isCollection": false,
"magicKey": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3Nzg0NTIjbG5nPTQxI2xicz0xMDk6OTEzNjY3NjAjbG49V29ybGQ=",
"text": "Main Drive, Massey University, Palmerston North, Manawatu-Wanganui, 4472, NZL"
},
{
"isCollection": false,
"magicKey": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE4MDcwMTEjbG5nPTQxI2xicz0xMDk6OTEzNjExMjAjbG49V29ybGQ=",
"text": "Main Highway Entry, Ōtaki, Wellington, 5512, NZL"
},
{
"isCollection": false,
"magicKey": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE4MDY5MzIjbG5nPTQxI2xicz0xMDk6OTEzNjExMjEjbG49V29ybGQ=",
"text": "Main Highway Exit, Ōtaki, Wellington, 5512, NZL"
},
{
"isCollection": false,
"magicKey": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NDQ5ODQjbG5nPTQxI2xicz0xMDk6OTEzNjY3ODAjbG49V29ybGQ=",
"text": "Main Highway, Ellerslie, Auckland, 1051, NZL"
},
{
"isCollection": false,
"magicKey": "dHA9NCN0dj04NmU1NWE1MSNubT1NYWluIEhpZ2h3YXksIEVsbGVyc2xpZSwgQXVja2xhbmQsIDEwNjAsIE5aTCNzYz1OWiNsbmc9NDEjbG49V29ybGQ=",
"text": "Main Highway, Ellerslie, Auckland, 1060, NZL"
},
{
"isCollection": false,
"magicKey": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NDUwNjAjbG5nPTQxI2xicz0xMDk6OTEzNjY3ODAjbG49V29ybGQ=",
"text": "Main Highway, Ellerslie, Auckland, 1061, NZL"
},
{
"isCollection": false,
"magicKey": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NTA4NTkjbG5nPTQxI2xicz0xMDk6OTEzNjY3ODAjbG49V29ybGQ=",
"text": "Main Highway, Mount Wellington, Auckland, 1060, NZL"
}
]
}
2. The save address API
This example shows the details of the findAddressCandidates API
Step 1: Calling the ProcessFactorial Integration Engine
The first step is an external service, such as the ProcessFactorial Forms, calling the ProcessFactorial Integration Engine API. While this is typically called from another ProcessFactorial component, such as Forms or Flows, it can be called from other external services as well
cURL
Import the following into Postman to get the full request. Note that the Authorization header would have expired, so a fresh one will be needed
curl 'http://localhost:7231/api/dem/integrate' \
-H 'Accept: */*' \
-H 'Accept-Language: en-GB,en;q=0.9,en-US;q=0.8' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkhTMjNiN0RvN1RjYVUxUm9MSHdwSXEyNFZZZyJ9.eyJhdWQiOiIxYzllMzlhYS04ZWEwLTQxYTAtOWRlZC04YmI3ODA3MDU4MjEiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vMDYzZmY2YjYtODQ0Yy00ZGRmLThlNDUtYjcyYjNmYjk3MTRixxxxxxxx' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/json' \
-H 'Origin: http://localhost:5173' \
-H 'Pragma: no-cache' \
-H 'Referer: http://localhost:5173/' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-site' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0' \
-H 'demToken: Qs3WogQhBCS5dbTtPRFngm1pUbi158ktFHffTksf3ZspZI96X0vV0YKc2C8tSzCRGSn4GtBPrXefmJMtntR/voAr4IvK8GLvGhxtBgrStnLlHQEdCMPT6vUZMN+waXebYontG4dWzB7YgCyH/8R+6nlfAv1ZPiKxz3xMwbv7yRJ9JhaSIrYpILZ29NrfxdrJgA9DsI/tgD23fKLXJ36gMDcLowemYgB7EKp4loor8egiXFgK5zMvDzFUsffd6MCKacJqjQzFnVsYweJiFdOKXGRAit6aur3F8pFT8bUrC49x0fyxGO0GtIKuUyB5PiHSchS7hXRCgtKnQvCF9Ai3fbUiVb4UxyEm6PYTMqJV+GIEpaZeHPoTIk0+jNnrv8RDj9r+Vp6Cbr7RAtLYbScZocRMOONTTG3gycKP8umGzqy5+dsHyTJ5mglYywXPE0Y44QG/VwHYhS6uqjrF0TcXNc8oJLIb8Wkc+AEn5+I+Yqz0aWXN31y9bOyNcCPti8K4lvVQf0VNf0uhye21uvd0ug==' \
-H 'sec-ch-ua: "Chromium";v="140", "Not=A?Brand";v="24", "Microsoft Edge";v="140"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Windows"' \
--data-raw '{"integrationId":"aaaa2a43-bcac-49ca-96e2-2a1ccbac9007_aaaa2a43-bcac-49ca-96e2-2a1ccbac9008_aaaa2a43-bcac-49ca-96e2-2a1ccbac9009","data":{"OutputAction":"PopulateFormFields","IntegrationCategory":"Integrate","QueryStringValues":[{"Key":"key","SourceId":"50000000-1000-0000-0000-000000000002.key","DataType":"String","Value":"dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ="}]}}'
Request Path
Request Query String
Request Headers
authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkhTMjNiN0RvN1RjYVUxUm9MSHdwSXEyNFZZZyJ9.eyJhdWQiOiIxYzllMzlhYS04ZWEwLTQxYTAtOWRlZC04YmI3ODA3MDU4MjEiLCJpc3MiOiJodHRwczovLxxxxxxxxx
Request Body
{
"data": {
"IntegrationCategory": "Integrate",
"OutputAction": "PopulateFormFields",
"QueryStringValues": [
{
"DataType": "String",
"Key": "key",
"SourceId": "50000000-1000-0000-0000-000000000002.key",
"Value": "dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ="
}
]
},
"integrationId": "aaaa2a43-bcac-49ca-96e2-2a1ccbac9007_aaaa2a43-bcac-49ca-96e2-2a1ccbac9008_aaaa2a43-bcac-49ca-96e2-2a1ccbac9009"
}
Response Body
The response body is returned after the Integration Engine has completed all its internal integration calls, which can be either a single integration to an external API or a series of integrations with an Integration Workflow In other words, this is the very final response of the entire sequence of integrations and is the actual response returned back to the original sender.
{
"content": {
"id": "aaaa2a43-bcac-49ca-96e2-2a1ccbac9007_aaaa2a43-bcac-49ca-96e2-2a1ccbac9008_aaaa2a43-bcac-49ca-96e2-2a1ccbac9009_1.0.0.0",
"isActive": true,
"referenceRecordsJSON": "{\"address\":\"Main Drain Road, Glen Oroua, Manawatu-Wanganui, 4477\",\"line1\":\"Main Drain Road\",\"city\":\"Glen Oroua\",\"country\":\"NZL\",\"district\":\"\",\"postcode\":\"4477\",\"subregion\":\"Manawatu\",\"region\":\"Manawatu-Wanganui\",\"longitude\":175.425557901815,\"latitude\":-40.364695750347}"
},
"errors": [
],
"message": "Ok",
"warnings": [
]
}
The data in the referenceRecordsJSON property can then be parsed and consumed:
{
"address": "Main Drain Road, Glen Oroua, Manawatu-Wanganui, 4477",
"city": "Glen Oroua",
"country": "NZL",
"district": "",
"latitude": -40.364695750347,
"line1": "Main Drain Road",
"longitude": 175.425557901815,
"postcode": "4477",
"region": "Manawatu-Wanganui",
"subregion": "Manawatu"
}
Step 2: ProcessFactorial Integration Engine calling the ArcGIS Save Address API
This step is the actual internal call made by the Integration Engine to ArcGIS after any request mapping has taken place to convert the ProcessFactorial formats into the ArcGIS formats.
Notice how the response mapping from Step 1 above maps to the response mapping below.
cURL
Import the following into Postman to get the full request.
curl --location 'https://geocode.arcgis.com:443/arcgis/rest/services/World/GeocodeServer/findAddressCandidates?f=pjson&outFields=Address%2cDistrict%2cCity%2cSubRegion%2cRegion%2cPostal%2cCountry&maxLocations=1&langCode=EN&magicKey=dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ%3D%3D%3D'
Request Path
https://geocode.arcgis.com:443/arcgis/rest/services/World/GeocodeServer/findAddressCandidates?f=pjson&outFields=Address%2cDistrict%2cCity%2cSubRegion%2cRegion%2cPostal%2cCountry&maxLocations=1&langCode=EN&magicKey=dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ===
Request Query String
f=pjson
outFields=Address%2cDistrict%2cCity%2cSubRegion%2cRegion%2cPostal%2cCountry&maxLocations=1
langCode=EN
magicKey=dHA9MCN0dj04NmU1NWE1MSNsb2M9NzE3NzY4NzAjbG5nPTQxI2xicz0xMDk6OTEzNjA5NzUjbG49V29ybGQ===
Request Headers
Request Body
Response Body
The raw response body is returned by the ArcGIS Search API, prior to being converted into the #Response Body that is consumed by the original sender.
{
"candidates": [
{
"address": "Main Drain Road, Glen Oroua, Manawatu-Wanganui, 4477",
"attributes": {
"Address": "Main Drain Road",
"City": "Glen Oroua",
"Country": "NZL",
"District": "",
"Postal": "4477",
"Region": "Manawatu-Wanganui",
"SubRegion": "Manawatu"
},
"extent": {
"xmax": 175.426557901815,
"xmin": 175.424557901815,
"ymax": -40.363695750347,
"ymin": -40.365695750347
},
"location": {
"x": 175.425557901815,
"y": -40.364695750347
},
"score": 100
}
],
"spatialReference": {
"latestWkid": 4326,
"wkid": 4326
}
}
