Skip to content

Usage

Authentication

To use the api, you must have an api key provided by Spatial. All requests must contain a header with your key in the x-api-key field.

API Endpoints

get_segment

This GET endpoint returns the segment information for a single record. It accepts the same parameters that would be in a file upload. The code below shows examples of a get_segment request encoded in the url or sent in json format.

Example (Python):

headers = {'x-api-key':'my_key'}
result = requests.get(
    'https://api.persona.spatial.ai/get_segment?address=20 mercer st&city=cincinnati&zip=45202',
    headers=headers
)

result.json()
{
    'address': '20 mercer st',
    'city': 'cincinnati',
    'state': 'OH',
    'zip': '45202',
    'Segment': 'G03 - #Urbanists',
    'Family': 'G - Educated Urbanites',
    'Match Level': 'ADDRESS'
}
or
headers={'x-api-key':'my_key'}
result = requests.get(
    'https://api.persona.spatial.ai/get_segment',
    data = json.dumps({
        'address':'20 Mercer St',
        'city':'cincinnati',
        'zip':'45202'
    }),
    headers=headers
)

result.json()
{
    'address': '20 mercer st',
    'city': 'cincinnati',
    'zip': '45202',
    'Segment': 'G03 - #Urbanists',
    'Family': 'G - Educated Urbanites',
    'Match Level': 'ADDRESS'
}


live_topics

This GET endpoint takes a segment and returns the current list of live topics.

Example (Python):

headers={'x-api-key':'my_key'}
segment = 'a01'
result = requests.get(
    'https://api.persona.spatial.ai/segment_data/live_topics?segment=' + segment,
    headers=headers
)

result.json()
{'request_url': '/segment_data/live_topics?segment=a01',
 'topics': ['#investors',
            '#ust',
            '#hitmc',
            '#agencyoftheyear',
            '#steveschmidt',...]
}            

live_visitation

This GET endpoint takes a segment and returns live visitation scores.

Example (Python):

headers={'x-api-key':'my_key'}
segment = 'a01'
result = requests.get(
    'https://api.persona.spatial.ai/segment_data/live_visitation?segment=' + segment,
    headers=headers
)

result.json()
{'request_url': '/segment_data/live_visitation?segment=a01',
'live-visitation.dates': ['2021-04-01',
                           '2021-05-01',
                           '2021-06-01',
                           '2021-07-01',
                           '2021-08-01',
                           '2021-09-01',
                           '2021-10-01',
                           '2021-11-01',
                           '2021-12-01',
                           '2022-01-01',
                           '2022-02-01',
                           '2022-03-01',
                           '2022-04-01'],
 'hotels': {'Courtyard by Marriott': [146.0,
                                      143.0,
                                      168.0,
                                      197.0,
                                      169.0,
                                      163.0,
                                      176.0,
                                      173.0,
                                      145.0,
                                      149.0,
                                      183.0,
                                      224.0,
                                      224.0],
            'Doubletree by Hilton': [141.0,
                                     139.0,
                                     153.0,
                                     175.0,
                                     150.0,
                                     149.0,
                                     164.0,
                                     167.0,
                                     160.0,
                                     148.0,
                                     189.0,
                                     220.0,
                                     225.0],
...}                                                                
}            

get_radius_counts

This POST endpoint takes a list of centers and a radius and returns the count of each segment within.

Example (Python):

headers={'x-api-key':'my_key'}
radiusInMiles = 5
radiusInMeters = radiusInMiles*1609.344
latitude = 39.1
longitude = -84.5
result = requests.post(
    'https://api.persona.spatial.ai/file_upload/get_radius_counts',
    data=json.dumps({'centers':[[longitude, latitude]],'radius':radiusInMeters}),
    headers=headers
)

result.json()
{'counts': 
    {'A01': 196, 'A02': 234, 'A03': 384, ...}
}            

process_file

This POST endpoint takes an uploaded CSV (described below) and processes it. It will return a job_id, which you will need to get the results.

Example (Python):

headers={'x-api-key':'my_key'}
result = requests.post(
    'https://api.persona.spatial.ai/process_file',
    data=open('my_data.csv','rb'),
    headers=headers
)

result.json()
{'job_id':'000000'}

get_job_status

This GET endpoint takes a job_id and returns its status. The only parameter it accepts is job_id.

Example (Python):

headers={'x-api-key':'my_key'}
result = requests.get(
    'https://api.persona.spatial.ai/get_job_status?job_id=00000',
    headers=headers
)

result.json()
{
   "job_id":"000000",
   "status":"COMPLETE. 17 records processed"
}

get_job_results

This GET endpoint downloads the results of a completed job. The only parameter it accepts is job_id.

Example (Python):

headers={'x-api-key':'my_key'}
result = requests.get(
    'https://api.persona.spatial.ai/get_job_results?job_id=00000',
    headers=headers
)

result.text
'id,Segment,Family,Match Level\n0,G03 - #Urbanists,G - Educated Urbanites,NAME\n'

Input File Format

The input file should contain one header line, followed by any number of individual records to be matched. Each field should be separated by a comma, pipe, or tab character and each line should be separated by a newline. The file itself should be in utf-8 format and can optionally be compressed in zip or gzip format. The file should have a .csv, .zip, or .gz extension.

The file can contain any number of fields, but to protect PII the processed file will not return them all back (see Output File below). We strongly recommend including an id field so you can match results back to your own records — without one, results can only be tied back by row order. Only specific fields will be used for matching, these include :

  • id - a unique identifier for each record
  • full_name - combined first and last name, without prefixes (e.g. Mrs.) or suffixes (e.g. Jr.). Skip this if you are using the split name fields below
  • first_name
  • middle_name
  • last_name
  • address - full address in one column, including street info, apartment number, city, state, and zip (e.g. "1008 Race Street, Cincinnati, OH, 45202"). Skip this if the components are split across columns
  • address_line_1 - street address. Skip if you are using the single 'address' field
  • address_line_2 - apartment number if applicable
  • city
  • state - abbreviations ("OH") and full state names ("Ohio") are both accepted
  • zip - 5-digit code (any "+4" extension is ignored)
  • email - include the domain name (e.g. gmail.com) and remove any spaces
  • email_hash - the SHA-256 hash of the lowercased email address. Use this if you prefer not to send plain email addresses
  • CBG - block group
  • lat - latitude
  • long - longitude
  • clat - central latitude. Use 'clat' and 'clng' together to search for individuals by name within a 25 mile radius of a known location, when you only have an approximate location
  • clng - central longitude. Must be paired with 'clat'

All of these are optional, but to get a match each record must include either a geographic component (address, block group, or lat/long pair) or an email (plain or hashed). The more fields that are provided, the more accurate the match will be.

This API does NOT perform geocoding. If you do not include a zip code, block group ID, or latitude and longitude (this is preferable), we will only find exact name, address, or email matches. This will lower your overall match rate. If you do include this info, we can include the dominant segment and family from the given block group or zip code when we can't find a more specific match.

Example Input

id first_name last_name address_line_1 address_line_2 city state zip email lat lng
0 john doe 1008 Race Street Suite 1 Cincinnati OH 45202 john@email.com 39.10621 -84.5156
1 john smith 100 E Spring Street Columbus OH 43215 39.9669 -82.9983

Watch Outs

A couple of things to double check you are handling correctly in order to have the best match rate:

  • Zip codes must be 5 digits. Many softwares cut off zeros at the beginning of zip codes. Make sure the data you upload doesn't have this issue.
  • Similarly, Census block group IDs must be 12 digits.

Output File

Once a job is complete, download the results with get_job_results. To protect PII, the output does not include the matching fields you uploaded (names, addresses, emails, etc.) — it contains your id column and three additional fields:

  • Segment - Name of the segment which this record is classified as.
  • Family - Name of the family of segments to which this record's segment belongs.
  • Match Level - Accuracy of the match. Possible values (in order of accuracy):
    • EMAIL - Highest match level, the input email (or hashed email) was matched directly to an individual.
    • NAME - The input name and address were matched.
    • ADDRESS - Address matched, but exact name not found.
    • BLOCKGROUP- Neither name nor address matched. Dominant segment in block group used. Only available if blockgroup or latitude and longitude coordinates are provided.
    • ZIP - Neither name nor address matched. Dominant segment in zip code used. If unable to make a block group level match, zip code is used.
    • NO MATCH - Not able to match record.

Example Output

id Segment Family Match Level
0 A01 - #MidasMight A - Ultra Wealthy Families NAME
1 Q06 - #BlueCollarGrit Q - Urban Low Income ADDRESS
Back to top