IO Reports API
Descriptionβ
IO Reports API is an IO Reports product feature that provides customers with the ability to generate Neighborhood Lifestyle Reports or Neighborhood Market Reports via an API call. With this feature, customers do not need an SSO integration and can generate reports without manual use of the IO Reports dashboard. It can be used to power calls to action, CRM campaigns for leads, and to automatically provide agents and homeseekers with in-depth neighborhood reports at scale.
As with reports manually generated and shared, the reports are always loaded with the latest neighborhood data and agent personalization. As new points of interest are added, or scores are recomputed, or neighborhood boundaries change, the contents of IO Reports will change. And as agents update contact information or new profile photos for the reports, past reports are also updated.
Authentication Optionsβ
IO Reports API offers two mechanisms for authentication, outlined below. For any clients wishing to include agent information and personalize the report, the authentication tokens provided below are per-agent.
Local Logic Client ID + Secretβ
Once granted access for IO Reports, you can leverage your Local Logic client ID and client secret through a call to get a Local Logic bearer token.
You should never store your Local Logic client ID and client secret on a website, as unauthorized users will be able to access it and generate reports. They could even update reports you've already sent to clients to add filters and remove sections!
You should also never store the returned bearer token on a public website, but it is safe to store these tokens on internal pages.
To retrieve the access_token which can be used for all IO Reports API calls:
# Generic token - no agent personalization or only a single, default agent
POST https://api.locallogic.co/oauth/token
Body:
{
"client_id"="{CLIENT_ID}",
"client_secret"="{CLIENT_SECRET}",
"audience"="reports-api"
}
# Personalized token for a specific agent
POST https://api.locallogic.co/oauth/token
Body:
{
"client_id"="{CLIENT_ID}",
"client_secret"="{CLIENT_SECRET}",
"audience"="reports-api",
"agent_id"="{AGENT_ID}"
}
Custom JWT Flowβ
Alternatively, Local Logic can support custom JWT authentication via a "soft" integration to better support front-end generation of reports within a web view (such as tied to buttons or forms on a listing page).
This flow has the following requirements:
- Local Logic requires a copy of a JWKS (JSON Web Key Set) with public keys to verify JWTs
- The supplied JWTs are valid for a maximum of 24 hours (after which they will be refused)
- Local Logic requires a JWT with the following format be passed to
https://api.locallogic.co/oauth/token:
{
"iss": "{YOUR_API_DOMAIN}",
"sub": "{AGENT_CLIENT_ID}@clients",
"aud": "https://reports-api.locallogic.co/",
"gty": "client_credentials",
"azp": "{AGENT_CLIENT_ID}",
"provider": "{PROVIDER_CODE}",
"iat": {ISSUED_UNIX_TIMESTAMP},
"exp": {EXPIRY_UNIX_TIMESTAMP}
}
POST /v1/reportsβ
This endpoint is used to generate a report once a valid reports-api bearer token has been retrieved as explained in the above section. It returns both a report ID, and a report URL that can be used as a permalink to load the latest location data for the report location over time.
We recommend using this endpoint to generate always-up-to-date report links for all locations and agents who will use IO Reports. For example, this endpoint can be called each time a new listing is added. Per location, the single returned URL can be saved and shared to multiple users, rather than generating a unique report URL for each individual report that you want to share.
POST /v1/reports
Headerβ
This API uses JWT token based authentication. This JWT Bearer token is what is used to populate the
Authorization header below.
Instructions on how to retrieve this token can be found in the proceeding sections of this document.
| Header | Status | Description |
|---|---|---|
| Authorization | required | Your bearer token retrieved from our authorization API, ex. Bearer eyJhbGci... |
| Accept | required | The datatype to request, this API will return application/json. |
Body Parametersβ
| Parameter | Status | Description |
|---|---|---|
| lat | optional* | A decimal number between -90 and 90, representing the latitude. * Required for address-based reports, which are generated with lat/lng. |
| lng | optional* | A decimal number between -180 and 180, representing the longitude. * Required for address-based reports, which are generated with lat/lng. |
| geog_id | optional* | The geog_id for neighborhood based reports. Valid geographies are those below level 40: those starting with g10_, g20_, g30_, g32_, g35_, g37_ and g38_.* Required for geography-based reports, which concern a whole neighborhood or municipality. |
| address_label | optional* | An address label to displayed on the front page of the report. It can be the name of a neighborhood, but it generally represents the street address, followed by the city name. * Required for address-based reports, which are generated with lat/lng. For geography-based reports, by default the name of the neighborhood or community will be used. |
| language | required | The language for the report. Currently this is required, but en (English) is the only valid option. |
| type | required | The report type to be generated, either Neighborhood Lifestyle Report (for Canada or the US; formerly NeighborhoodIntel) or Neighborhood Market Report (US-only). Available: ni and nmr |
| disabled_pages | optional | Used to hide certain sections of the IO Reports upon generation. This is an optional array. Available ( ni): amenities, character, climate, community_portrait, education, highlights, nature, profiles, transportation, trends.Available ( nmr): selling_speed, home_cost, time_to_buy, market_timeframe, market_snapshot, value_drivers. |
| filters | optional | Only valid for Neighborhood Market Reports. Used to specify report filters for the neighborhood, property type, and time frame.area: An array of valid geog_ids.***property_type: A valid property_type as explained in the market stats API documentation.time_frame: One of 1y, 3y, or 5y.Ex: {"area":["g20_dr4e16mj"],"property_type":"condo_townhome","time_frame":"1y"} |
Usage examplesβ
- NodeJS
- Python
// Address-based report
require('node-fetch')('https://reports-api.locallogic.co/v1/reports', {
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: 'Bearer eyJhbGciOiJ...'
},
body: JSON.stringify({
lat: 39.92422,
lng: -75.15548,
address_label: '500 Dudley St, Philadelphia, PA 19148',
language: 'en',
type: 'nmr'
})
})
.then(response => response.json())
.then(body => {
console.log(body)
})
.catch(error => {
console.log(error)
})
// Geography-based report
require('node-fetch')('https://reports-api.locallogic.co/v1/reports', {
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: 'Bearer eyJhbGciOiJ...'
},
body: JSON.stringify({
geog_id: 'g20_dr4e16mj',
language: 'en',
type: 'nmr'
})
})
.then(response => response.json())
.then(body => {
console.log(body)
})
.catch(error => {
console.log(error)
})
import requests
# Address-based report
response = requests.post(
"https://reports-api.locallogic.co/v1/reports",
headers={
"Accept": "application/json",
"Authorization": "Bearer eyJhbGciOiJ..."},
json={
"lat": 39.92422,
"lng": -75.15548,
"address_label": "500 Dudley St, Philadelphia, PA 19148",
"language": "en",
"type": "nmr"
}
)
print(response.json())
# Geography-based report
response = requests.post(
"https://reports-api.locallogic.co/v1/reports",
headers={
"Accept": "application/json",
"Authorization": "Bearer eyJhbGciOiJ..."},
json={
"geog_id": "g20_dr4e16mj",
"language": "en",
"type": "nmr"
}
)
print(response.json())
Response exampleβ
{
"report_id": "75952235-13af-48c1-88af-5715a228844a",
"report_url": "https://neighborhoodintel.locallogic.co/nmr/75952235-13af-48c1-88af-5715a228844a"
}
PATCH /v1/agents/meβ
This endpoint is used to update an agent's profile to enable a report to be personalized. Personalization is tied to a specific Bearer Token based on the agent_id. For a fuller example of how this could work in an onboarding flow, please see the guide Personalizing Reports via API.
Although not documented separately on this page, executing a call to GET https://reports-api.locallogic.co/v1/agents/me will return the currently active profile settings associated with the given Bearer Token.
PATCH /v1/agents/me
Headerβ
This API uses JWT token based authentication. This JWT Bearer token is what is used to populate the
Authorization header below.
Instructions on how to retrieve this token can be found in the proceeding sections of this document.
| Header | Status | Description |
|---|---|---|
| Authorization | required | Your bearer token retrieved from our authorization API, ex. Bearer eyJhbGci... |
| Accept | required | The datatype to request, this API will return application/json. |
Body Parametersβ
| Parameter | Status | Description |
|---|---|---|
| first_name | optional | The user's first name for the agent profile. Limit of 20 characters. |
| last_name | optional | The user's last name for the agent profile. Limit of 20 characters. |
| company_name | optional | The name of the company for the agent profile. Limit of 50 characters. |
| company_website | optional | The URL of the company website for the agent profile. Limit of 150 characters. |
| description | optional | The user's biography/description for the agent profile. Limit of 300 characters. |
| optional | The user's email for the agent profile. Limit of 50 characters. | |
| is_personalization_active | optional | A boolean TRUE/FALSE representing whether this user's reports will show their agent profile. This option can be enabled retroactively and affects all reports generated for a specific user. |
| links | optional | An array of up to 3 strings representing URLs for social links or other online profiles. Each string in the array should be 150 characters or less. |
| phone | optional | The user's phone number for the agent profile. Limit of 12 characters. No formatting is applied to this value on the report itself, so include hyphens and necessary formatting. |
Usage examplesβ
- NodeJS
- Python
// Update profile
require('node-fetch')('https://reports-api.locallogic.co/v1/agents/me', {
method: 'PATCH',
headers: {
Accept: 'application/json',
Authorization: 'Bearer eyJhbGciOiJ...'
},
body: JSON.stringify({
first_name: 'John',
last_name: 'Smith',
email: 'john.smith@gmail.com',
phone: '706-999-9999'
})
})
.then(response => response.json())
.then(body => {
console.log(body)
})
.catch(error => {
console.log(error)
})
// Get current profile
require('node-fetch')('https://reports-api.locallogic.co/v1/agents/me', {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: 'Bearer eyJhbGciOiJ...'
}
})
.then(response => response.json())
.then(body => {
console.log(body)
})
.catch(error => {
console.log(error)
})
import requests
# Update profile
response = requests.patch(
"https://reports-api.locallogic.co/v1/agents/me",
headers={
"Accept": "application/json",
"Authorization": "Bearer eyJhbGciOiJ..."},
json={
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@gmail.com",
"phone": "706-999-9999"
}
)
print(response.json())
# Get current profile
response = requests.get(
"https://reports-api.locallogic.co/v1/agents/me",
headers={
"Accept": "application/json",
"Authorization": "Bearer eyJhbGciOiJ..."}
)
print(response.json())
Response exampleβ
{
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@gmail.com",
"phone": "706-999-9999"
}
PUT /v1/agents/me/logoβ
This endpoint is used to upload a personalized agent logo to be shown on reports. Personalization (including the logo) is tied to a specific Bearer Token based on the agent_id. The maximum logo size is 10 MB.
PUT /v1/agents/me/logo
Headerβ
This API uses JWT token based authentication. This JWT Bearer token is what is used to populate the
Authorization header below.
Instructions on how to retrieve this token can be found in the proceeding sections of this document.
| Header | Status | Description |
|---|---|---|
| Authorization | required | Your bearer token retrieved from our authorization API, ex. Bearer eyJhbGci... |
| Accept | required | The datatype to request, this API will return application/json. |
Body Parametersβ
| Parameter | Status | Description |
|---|---|---|
| logo | required | The user's logo for personalized IO Reports. Sent as binary data, with a maximum of 10 MB |
Usage examplesβ
- NodeJS
- Python
// Update profile
const fs = require('fs');
const FormData = require('form-data');
const form = new FormData();
form.append('logo', fs.createReadStream('logo.png'));
const imageBuffer = fs.readFileSync('logo.png');
require('node-fetch')('https://reports-api.locallogic.co/v1/agents/me/logo', {
method: 'PUT',
headers: {
Accept: 'application/json',
Authorization: 'Bearer eyJhbGciOiJ...',
form.getHeaders()
},
body: form
})
.then(response => response.json())
.then(body => {
console.log(body)
})
.catch(error => {
console.log(error)
})
import requests
with open("awesome-logo.png", "rb") as fp:
binary_data = fp.read()
response = requests.put(
"https://reports-api.locallogic.co/v1/agents/me/logo",
headers={
"Accept": "application/json",
"Authorization": "Bearer eyJhbGciOiJ...",
"Content-Type": "multipart/form-data"},
json={
"logo": binary_data
}
)
print(response.json())
Additional Report API Endpointsβ
This page highlights both the authentication flow for IO Reports API, as well as the options available when generating a report. However, a number of further IO Reports API endpoints are available to support other features and remain available on our auto-generated technical documentation site, including: