> ## Documentation Index
> Fetch the complete documentation index at: https://docs.homelogs.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Copy/paste path: resolve -> permits -> permit signals

## What you'll build

A basic flow that takes user text like `Seattle` and returns:

* a stable `geo_id`
* current permits for that geo
* permit-scoped leads and stats for that geo
* active geo-scoped signals for that geo

For a complete signal list and timing guide, see [Signals Catalog](/signals).

## Prerequisites

* API key
* `curl`

## 0. Set environment variables

```bash theme={null}
export BASE_URL="https://api.homelogs.io"
export API_KEY="YOUR_API_KEY"
```

## 1. Resolve user input to `geo_id`

```bash theme={null}
curl -sS -G "$BASE_URL/v1/locations/resolve" \
  -H "X-API-Key: $API_KEY" \
  --data-urlencode "query=Seattle" \
  --data-urlencode "state=WA" \
  --data-urlencode "limit=5"
```

Pick one `candidates[].geo_id`.

For permit-scoped signals, pick a non-property `geo_id` such as a city, county, zip, jurisdiction, or state.

## 2. Fetch permits for that geo

```bash theme={null}
export GEO_ID="<paste candidates[0].geo_id>"

curl -sS -G "$BASE_URL/v1/permits/search" \
  -H "X-API-Key: $API_KEY" \
  --data-urlencode "geo_id=$GEO_ID" \
  --data-urlencode "limit=25" \
  --data-urlencode "sort=desc"
```

If `next_cursor` is not null, request the next page:

```bash theme={null}
curl -sS -G "$BASE_URL/v1/permits/search" \
  -H "X-API-Key: $API_KEY" \
  --data-urlencode "geo_id=$GEO_ID" \
  --data-urlencode "limit=25" \
  --data-urlencode "cursor=CURSOR_TOKEN"
```

## 3. Fetch permit-scoped leads for that geo

Use the same `geo_id` for permit signal reads.

```bash theme={null}
curl -sS -G "$BASE_URL/v1/signals/permit/leads" \
  -H "X-API-Key: $API_KEY" \
  --data-urlencode "geo_id=$GEO_ID" \
  --data-urlencode "signal_keys=site_prep_issued_nowcast,new_construction_issued_nowcast" \
  --data-urlencode "limit=25"
```

By default, permit leads return only rows inside the freshness window. Add `include_stale=true` to include older rows.

## 4. Fetch permit-scoped stats for that geo

```bash theme={null}
curl -sS -G "$BASE_URL/v1/signals/permit/stats" \
  -H "X-API-Key: $API_KEY" \
  --data-urlencode "geo_id=$GEO_ID" \
  --data-urlencode "signal_keys=framing_nowcast_early,rough_in_nowcast_early"
```

If you want the more conservative timing variants, swap in:

* `framing_window_late`
* `rough_in_window_late`

## 5. Fetch active geo-scoped signals for that geo

```bash theme={null}
curl -sS -G "$BASE_URL/v1/signals/geo/location/$GEO_ID" \
  -H "X-API-Key: $API_KEY" \
  --data-urlencode "signal_keys=roofing_activity_hotspot,hvac_activity_hotspot"
```

## 6. Search geo-scoped signals across a state

```bash theme={null}
curl -sS -G "$BASE_URL/v1/signals/geo/search" \
  -H "X-API-Key: $API_KEY" \
  --data-urlencode "state=WA" \
  --data-urlencode "geo_type=city" \
  --data-urlencode "signal_keys=roofing_activity_hotspot" \
  --data-urlencode "decision=positive" \
  --data-urlencode "min_score=0.5" \
  --data-urlencode "limit=25"
```

## Common first-run issues

* `403`: missing/invalid API key
* `422`: invalid query format, unsupported permit-scoped geo type, or bad cursor
* `404`: valid request but no matching resource

See [Troubleshooting](/troubleshooting).

Want more detail on signal fields and scoring behavior? See [Signals Catalog](/signals) and [Signals & Methodology](/signals-and-methodology).
