Category
by January 26, 2026

This is the developer API reference for GroundTruth Layer. For an overview, see: (link).

Base URL

 

  • Production: https://api.groundtruthlayer.com

  • Sandbox: https://sandbox.api.groundtruthlayer.com

 

Each customer is provisioned a dedicated environment. Your base URL or tenant identifier may vary.


 

Authentication

 

API Keys

 

All requests must include an API key.

Header

  • Authorization: Bearer <API_KEY>

 

Optional headers

  • X-Customer-Id: <customer_id> (if your auth model supports multi-tenant keys)

  • X-Request-Id: <uuid> (recommended for tracing)

 

Scopes / Roles (optional)

 

If you use scoped keys, document them here:

  • read:listings

  • read:media

  • read:tiles

  • read:autocomplete

  • read:ai

  • read:health

 


 

Content Types

 

  • Requests: application/json

  • Responses: application/json

  • Vector tiles: application/x-protobuf (.pbf)

 


 

Versioning

 

  • Current API version: v1

  • Base path: /v1

 

Recommended strategy:

  • URL versioning (/v1/…)

  • Backward compatible changes only within a major version

 


 

Rate Limits

 

Describe your policy:

  • Default: X requests/minute per API key

  • Burst: Y requests/second

 

Headers

  • X-RateLimit-Limit

  • X-RateLimit-Remaining

  • X-RateLimit-Reset

 


 

Idempotency (optional)

 

For endpoints that write data (segments/classifications), support:

  • Idempotency-Key: <uuid>

 


 

Error Handling

 

Error Format

 

{
  "error": {
    "code": "invalid_request",
    "message": "Human-readable explanation.",
    "details": {
      "field": "min_price",
      "reason": "must be >= 0"
    },
    "request_id": "req_123"
  }
}

Common HTTP Status Codes

 

  • 400 Invalid request

  • 401 Unauthorized

  • 403 Forbidden

  • 404 Not found

  • 409 Conflict (e.g., version mismatch)

  • 422 Validation error

  • 429 Rate limited

  • 500 Server error

  • 503 Maintenance / upstream dependency

 


 

Pagination

 

Cursor Pagination (recommended)

 

Query params:

  • limit (default 50, max 500)

  • cursor (opaque token)

 

Response shape:

{
  "data": [],
  "page": {
    "next_cursor": "opaque_token",
    "has_more": true
  }
}

 

Filtering & Sorting Conventions

 

Filters

 

  • Exact: status=active

  • Range: price_min=500000&price_max=1200000

  • Multi: status=active,pending

  • Arrays: property_type[]=residential&property_type[]=condo

 

Sorting

 

  • sort=price_asc

  • sort=updated_at_desc

 

Geospatial

 

One of:

  • Bounding box: bbox=minLng,minLat,maxLng,maxLat

  • Radius: lat=…&lng=…&radius_m=…

  • Polygon: polygon=<encoded> (geojson or polyline encoding)

 


 

Endpoints

 

Health & Status

 

Get Platform Health

 

GET /v1/health

Response

{
  "status": "ok",
  "request_id": "req_123"
}

Get Sync Status (per customer/environment)

 

GET /v1/status/sync

Response

{
  "environment_id": "env_abc",
  "mls": {
    "source": "MLS_NAME",
    "freshness_seconds": 180,
    "last_success_at": "2026-01-26T20:15:00Z",
    "last_error_at": null
  },
  "inventory": {
    "active": 12345,
    "pending": 2345,
    "sold": 999
  }
}

 

Listings

 

Search Listings

 

GET /v1/listings

Common query params:

  • q (optional keyword, if supported)

  • segment_id (optional)

  • filters: status, property_type, beds_min, baths_min, price_min, price_max, etc.

  • geo: bbox / radius_m / polygon

  • limit, cursor

  • sort

 

Response

{
  "data": [
    {
      "listing_id": "lst_123",
      "status": "active",
      "address": { "line1": "123 Main St", "city": "San Mateo", "state": "CA", "zip": "94401" },
      "geo": { "lat": 37.56, "lng": -122.32 },
      "price": 1200000,
      "beds": 3,
      "baths": 2,
      "updated_at": "2026-01-26T20:10:00Z"
    }
  ],
  "page": { "next_cursor": "opaque", "has_more": true }
}

Get Listing by ID

 

GET /v1/listings/{listing_id}

Get Listing Media

 

GET /v1/listings/{listing_id}/media

Response

{
  "listing_id": "lst_123",
  "photos": [
    {
      "media_id": "med_1",
      "url": "https://cdn.../image.jpg",
      "width": 2048,
      "height": 1536,
      "order": 1
    }
  ]
}

Get Listing History (changes/events)

 

GET /v1/listings/{listing_id}/history

Examples of events:

  • created

  • updated

  • status_changed

  • removed

  • media_changed

 


 

Segments & Classifications (Customer Extensions)

 

List Segments

 

GET /v1/segments

Create Segment

 

POST /v1/segments

Request

{
  "name": "Residential Single Family, For Sale",
  "description": "Internal definition used across search and maps.",
  "rules": {
    "status": ["active"],
    "property_type": ["residential"],
    "subtype": ["single_family"]
  }
}

Update Segment

 

PATCH /v1/segments/{segment_id}

Delete Segment

 

DELETE /v1/segments/{segment_id}

Preview Segment Results (optional but very helpful)

 

POST /v1/segments/preview


 

Autocomplete

 

Suggest Locations / Addresses

 

GET /v1/autocomplete

Query params:

  • q (required)

  • types (optional): city,neighborhood,address,zip,school

  • lat, lng (optional for proximity ranking)

  • limit

 

Response

{
  "data": [
    {
      "type": "city",
      "label": "San Mateo, CA",
      "id": "loc_city_san_mateo_ca",
      "center": { "lat": 37.56, "lng": -122.32 }
    }
  ]
}

 

Maps (Vector Tiles)

 

Vector tiles are intended for map rendering and clustering. They should contain lightweight attributes only (e.g., listing_id, price bucket, status).

Get Listings Tile

 

GET /v1/tiles/listings/{z}/{x}/{y}.pbf

Query params (should mirror listing filters):

  • segment_id

  • status, property_type, price_min, price_max, etc.

  • (optional) fields to control attributes included

 

Response

  • Content-Type: application/x-protobuf

 

Tile Metadata (optional)

 

GET /v1/tiles/metadata


 

AI-Ready Access

 

Natural Language Query

 

POST /v1/ai/query

Request

{
  "query": "3 bed under 1.2M near good schools, walkable",
  "constraints": {
    "status": ["active"],
    "bbox": "-122.6,37.4,-122.1,37.7",
    "price_max": 1200000,
    "beds_min": 3
  },
  "limit": 50
}

Response

{
  "data": [
    { "listing_id": "lst_123", "score": 0.82, "highlights": ["walkable", "near schools"] }
  ]
}

Similar Listings

 

GET /v1/ai/similar/{listing_id}?limit=20


 

Webhooks (Optional but recommended)

 

Event Types

 

  • listing.created

  • listing.updated

  • listing.status_changed

  • listing.removed

  • listing.media_changed

  • sync.health_changed

 

Register Webhook

 

POST /v1/webhooks

List Webhooks

 

GET /v1/webhooks

Verify Signatures

 

Document header like:

  • X-GTL-Signature: …

 


 

Exports & Snapshots (Optional)

 

Export Listings Snapshot

 

POST /v1/exports/listings

Options:

  • format: jsonl / parquet

  • scope: segment / filters

  • include history: true/false

 

List Exports

 

GET /v1/exports

Download Export

 

GET /v1/exports/{export_id}/download


 

Environments & Keys (Optional)

 

Get Environment Info

 

GET /v1/environment

Rotate API Key

 

POST /v1/keys/rotate


 

Changelog

 

v1

 

  • Initial release

  • Listings search and detail

  • Map tiles

  • Autocomplete

  • Segments

  • AI-ready endpoints (optional)

  • Health/sync status