Import geofences
Import circles and polygons into a geofence set from a GeoJSON, GeoJSONL, or CSV file.
To import multiple geofences, first create a geofence set. Then create either a GeoJSON file or CSV file with the required fields. You can import up to 10,000 geofences per geofence set, and the file must be less than 32 MB. GeoJSON files, including GeoJSONL files, can contain circles, polygons, or both. CSV files only support circles.
You can also import a file with the import endpoint in the App API by setting type to geoset. The file uses the same formats and fields as an import in the UI, and your set’s geoset_id is the number after geosets/ in the set’s URL.
- Select a geofence set.
- Click Import.
- Upload a GeoJSON or CSV file.
- Decide how to run the import:
- Choose Add and update if you want to add new geofences and update existing geofences. If the geofence shares an ID with other geofences, every geofence with that ID updates to match the new settings, even if the geofence is in a different geofence set.
- Choose Replace all if you want to replace all geofences in the set with only what’s in the import file. This only removes geofences from this set; if a deleted geofence shares an ID with a geofence in another set, the other geofence set keeps the geofence.
- Click Import files.
You can preview the geofences after importing.
GeoJSON
GeoJSON is a geospatial data interchange format based on JavaScript Object Notation (JSON). You can learn about the spec through the IETF and validate your spec before import at geojson.io.
This example contains a circular geofence and a polygon geofence:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "hq-sf",
"geometry": {
"type": "Point",
"coordinates": [
-122.4194,
37.7749
]
},
"properties": {
"name": "HQ",
"radius": 250,
"promo_code": "HQ10"
}
},
{
"type": "Feature",
"id": "campus-sf",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-122.394, 37.794],
[-122.39, 37.794],
[-122.39, 37.798],
[-122.394, 37.798],
[-122.394, 37.794]
]
]
},
"properties": {
"name": "Campus",
"promo_code": "CAMPUS10"
}
}
]
}The following fields are required unless noted otherwise:
| Field | Description |
|---|---|
type | Must be “FeatureCollection” |
features | An array of objects, where each object is a geofence |
features. | Must be “Feature” |
features. | A unique identifier for the feature; if you leave this blank, Customer.io generates a UUID |
features. | An object with a type and coordinates |
features. | Use Point for a circle or Polygon for a polygon. You can’t use other geometry types, including MultiPolygon. |
features. | For a circle, use [<longitude>, <latitude>]. For a polygon, use one array of coordinate pairs that meets the polygon requirements. |
features. | An object with a name and any additional custom properties you want to store with the geofence. Circles also require a radius. |
features. | The name of your geofence |
features. | Required for circles. Integer representing the radius in meters, from 100–10,000. Remove this property from polygons; otherwise, validation rejects the feature. Customer.io calculates the enclosing circle from the polygon boundary. |
features. | (Optional) The time, in seconds, that a person needs to stay inside the geofence before the SDK sends a dwell event. Use 0 or null to turn dwell events off. Omit this property to keep the current dwell time. |
features. | (Optional) Any additional properties—like a location ID, category, or deeplink slug—are stored as the geofence’s attributes. Values keep their JSON types, so numbers and true/false stay numbers and booleans. |
You can also upload a GeoJSONL file (.geojsonl), which puts one Feature object on each line instead of wrapping features in a FeatureCollection. Each line uses the same features.* fields as the preceding table. When you export a geofence set, Customer.io writes the export in this format, so you can edit an export and import it again without converting it.
CSV
To import multiple geofences from a CSV file, create a CSV file with these fields. All fields are required except where noted:
| Field | Description |
|---|---|
name | The name of your geofence |
radius | Integer. Represents radius in meters. Must be within 100–10,000. |
longitude | The longitude of your geofence |
latitude | The latitude of your geofence |
external_id | (Optional) A unique identifier for the feature; if you leave this blank, Customer.io generates a UUID |
dwell_threshold_seconds | (Optional) The time, in seconds, that a person needs to stay inside the geofence before the SDK sends a dwell event. Use 0 to turn dwell events off. Leave empty to keep the current dwell time. |
Any other column becomes a custom attribute on each geofence, named after the column header. Customer.io stores these values as text, so use GeoJSON if you need an attribute to be a number or true/false. Use the column names in the table exactly as written, in lowercase. A column that only differs from one of them by capitalization, like Name, makes the import fail.
From the import UI, you can download a CSV template to help you create your file.
Polygon requirements
Whether you draw a polygon in Customer.io or import it with GeoJSON, it must meet these requirements:
- Use one boundary with 3–500 points.
- Use a convex shape. The boundary can’t turn inward or include a cut-out, such as an L or T shape. To exclude a building at the corner of a larger area, use two rectangular geofences to cover the remaining space. Customer.io tracks each rectangle as a separate geofence.
- Don’t use holes, crossing edges, or duplicate adjacent points.
- The enclosing radius of the polygon must be no smaller than 100 meters and no larger than 10 kilometers.
- Keep every point between -85° and 85° latitude, and don’t draw a polygon across the 180° longitude line.
For GeoJSON imports, you must also:
- Close the boundary by repeating its first point at the end. The repeated closing point does not count toward the 500-point limit.
- Start each coordinate with longitude followed by latitude. Customer.io ignores additional numeric values such as altitude, but rejects non-numeric values.
- Remove
latitude,longitude, andradiusfrom the feature’sproperties. Customer.io calculates the center and enclosing circle from the polygon boundary.
If a GeoJSON file contains at least one polygon, every feature in the file must be valid before you can import it.
Polygons must be convex
Mobile operating systems don’t report polygon crossings, so the SDK works out for itself which side of the boundary a person is on. Each location reading comes with an accuracy radius: how far off the real position might be. A reading that lands within that distance of the boundary could belong on either side, so it’s less reliable than one that lands well inside or well outside.
Concave shapes have pockets of outside space that reach into the boundary. The U below is an extreme example, but any inward turn creates a smaller pocket. A reading in a narrow pocket can land near both walls, and it can be tough to determine whether someone is in or out of the boundary. Because these pockets make detection less reliable, Customer.io only supports convex polygons for now.
Convex boundary
Uncertainty stays in a thin strip along the edge, and a straight walk across the inside never crosses the boundary.
Concave boundary
A gap that reaches into the shape puts a reading near two walls at once, and the same walk leaves the boundary and comes back.