---
title: "Permit, 311, and code-violation time series for a neighborhood (cited)"
method: POST
path: "/api/locus-local-trend-brief"
tags: ["data", "search", "real-estate", "property", "property-research", "due-diligence", "public-records", "x402", "research", "local-data", "local-change-analysis", "development-activity", "permits", "code-cases", "government", "citations", "category:policy"]
---

# Permit, 311, and code-violation time series for a neighborhood (cited)

`POST /api/locus-local-trend-brief`

## Request

- Base URL: `https://api.locus.report`
- URL: `https://api.locus.report/api/locus-local-trend-brief`
- Auth: one of:
  - API key in header `PAYMENT-SIGNATURE`
  - API key in header `Authorization`

Official monthly permit, 311, and code-violation counts and year-over-year change for a neighborhood, ZIP, city, or county. Each series cites its dataset. Coverage follows the source-card registry and lane availability; unsupported or thin places get a charge-free diagnostic. npx @velinussage/locus-agent-skill add.

## Request body

- object: Flexible US place string (street address, ZIP, city, county, or city/state) plus a Locus intent. Street address is best for property workflows. Coverage is checked before any charge; unsupported places return a free diagnostic.
  - `place` string, required: Flexible US place string: street address, ZIP, city, county, or city/state. Street address is best for property due diligence; broader places return jurisdiction-level coverage where supported.
  - `intent` 'renter_due_diligence' | 'homebuyer_due_diligence' | 'small_business_siting' | 'community_organizer_journalist', required
  - `lookbackMonths` integer, required
  - `includeCrime` boolean, required
  - `context` string
  - `followUp` string

## Response `200`

Successful paid artifact, or a free pre-charge diagnostic when the request is outside current coverage.

- union: A `kind`-discriminated union: `local_trend_brief` for paid cited trend context, or `coverage_diagnostic` for a free pre-charge coverage diagnostic.
  - object
    - `kind` 'local_trend_brief', required
    - `id` string, required
    - `generatedAt` string, required
    - `place` object, required
      - `input` string, required
      - `resolved` string
      - `jurisdictionId` string, required
      - `coverageStatus` 'supported' | 'supported_partial' | 'discovery_only' | 'unsupported', required
    - `intent` string, required
    - `intentRulesetVersion` string, required
    - `lookbackMonths` number, required
    - `coverage` object[], required
      - `source` 'permits' | 'code_violations' | 'service_requests_311' | 'crimes', required
      - `datasetId` string, required
      - `status` 'ok' | 'empty' | 'unavailable', required
      - `recordCount` number, required
      - `lookbackCovered` boolean, required
      - `sourceUrl` string, required
    - `series` object[], required
      - `key` string, required
      - `source` 'permits' | 'code_violations' | 'service_requests_311' | 'crimes', required
      - `bucket` 'monthly' | 'quarterly', required
      - `points` object[], required
        - `periodStart` string, required
        - `count` number, required
      - `change` object, required
        - `direction` 'up' | 'down' | 'flat', required
        - `absoluteDelta` number, required
        - `pctChange` number, nullable, required
        - `method` 'first-half-vs-second-half' | 'year-over-year', required
      - `confidence` 'low' | 'medium' | 'high', required
      - `categoryBreakdown` object
        - `top` object[], required
          - `label` string, required
          - `count` number, required
          - `recentCount` number, required
          - `baselineCount` number, required
          - `delta` number, required
        - `totalCategorized` number, required
        - `uncategorized` number, required
    - `whatThisMayMean` string[], required
    - `whatThisDoesNotProve` string[], required
    - `questionsToAsk` string[], required
    - `citations` object[], required
      - `label` string, required
      - `sourceName` string, required
      - `sourceUrl` string, required
      - `datasetId` string, required
    - `caveats` string[], required
    - `citedCards` object[], required
      - `cardId` string, required
      - `jurisdictionId` string, required
      - `category` string, required
      - `sourceUrl` string, required
      - `biasProfile` object
        - `measures` string, required
        - `doesNotMeasure` string, required
        - `knownBiases` string[], required
        - `lagDays` integer
    - `chargeable` boolean, required
    - `storage` object[]
      - `provider` string, required
      - `locator` string, required
      - `contentHash` string, required
      - `pinned` boolean
    - `refinement` object
      - `context` object
        - `input` string, required
        - `emphasizedSources` string[], required
        - `rationale` string[], required
      - `followUp` object
        - `question` string, required
        - `status` 'answered' | 'gated' | 'unsupported', required
        - `answer` string[], required
        - `gatedReason` string
        - `gatedReasonCode` string
        - `citations` object[], required
          - `label` string, required
          - `sourceName` string, required
          - `sourceUrl` string, required
          - `datasetId` string, required
        - `caveats` string[], required
    - `communitySignal` object[]
      - `label` 'contested', required
      - `observationId` string, required
      - `jurisdictionId` string, required
      - `claimType` string, required
      - `body` string, required
      - `status` string, required
      - `placeLabel` string, required
      - `evidenceUrl` string, uri
    - `verifyNext` object[]
      - `step` string, required
      - `url` string
      - `source` string
  - object
    - `kind` 'coverage_diagnostic', required
    - `place` object, required
      - `input` string, required
      - `resolved` string
      - `jurisdictionId` string
      - `coverageStatus` 'discovery_only' | 'unsupported' | 'insufficient_data' | 'source_unavailable', required
    - `intent` string, required
    - `charged` false, required
    - `message` string, required
    - `candidateSources` object[], required
      - `category` string, required
      - `sourceName` string, required
      - `sourceUrl` string, required
    - `whatWeWouldNeed` string[], required
    - `sourceCounts` object[]
      - `source` string, required
      - `recordCount` number, required
    - `preflight` object
      - `tool` string, required
      - `url` string, required
      - `note` string, required
    - `requestCoverage` object
      - `tool` string, required
      - `endpoint` string, required
      - `note` string, required
    - `componentReadiness` object
      - `trend` 'ok' | 'partial' | 'thin' | 'missing' | 'unavailable', required
      - `parcel` 'ok' | 'varies' | 'missing' | 'unavailable', required
      - `policy` 'ok' | 'missing' | 'unavailable', required
    - `componentReadinessDetail` object[]
      - `component` 'trend' | 'parcel' | 'policy', required
      - `ready` boolean, required
      - `state` string, required
      - `reason` string, required
    - `insufficientComponents` string[]
    - `suggestedAlternative` string
    - `caveats` string[], required

## Other responses

- `400`: Invalid request body.
- `402`: Payment Required. For x402 v2, repeat the identical request with a valid PAYMENT-SIGNATURE header (legacy X-PAYMENT is accepted for compatibility), or use Authorization: Payment for MPP Tempo when advertised in x-payment-info.offers.

---

[API](https://skmtc.dev/locus/apis/locus-api.md) · [All operations](https://skmtc.dev/locus/apis/locus-api/llms.txt) · [OpenAPI document](https://skmtc.dev/locus/apis/locus-api/revisions/ba7786b74adb?raw)
