# Tell your AI agent if the ground is sinking: measured ground-motion with SibFly + LangChain

> Source: <https://dev.to/jamessib/tell-your-ai-agent-if-the-ground-is-sinking-measured-ground-motion-with-sibfly-langchain-2dc1>
> Published: 2026-07-01 01:19:15+00:00

Most "is this property risky?" data your agent can reach is *modeled* — a prediction from soil maps and flood zones. There's a different, underused signal: **measured** ground motion. Satellites have been tracking how far the ground has physically moved, to the millimeter, for years.

[SibFly](https://sibfly.com) packages that into one call: give it a US address, get back how fast the ground is sinking or rising, in mm/year, derived from NASA's OPERA Sentinel-1 InSAR dataset. Measured, not modeled. Negative = sinking.

This post wires it into a LangChain agent in about 30 lines.

Ground subsidence (sinking) quietly wrecks foundations, and it's invisible on a normal map. It shows up in radar interferometry (InSAR): compare two satellite passes over the same spot and you can measure sub-centimeter vertical change. NASA processes this for all of North America and publishes it for free — but the raw data is 400 MB HDF5 granules in radar geometry, not something an agent can query per address.

SibFly does the ETL and serves the pixel: `GET /api/v1/motion?address=...`

→ a JSON verdict.

```
pip install -U langchain-sibfly
export SIBFLY_API_KEY="sf_live_..."
```

Grab a key with free starter credits at [sibfly.com](https://sibfly.com). Agents can also self-register with no human in the loop:

```
curl -X POST https://sibfly.com/api/v1/autonomous/register \
  -H "Content-Type: application/json" -d '{"email":"you@example.com"}'
# -> { "api_key": "sf_live_...", "credits_usd": 1.0, ... }
python
from langchain_sibfly import SibflyGroundMotion

motion = SibflyGroundMotion()  # reads SIBFLY_API_KEY

print(motion.invoke({"address": "1100 Congress Ave, Austin, TX"}))
{
    "status": "ok",
    "velocity_vertical_mm_yr": -6.0,
    "velocity_uncertainty_mm_yr": 1.5,
    "assessment_code": "notable_subsidence",
    "confidence": 0.86,
    "data_age_days": 73,
    "cost_usd": 0.4,
    "credits_remaining_usd": 0.6,
}
```

Route your logic on `assessment_code`

— a stable enum (`rapid_subsidence`

, `notable_subsidence`

, `stable`

, `mild_uplift`

, `strong_uplift`

) — not on the human-readable string.

The thing I appreciate as someone who builds agents: **misses are free.** Out-of-coverage, no-data, too-stale, and low-confidence responses all come back HTTP 200 with `cost_usd: 0`

. You only pay $0.40 when you get a real covered reading. And there's a free preview:

```
# free: coverage + confidence + would_cost_usd, no charge
motion.invoke({"lat": 30.3244, "lon": -97.8102, "dry_run": True})
```

You can also refuse to pay for data you'd reject, server-side:

``` php
motion.invoke({
    "address": "...",
    "max_age_days": 400,     # too old -> free "stale_data"
    "min_confidence": 0.7,   # too noisy -> free "low_confidence"
})
python
from langchain_sibfly import SibflyGroundMotion
from langchain_anthropic import ChatAnthropic
from langgraph.prebuilt import create_react_agent

agent = create_react_agent(
    ChatAnthropic(model="claude-sonnet-5"),
    tools=[SibflyGroundMotion()],
)

out = agent.invoke({"messages": [
    ("user", "Is the ground sinking under 1100 Congress Ave, Austin TX? "
             "Check coverage first so we don't waste a call.")
]})
print(out["messages"][-1].content)
```

The agent will typically `dry_run`

first (free), see it's covered, then pull the real reading.

SibFly also runs a hosted MCP server, so any MCP client can use it with no SDK:

```
https://sibfly.com/mcp   (Streamable HTTP, Bearer auth)
```

It's in the official MCP registry as `com.sibfly/ground-motion`

. Tools: `check_ground_motion`

, `check_coverage`

, `check_portfolio`

, `get_motion_history`

, `get_account`

.

This is a **screening** signal, not an engineering survey. It tells you a parcel is moving and roughly how fast; it doesn't replace a geotechnical report. SibFly returns an uncertainty (`±mm/yr`

), a confidence score, and a `neighbor_consistent`

flag so your agent can tell a real trend from a single noisy pixel. Treat it like a credit-score check: fast, cheap, directional.

`llama-index-tools-sibfly`
