API Reference
Complete reference for all available API endpoints. All endpoints require authentication via x-api-key header unless noted otherwise.
Base URL: http://localhost:3000
POST/api/v1/score
Score any Canadian address or coordinate pair for sign placement viability. Returns an overall score (0-100), letter grade, and per-factor breakdown across 7 dimensions. Supports custom weight profiles.
Request Body
| Field | Type | Required | Description |
|---|
address | string | No | Street address to score (use this OR lat/lng) |
lat | number | No | Latitude (use with lng instead of address) |
lng | number | No | Longitude (use with lat instead of address) |
weights | object | No | Custom weight profile — keys: vehicleTraffic, roadClass, populationDensity, income, poiDensity, pedestrian, transit. Values must sum to 1.0 |
Response
| Field | Type | Description |
|---|
overallScore | number | Composite score 0-100 |
grade | string | Letter grade (A+, A, B+, B, C+, C, D, F) |
address | string | Resolved display address |
lat | number | Latitude |
lng | number | Longitude |
factorScores | object | Per-factor breakdown with score, weight, label, and raw value |
dataSources | object | Attribution for each data source used |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/score \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"address":"example","lat":"value","lng":"value","weights":"value"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/score", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"address":"example","lat":"value","lng":"value","weights":"value"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/score",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"address":"example","lat":"value","lng":"value","weights":"value"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | Missing address or lat/lng, or geocoding failed |
401 | UNAUTHORIZED | Missing or invalid API key |
POST/api/v1/compare
Score 2-5 locations in parallel and return results sorted by score with a winner highlighted.
Request Body
| Field | Type | Required | Description |
|---|
locations | array | Yes | Array of 2-5 objects, each with { address } or { lat, lng } |
weights | object | No | Custom weight profile applied to all locations |
Response
| Field | Type | Description |
|---|
results | array | Array of score results sorted by overallScore descending |
winner | object | The highest-scoring location |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/compare \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"locations":"value","weights":"value"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/compare", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"locations":"value","weights":"value"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/compare",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"locations":"value","weights":"value"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | Must provide 2-5 locations |
401 | UNAUTHORIZED | Missing or invalid API key |
POST/api/v1/ai/query
Natural language interface for sign placement queries. Extracts intent, suggests addresses, and geocodes results. Example: 'Find good sign spots near downtown Toronto for a cafe'.
Request Body
| Field | Type | Required | Description |
|---|
query | string | Yes | Natural language question about sign placement |
Response
| Field | Type | Description |
|---|
intent | string | Classified intent: find_locations, score_location, compare, general_question |
city | string | Extracted city or region |
businessType | string | Extracted business type |
suggestedAddresses | array | Up to 3 specific addresses to score |
geocodedLocations | array | Geocoded lat/lng for each suggested address |
explanation | string | AI reasoning |
suggestedWeights | object | Optimized scoring weights if applicable |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/ai/query \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"query":"example"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/ai/query", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"query":"example"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/ai/query",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"query":"example"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | Missing query or ANTHROPIC_API_KEY not configured |
POST/api/v1/ai/weights
Generate an optimized scoring weight profile based on a business description. Returns factor weights that sum to 1.0, a profile name, and explanation.
Request Body
| Field | Type | Required | Description |
|---|
businessDescription | string | Yes | Description of the business type and context |
Response
| Field | Type | Description |
|---|
weights | object | Weight object with keys: vehicleTraffic, roadClass, populationDensity, income, poiDensity, pedestrian, transit |
profileName | string | Short name for the generated profile |
explanation | string | 2-3 sentences explaining the weight choices |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/ai/weights \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"businessDescription":"example"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/ai/weights", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"businessDescription":"example"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/ai/weights",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"businessDescription":"example"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | Missing businessDescription or ANTHROPIC_API_KEY not configured |
POST/api/v1/ai/recommend
Given a location score result, recommends the best sign type (Channel Letters, Pylon Signs, etc.) with reasoning, alternatives, and placement tips.
Request Body
| Field | Type | Required | Description |
|---|
scoreResult | object | Yes | Full score result from /api/v1/score |
businessType | string | No | Optional business type for more targeted recommendations |
Response
| Field | Type | Description |
|---|
primaryRecommendation | object | { type, reason } — best sign type |
alternatives | array | Array of { type, reason } alternatives |
tips | array | Actionable placement tips |
estimatedImpact | string | Expected visibility statement |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/ai/recommend \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"scoreResult":"value","businessType":"example"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/ai/recommend", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"scoreResult":"value","businessType":"example"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/ai/recommend",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"scoreResult":"value","businessType":"example"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | Missing scoreResult or ANTHROPIC_API_KEY not configured |
GET/api/v1/projects
Returns all projects for the authenticated user, ordered by most recently updated. Includes saved location coordinates for each project.
Response
| Field | Type | Description |
|---|
id | string | Project UUID |
name | string | Project name |
description | string | Project description |
locations | array | Array of { lat, lng } for saved locations |
createdAt | string | ISO 8601 creation timestamp |
Code Examples
cURL
curl -X GET http://localhost:3000/api/v1/projects \
-H "x-api-key: sk_your_api_key"
JavaScript
const response = await fetch("http://localhost:3000/api/v1/projects", {
method: "GET",
headers: {
"x-api-key": "sk_your_api_key"
},
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.get(
"http://localhost:3000/api/v1/projects",
headers={"x-api-key":"sk_your_api_key"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
401 | UNAUTHORIZED | Not authenticated |
POST/api/v1/projects
Create a new project to organize scored locations.
Request Body
| Field | Type | Required | Description |
|---|
name | string | Yes | Project name |
description | string | No | Optional description |
Response
| Field | Type | Description |
|---|
id | string | New project UUID |
name | string | Project name |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/projects \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"name":"example","description":"example"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/projects", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"name":"example","description":"example"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/projects",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"name":"example","description":"example"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | Project name is required |
401 | UNAUTHORIZED | Not authenticated |
GET/api/v1/projects/:id
Get a project by ID with all its saved locations, scores, and grades.
Response
| Field | Type | Description |
|---|
id | string | Project UUID |
name | string | Project name |
locations | array | Saved locations with lat, lng, address, score, grade, monitored status |
Code Examples
cURL
curl -X GET http://localhost:3000/api/v1/projects/:id \
-H "x-api-key: sk_your_api_key"
JavaScript
const response = await fetch("http://localhost:3000/api/v1/projects/:id", {
method: "GET",
headers: {
"x-api-key": "sk_your_api_key"
},
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.get(
"http://localhost:3000/api/v1/projects/:id",
headers={"x-api-key":"sk_your_api_key"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
404 | NOT_FOUND | Project not found or not owned by user |
POST/api/v1/projects/:id/locations
Add a location to a project. The location is automatically scored and the result cached.
Request Body
| Field | Type | Required | Description |
|---|
address | string | No | Address (use this OR lat/lng) |
lat | number | No | Latitude |
lng | number | No | Longitude |
notes | string | No | Optional notes |
Response
| Field | Type | Description |
|---|
id | string | Saved location UUID |
latestScore | number | Score (0-100) |
latestScoreGrade | string | Letter grade |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/projects/:id/locations \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"address":"example","lat":"value","lng":"value","notes":"example"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/projects/:id/locations", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"address":"example","lat":"value","lng":"value","notes":"example"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/projects/:id/locations",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"address":"example","lat":"value","lng":"value","notes":"example"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | Must provide address or lat/lng |
404 | NOT_FOUND | Project not found |
POST/api/v1/projects/:id/share
Create a time-limited shareable link for a project (default 30-day expiry).
Request Body
| Field | Type | Required | Description |
|---|
expiresInDays | number | No | Link expiry in days (default 30) |
Response
| Field | Type | Description |
|---|
shareUrl | string | Full shareable URL |
expiresAt | string | ISO 8601 expiration timestamp |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/projects/:id/share \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"expiresInDays":"value"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/projects/:id/share", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"expiresInDays":"value"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/projects/:id/share",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"expiresInDays":"value"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
404 | NOT_FOUND | Project not found |
GET/api/v1/products
Returns all active sign products with their variants (sizes, materials, prices).
Response
| Field | Type | Description |
|---|
id | string | Product UUID |
name | string | Product name |
slug | string | URL-friendly slug |
category | string | Sign category |
basePriceMin | number | Minimum price across variants |
basePriceMax | number | Maximum price across variants |
variants | array | Array of product variants with size, material, price |
Code Examples
cURL
curl -X GET http://localhost:3000/api/v1/products \
-H "x-api-key: sk_your_api_key"
JavaScript
const response = await fetch("http://localhost:3000/api/v1/products", {
method: "GET",
headers: {
"x-api-key": "sk_your_api_key"
},
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.get(
"http://localhost:3000/api/v1/products",
headers={"x-api-key":"sk_your_api_key"},
)
print(response.json())
GET/api/v1/products/:id
Get a single product by ID with full details and all variants.
Response
| Field | Type | Description |
|---|
id | string | Product UUID |
name | string | Product name |
description | string | Full product description |
variants | array | All available variants |
Code Examples
cURL
curl -X GET http://localhost:3000/api/v1/products/:id \
-H "x-api-key: sk_your_api_key"
JavaScript
const response = await fetch("http://localhost:3000/api/v1/products/:id", {
method: "GET",
headers: {
"x-api-key": "sk_your_api_key"
},
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.get(
"http://localhost:3000/api/v1/products/:id",
headers={"x-api-key":"sk_your_api_key"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
404 | NOT_FOUND | Product not found |
GET/api/v1/cart
Returns the authenticated user's shopping cart with product details for each item.
Response
| Field | Type | Description |
|---|
id | string | Cart item UUID |
quantity | number | Item quantity |
productName | string | Product name |
sizeLabel | string | Size variant label |
price | string | Unit price |
locationContext | object | Optional { lat, lng, address, score } |
Code Examples
cURL
curl -X GET http://localhost:3000/api/v1/cart \
-H "x-api-key: sk_your_api_key"
JavaScript
const response = await fetch("http://localhost:3000/api/v1/cart", {
method: "GET",
headers: {
"x-api-key": "sk_your_api_key"
},
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.get(
"http://localhost:3000/api/v1/cart",
headers={"x-api-key":"sk_your_api_key"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
401 | UNAUTHORIZED | Not authenticated |
POST/api/v1/cart
Add a product variant to the cart. If the variant is already in the cart, the quantity is incremented.
Request Body
| Field | Type | Required | Description |
|---|
productVariantId | string | Yes | UUID of the product variant |
quantity | number | No | Quantity to add (default 1) |
locationContext | object | No | Optional { lat, lng, address, score } for location-aware ordering |
Response
| Field | Type | Description |
|---|
id | string | Cart item UUID |
quantity | number | Updated quantity |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/cart \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"productVariantId":"example","quantity":"value","locationContext":"value"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/cart", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"productVariantId":"example","quantity":"value","locationContext":"value"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/cart",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"productVariantId":"example","quantity":"value","locationContext":"value"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | productVariantId is required |
401 | UNAUTHORIZED | Not authenticated |
PATCH/api/v1/cart
Update the quantity of a cart item.
Request Body
| Field | Type | Required | Description |
|---|
cartItemId | string | Yes | Cart item UUID to update |
quantity | number | Yes | New quantity (must be >= 1) |
Response
| Field | Type | Description |
|---|
id | string | Cart item UUID |
quantity | number | Updated quantity |
Code Examples
cURL
curl -X PATCH http://localhost:3000/api/v1/cart \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"cartItemId":"example","quantity":"value"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/cart", {
method: "PATCH",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"cartItemId":"example","quantity":"value"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.patch(
"http://localhost:3000/api/v1/cart",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"cartItemId":"example","quantity":"value"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | cartItemId and positive quantity are required |
404 | NOT_FOUND | Cart item not found |
DELETE/api/v1/cart
Remove an item from the cart by ID (query param ?id= or JSON body { cartItemId }).
Request Body
| Field | Type | Required | Description |
|---|
cartItemId | string | Yes | Cart item UUID to remove |
Response
| Field | Type | Description |
|---|
deleted | boolean | true if successfully removed |
Code Examples
cURL
curl -X DELETE http://localhost:3000/api/v1/cart \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"cartItemId":"example"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/cart", {
method: "DELETE",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"cartItemId":"example"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.delete(
"http://localhost:3000/api/v1/cart",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"cartItemId":"example"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | Cart item id is required |
404 | NOT_FOUND | Cart item not found |
GET/api/v1/orders
Returns all orders for the authenticated user with items and product names.
Response
| Field | Type | Description |
|---|
id | string | Order UUID |
status | string | Order status: ordered, in_production, shipped, installed |
total | string | Order total |
trackingNumber | string | Shipping tracking number (if shipped) |
items | array | Order line items with product details |
createdAt | string | ISO 8601 order timestamp |
Code Examples
cURL
curl -X GET http://localhost:3000/api/v1/orders \
-H "x-api-key: sk_your_api_key"
JavaScript
const response = await fetch("http://localhost:3000/api/v1/orders", {
method: "GET",
headers: {
"x-api-key": "sk_your_api_key"
},
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.get(
"http://localhost:3000/api/v1/orders",
headers={"x-api-key":"sk_your_api_key"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
401 | UNAUTHORIZED | Not authenticated |
POST/api/v1/quotes
Submit a request for a custom sign quote. Provide sign type, size, requirements, and optional location.
Request Body
| Field | Type | Required | Description |
|---|
signType | string | Yes | Type of sign (e.g., Channel Letters, Monument Sign) |
sizeEstimate | string | No | Approximate size |
requirements | string | Yes | Detailed requirements and special instructions |
locationAddress | string | No | Installation address |
locationLat | number | No | Installation latitude |
locationLng | number | No | Installation longitude |
Response
| Field | Type | Description |
|---|
id | string | Quote request UUID |
status | string | Quote status (pending) |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/quotes \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"signType":"example","sizeEstimate":"example","requirements":"example","locationAddress":"example","locationLat":"value","locationLng":"value"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/quotes", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"signType":"example","sizeEstimate":"example","requirements":"example","locationAddress":"example","locationLat":"value","locationLng":"value"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/quotes",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"signType":"example","sizeEstimate":"example","requirements":"example","locationAddress":"example","locationLat":"value","locationLng":"value"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | signType and requirements are required |
401 | UNAUTHORIZED | Not authenticated |
POST/api/v1/roi
Estimate the return on investment for a sign placement based on location score, sign type, and cost.
Request Body
| Field | Type | Required | Description |
|---|
overallScore | number | Yes | Vista Score (0-100) |
signCost | number | Yes | Estimated sign cost in dollars |
monthlyRevenue | number | No | Expected monthly revenue impact |
Response
| Field | Type | Description |
|---|
estimatedDailyImpressions | number | Estimated daily viewer impressions |
estimatedMonthlyValue | number | Estimated monthly advertising value |
paybackMonths | number | Estimated months to recoup investment |
roiPercentage | number | Annualized ROI percentage |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/roi \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"overallScore":"value","signCost":"value","monthlyRevenue":"value"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/roi", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"overallScore":"value","signCost":"value","monthlyRevenue":"value"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/roi",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"overallScore":"value","signCost":"value","monthlyRevenue":"value"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | overallScore and signCost are required |
POST/api/v1/reports/score
Generate a branded PDF Vista Score report for a location. Requires Pro plan or above.
Request Body
| Field | Type | Required | Description |
|---|
address | string | No | Address to report on (use this OR lat/lng) |
lat | number | No | Latitude |
lng | number | No | Longitude |
Response
| Field | Type | Description |
|---|
reportUrl | string | URL to download the generated PDF |
expiresAt | string | URL expiration timestamp |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/reports/score \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"address":"example","lat":"value","lng":"value"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/reports/score", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"address":"example","lat":"value","lng":"value"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/reports/score",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"address":"example","lat":"value","lng":"value"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
400 | BAD_REQUEST | Missing address or coordinates |
403 | FORBIDDEN | PDF reports require Pro plan or above |
GET/api/v1/notifications
Returns the 50 most recent notifications for the authenticated user.
Response
| Field | Type | Description |
|---|
id | string | Notification UUID |
type | string | Type: scoreChange, dataUpdate, competitor, quoteResponse, orderStatus, system |
title | string | Notification title |
message | string | Notification body |
read | boolean | Whether the notification has been read |
createdAt | string | ISO 8601 timestamp |
Code Examples
cURL
curl -X GET http://localhost:3000/api/v1/notifications \
-H "x-api-key: sk_your_api_key"
JavaScript
const response = await fetch("http://localhost:3000/api/v1/notifications", {
method: "GET",
headers: {
"x-api-key": "sk_your_api_key"
},
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.get(
"http://localhost:3000/api/v1/notifications",
headers={"x-api-key":"sk_your_api_key"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
401 | UNAUTHORIZED | Not authenticated |
POST/api/v1/prospects
Enterprise feature: discover businesses that could benefit from signage in a given area. Searches by city, coordinates, or radius.
Request Body
| Field | Type | Required | Description |
|---|
city | string | No | City name to search |
lat | number | No | Center latitude for radius search |
lng | number | No | Center longitude for radius search |
radiusKm | number | No | Search radius in km (default 5) |
businessType | string | No | Filter by business type |
Response
| Field | Type | Description |
|---|
prospects | array | Array of business prospects with name, address, type, and nearby Vista Score |
Code Examples
cURL
curl -X POST http://localhost:3000/api/v1/prospects \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"city":"example","lat":"value","lng":"value","radiusKm":"value","businessType":"example"}'
JavaScript
const response = await fetch("http://localhost:3000/api/v1/prospects", {
method: "POST",
headers: {
"x-api-key": "sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({"city":"example","lat":"value","lng":"value","radiusKm":"value","businessType":"example"}),
});
const data = await response.json();
console.log(data);
Python
import requests
response = requests.post(
"http://localhost:3000/api/v1/prospects",
headers={"x-api-key":"sk_your_api_key","Content-Type":"application/json"},
json={"city":"example","lat":"value","lng":"value","radiusKm":"value","businessType":"example"},
)
print(response.json())
Errors
| Status | Code | Description |
|---|
401 | UNAUTHORIZED | Not authenticated |
403 | FORBIDDEN | Requires Enterprise plan |