The ArcGIS Survey123 Field App is a native mobile application designed for field data collection. While the Field App has limited programmatic extension capabilities, it can be integrated with external systems through data access, URL schemes, and webhooks. This topic covers the practical approaches for integrating the Field App into your development workflows.
The Survey123 Field App has limited programmatic extension capabilities but you can configure surveys to work better with your workflows. The Field App is designed as a data collection tool rather than a customizable platform, which means most integration happens through data access and URL schemes rather than direct app modification.
| Limitation | Explanation | Alternative |
|---|---|---|
| Custom JavaScript | Field App does not support custom JavaScript functions | Use XLSForm calculations or web app for complex logic |
| Plugin Extensions | No plugin architecture for custom functionality | Build custom mobile apps using ArcGIS Maps SDKs |
| Direct API Access | Field App does not expose APIs for external integration | Use Feature Layer REST API to access survey data |
| Custom UI Components | Cannot modify the Field App's user interface | Use Survey123 Web Designer for custom web forms |
Data integration
The Field App collects survey responses and stores them in ArcGIS Feature Layers. You can access this data programmatically using the ArcGIS REST API.
Accessing survey data
The primary way to integrate with the Survey123 Field App is through the data it collects. Survey responses are stored in ArcGIS Feature Layers and can be accessed programmatically using the ArcGIS REST API.
| Method | Purpose | Use Cases |
|---|---|---|
| Feature Layer REST API | Direct access to survey data | Custom reporting, data analysis, real-time dashboards |
| ArcGIS API for Python | Automated data processing | Workflow automation, data analysis, report generation |
| ArcGIS Maps SDKs | Custom applications | Building custom data visualization and management tools |
You can use the ArcGIS API for Python to access survey data programmatically and analyze survey responses. Below is an example of how to access survey data.
from arcgis.gis import GIS
from arcgis.features import FeatureLayer
try:
# Connect to ArcGIS Online
gis = GIS("https://www.arcgis.com", username="your_username", password="your_password")
# Access survey data through feature layer
survey_layer = FeatureLayer("https://services.arcgis.com/.../FeatureServer/0", gis=gis)
responses = survey_layer.query()
# Process and analyze data
if responses.features:
for feature in responses.features:
# Custom data processing logic
attributes = feature.attributes
geometry = feature.geometry
print(f"Processing survey ID: {attributes.get('objectid')}")
# Add your custom processing here
else:
print("No survey responses found")
except Exception as e:
print(f"Error accessing survey data: {str(e)}")You can monitor survey submissions using webhooks for real-time notifications. See the Webhooks for real-time integration section below for implementation details.
Alternatively, you can poll for new submissions using the ArcGIS REST API:
// Poll for new survey submissions
function checkForNewSubmissions(featureLayerUrl, token, lastCheckTime) {
const queryUrl = `${featureLayerUrl}/query`;
const params = new URLSearchParams({
where: `CreationDate > timestamp '${lastCheckTime}'`,
outFields: '*',
returnGeometry: true,
f: 'json',
token: token
});
fetch(`${queryUrl}?${params}`)
.then(response => response.json())
.then(data => {
if (data.features && data.features.length > 0) {
// Process new survey submissions
data.features.forEach(feature => {
processNewSubmission(feature.attributes);
});
}
})
.catch(error => {
console.error('Error checking for submissions:', error);
});
}
// Poll every 30 seconds
setInterval(() => {
checkForNewSubmissions(
"https://services.arcgis.com/.../FeatureServer/0",
"YOUR_TOKEN",
new Date(Date.now() - 30000).toISOString()
);
}, 30000);App integration
You can integrate the Field App with other applications using URL schemes. Below are examples of how to integrate the Field App with other applications using URL schemes.
URL schemes and deep linking
The Survey123 Field App supports two methods for launching surveys from other applications:
App Link (Recommended):
| URL Format | Purpose | Parameters |
|---|---|---|
https | Launch specific survey (cross-platform) | item, callback, field parameters |
https | Launch survey with return URL | Pre-populate fields and return to calling app |
https | Launch survey with pre-filled data | Custom field values (URL-encoded) |
Custom URL Scheme (Alternative):
| URL Format | Purpose | Notes |
|---|---|---|
arcgis-survey123 | Launch specific survey (iOS/Android) | Requires app installed; may not work on all platforms |
Web application integration
You can integrate the Field App with other applications using URL schemes. Below are examples of how to integrate the Field App with other applications using URL schemes.
// Launch Survey123 Field App from web application
function launchSurveyApp(surveyId, prefillData) {
// Use app link format for better cross-platform compatibility
const baseUrl = "https://survey123.arcgis.app";
const params = new URLSearchParams({
itemID: surveyId,
callback: window.location.href
});
// Add prefill data
if (prefillData) {
for (const key in prefillData) {
params.append(key, prefillData[key]);
}
}
const surveyUrl = baseUrl + "?" + params.toString();
// Open the survey
window.location.href = surveyUrl;
// Optional: Detect if app is not installed (mobile only)
setTimeout(() => {
if (document.hidden) {
// App opened successfully
console.log("Survey app launched");
} else {
// On mobile, redirect to app store if app not installed
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
if (/android/i.test(userAgent)) {
window.location.href = "https://play.google.com/store/apps/details?id=com.esri.survey123";
} else if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
window.location.href = "https://apps.apple.com/app/arcgis-survey123/id993015031";
}
}
}, 1500);
}
// Example usage
launchSurveyApp("abc123def456ghi789", {
"inspector_name": "John Doe",
"date": new Date().toISOString()
});External systems integration
You can integrate the Field App with other applications using webhooks.
Webhooks for real-time integration
Configure webhooks to receive notifications when surveys are submitted through the Field App. Webhooks are configured through the ArcGIS Feature Layer's webhook management:
// Configure webhook using ArcGIS REST API
const featureLayerUrl = "https://services.arcgis.com/your_org/arcgis/rest/services/your_survey/FeatureServer/0";
const webhookPayload = {
name: "Survey123 Submission Webhook",
hookUrl: "https://your-system.com/webhook/survey123",
changeTypes: "INSERT,UPDATE,DELETE",
signatureKey: "your-signature-key",
active: true,
f: "json",
token: "YOUR_ACCESS_TOKEN"
};
// POST to create webhook
fetch(`${featureLayerUrl}/createWebhook`, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: new URLSearchParams(webhookPayload)
})
.then(response => response.json())
.then(result => {
console.log("Webhook created:", result);
})
.catch(error => {
console.error("Error creating webhook:", error);
});You can process incoming webhook from Survey123 using the ArcGIS REST API. Below is an example of how to process incoming webhook from Survey123.
// Process incoming webhook from Survey123
app.post('/webhook/survey123', function(req, res) {
var eventType = req.body.eventType;
var surveyInfo = req.body.surveyInfo;
var feature = req.body.feature;
var userInfo = req.body.userInfo;
if (eventType === 'addData') {
// Process new survey submission from Field App
processNewSubmission(feature.attributes);
// Example: Create workflow task
createWorkflowTask(feature.attributes);
// Example: Send notification
sendNotification(surveyInfo.name, userInfo.username);
}
res.status(200).send('OK');
});Data export and integration
Export survey data collected by the Field App for integration with external systems:
| Format | Use Case | Access Method |
|---|---|---|
| CSV | Spreadsheet analysis, data import | Feature Layer REST API with f=csv |
| JSON | Web application integration | Feature Layer REST API with f=json |
| GeoJSON | GIS platform integration | Feature Layer REST API with f=geojson |
| PDF Reports | Document generation | Survey123 REST API report endpoint |
You can use the ArcGIS API for Python to export survey data for integration with external systems. Below is an example of how to export survey data for integration with external systems.
# Export survey data from Field App
import requests
import pandas as pd
import json
def exportSurveyData(featureLayerUrl, token, outputFormat='json'):
"""
Export survey data from ArcGIS Survey123 Field App
Args:
featureLayerUrl: URL of the feature layer containing survey data
token: Authentication token
outputFormat: Export format ('json', 'csv', 'geojson')
Returns:
Exported data or None if error occurs
"""
try:
# Query survey data
url = f"{featureLayerUrl}/query"
params = {
'where': '1=1',
'outFields': '*',
'returnGeometry': True,
'f': 'json',
'token': token
}
response = requests.get(url, params=params)
response.raise_for_status()
data = response.json()
if 'error' in data:
print(f"Error querying data: {data['error']}")
return None
# Process based on output format
if outputFormat == 'csv':
# Convert to CSV using pandas
features = data.get('features', [])
if features:
df = pd.DataFrame([f['attributes'] for f in features])
df.to_csv('survey_export.csv', index=False)
print(f"Exported {len(features)} records to survey_export.csv")
return df
elif outputFormat == 'geojson':
# Convert to GeoJSON
geojson = {
'type': 'FeatureCollection',
'features': []
}
for feature in data.get('features', []):
geojson['features'].append({
'type': 'Feature',
'properties': feature['attributes'],
'geometry': feature.get('geometry')
})
with open('survey_export.geojson', 'w') as f:
json.dump(geojson, f)
print(f"Exported {len(geojson['features'])} records to survey_export.geojson")
return geojson
else: # JSON format
with open('survey_export.json', 'w') as f:
json.dump(data, f, indent=2)
print(f"Exported {len(data.get('features', []))} records to survey_export.json")
return data
except requests.exceptions.RequestException as e:
print(f"Network error: {str(e)}")
return None
except Exception as e:
print(f"Error exporting survey data: {str(e)}")
return None
# Example usage
if __name__ == "__main__":
feature_layer_url = "https://services.arcgis.com/your_org/arcgis/rest/services/your_survey/FeatureServer/0"
access_token = "YOUR_ACCESS_TOKEN"
# Export as CSV
exportSurveyData(feature_layer_url, access_token, 'csv')
# Export as GeoJSON
exportSurveyData(feature_layer_url, access_token, 'geojson')Best practices
Follow these essential best practices for extending and integrating the Survey123 Field App:
- Design for offline-first: Optimize surveys and integrations for offline data collection scenarios
- Use appropriate integration methods: Choose the right approach (URL schemes, webhooks, REST API) for your use case
- Handle authentication properly: Implement secure authentication for external system integrations
- Test on mobile devices: Verify integrations work correctly on actual mobile devices and networks
- Monitor performance: Track data synchronization and app performance in field conditions
Code examples
Manage your surveys programmatically
Developers can manage surveys and data collection programmatically using the ArcGIS API for Python:
// Access Survey123 data via REST API
const surveyUrl = "https://survey123.arcgis.com/api/surveys/your_survey_id";
const token = "YOUR_ACCESS_TOKEN";
// Get survey metadata
fetch(surveyUrl + "?token=" + token)
.then(response => response.json())
.then(survey => {
console.log("Survey title:", survey.title);
console.log("Feature layer:", survey.featureLayerUrl);
});
// Query survey responses
const featureLayerUrl = "https://services.arcgis.com/your_org/arcgis/rest/services/your_survey/FeatureServer/0";
const queryUrl = featureLayerUrl + "/query?where=1=1&outFields=*&f=json&token=" + token;
fetch(queryUrl)
.then(response => response.json())
.then(data => {
console.log("Survey responses:", data.features);
});Integrate with other applications
Integrate the Field App with other applications using URL schemes:
// Launch Survey123 Field App with URL scheme integration
function launchSurveyApp(surveyId, prefillData, useCustomScheme) {
var baseUrl = useCustomScheme ? "arcgis-survey123://" : "https://survey123.arcgis.app";
var params = new URLSearchParams({
itemID: surveyId
});
// Add callback URL (use 'callback' for app link, 'returnURL' for custom scheme)
if (useCustomScheme) {
params.append("returnURL", window.location.href);
} else {
params.append("callback", encodeURIComponent(window.location.href));
}
// Add prefill data
if (prefillData) {
for (var key in prefillData) {
params.append(key, prefillData[key]);
}
}
var surveyUrl = baseUrl + "?" + params.toString();
// Try to open the survey
window.location.href = surveyUrl;
// Fallback to app store if app not installed (mobile only)
setTimeout(function() {
if (document.hidden) {
// App opened successfully
console.log("Survey app launched");
} else {
// Detect platform and redirect to appropriate store
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
if (/android/i.test(userAgent)) {
window.location.href = "https://play.google.com/store/apps/details?id=com.esri.survey123";
} else if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
window.location.href = "https://apps.apple.com/app/arcgis-survey123/id993015031";
}
}
}, 1500);
}
// Example usage with app link (recommended)
launchSurveyApp("abc123def456", {
"inspector_name": "John Doe",
"location": "Building A"
}, false);
// Example usage with custom scheme (alternative)
launchSurveyApp("abc123def456", {
"inspector_name": "Jane Smith",
"site_id": "SITE-001"
}, true);Configure offline capabilities
Programmatically configure offline capabilities for field deployment:
from arcgis.gis import GIS
from arcgis.features import FeatureLayer
import requests
# Configure offline survey deployment
def configureOfflineSurvey(feature_layer_url, username, password):
# Connect to ArcGIS Online
gis = GIS("https://www.arcgis.com", username, password)
# Get the feature layer
feature_layer = FeatureLayer(feature_layer_url, gis=gis)
# Configure offline settings for the feature layer
offline_config = {
"supportsOffline": True,
"maxRecordCount": 1000,
"syncEnabled": True,
"syncCapabilities": {
"supportsAsync": True,
"supportsRegisteringExistingData": True,
"supportsSyncDirectionControl": True,
"supportsPerLayerSync": True,
"supportsPerReplicaSync": False,
"supportsRollbackOnFailure": False,
"supportsAttachmentsSyncDirection": True
}
}
# Update the feature layer definition
update_result = feature_layer.manager.update_definition(offline_config)
if update_result['success']:
print("Offline configuration updated successfully")
return feature_layer
else:
raise Exception("Failed to update offline configuration")
# Create offline replica for survey data
def createOfflineReplica(feature_layer_url, extent, username, password):
gis = GIS("https://www.arcgis.com", username, password)
feature_layer = FeatureLayer(feature_layer_url, gis=gis)
# Create replica parameters
replica_params = {
"replicaName": f"SurveyOffline_{int(time.time())}",
"layers": "0",
"geometry": extent,
"geometryType": "esriGeometryEnvelope",
"inSR": "4326",
"outSR": "4326",
"transportType": "esriTransportTypeUrl",
"returnAttachments": True,
"returnAttachmentsDataByUrl": False,
"async": False,
"syncModel": "none",
"dataFormat": "filegdb"
}
# Create the replica
replica_result = feature_layer.replicas.create(replica_params)
if replica_result['success']:
print(f"Offline replica created: {replica_result['replicaUrl']}")
return replica_result
else:
raise Exception("Failed to create offline replica")
# Usage example
import time
# Configure offline capabilities
feature_layer_url = "https://services.arcgis.com/your-org/arcgis/rest/services/YourSurvey/FeatureServer/0"
extent = {
"xmin": -122.5,
"ymin": 37.7,
"xmax": -122.3,
"ymax": 37.8,
"spatialReference": {"wkid": 4326}
}
try:
# Configure offline settings
layer = configureOfflineSurvey(feature_layer_url, "username", "password")
# Create offline replica
replica = createOfflineReplica(feature_layer_url, extent, "username", "password")
except Exception as e:
print(f"Error: {e}")Tutorials

Create a simple survey
Learn how to use ArcGIS Survey123 to create a simple survey.
Low-code/no-code

Analyze survey results
Learn how to use ArcGIS Survey123 to analyze survey results.
Low-code/no-code

Create a survey and dashboard for park maintenance
Learn how to integrate ArcGIS Survey123 with ArcGIS Dashboards to create a reporting solution.
Low-code/no-code

Create a smarter, responsive survey
Learn how to create intelligent surveys with conditional logic, hidden fields, and dynamic visibility using ArcGIS Survey123 and XLSForm.
Low-code/no-code