aicdapi-com Research coverage API

Dated evidence about possible DFW civic-data sources and research gaps.

Operations 1

GET /api/v1/public/coverage List DFW civic-data research coverage #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/aicdapi-com:aicdapi-com-research-coverage-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

aicdapi-com-research-coverage-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: AICD Research coverage API
  version: 1.0.0
  contact:
    name: AICD API
    url: https://aicdapi.com
    email: hello@aicdapi.com
  x-publisher:
    '@id': https://cairn-labs.com/#organization
  description: 'Structured Dallas-Fort Worth civic records. Public endpoints retain their documented cache and IP limits. Customer endpoints under /api/v1/data require a server bearer credential and always return Cache-Control: no-store. Customer grants, request/burst/export limits and response size caps are enforced. v1 allows additive response fields; breaking changes use a new version with a minimum 90-day migration notice during the first-customer pilot. Source check time and processing state describe observed coverage; no uptime or completeness guarantee is implied.'
servers:
- url: /
  description: Same origin as this document
security: []
tags:
- name: Research coverage
  description: Dated evidence about possible DFW civic-data sources and research gaps.
paths:
  /api/v1/public/coverage:
    get:
      operationId: listDfwResearchCoverage
      summary: List DFW civic-data research coverage
      description: Returns dated source-discovery evidence for 238 active municipalities and 16 counties in the NCTCOG region. Inactive Mustang is omitted unless `includeInactive=true`. M/D/P/R/U/N statuses apply only to the named data subtype. They do not prove full-family coverage, current completeness, reuse permission or production ingestion. Cursors are bound to the catalog version and all filters.
      tags:
      - Research coverage
      parameters:
      - name: jurisdictionSlug
        in: query
        description: Exact jurisdiction slug, such as `dallas` or `dallas-county`.
        schema:
          type: string
          minLength: 1
          maxLength: 80
      - name: county
        in: query
        description: One of the 16 lowercase DFW county slugs, such as `tarrant`.
        schema:
          $ref: '#/components/schemas/DfwCountySlug'
      - name: family
        in: query
        description: Fully qualified family ID, such as `city.permits` or `county.property_tax`.
        schema:
          $ref: '#/components/schemas/ResearchCoverageFamilyId'
      - name: includeInactive
        in: query
        description: Set to true to include inactive Mustang. The default is false.
        schema:
          type: boolean
          default: false
      - name: limit
        in: query
        description: Maximum jurisdictions per page. The small cap bounds source-evidence text.
        schema:
          type: integer
          minimum: 1
          maximum: 20
          default: 20
      - name: cursor
        in: query
        description: Opaque cursor from the prior page. Use it with the same filters and limit.
        schema:
          type: string
          minLength: 1
          maxLength: 4096
      responses:
        '200':
          description: Dated research evidence and gaps. This is not an ingestion-health response.
          headers:
            Cache-Control:
              $ref: '#/components/headers/PublicCacheControl'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchCoverageEnvelope'
              examples:
                cityPermitResearch:
                  value:
                    data:
                    - kind: city
                      researchId: city:4801240
                      jurisdictionSlug: addison
                      name: Addison
                      active: true
                      municipalityType: town
                      censusPlaceGeoid: '4801240'
                      counties:
                      - Dallas
                      regionCounties:
                      - Dallas
                      primaryRegionCounty: Dallas
                      censusStatus:
                        functionalStatus: A
                        placeClass: C1
                        vintage: '2026-01-01'
                      sourceUrls:
                        official: https://addisontexas.net/
                        openData: https://the-town-of-addison-gis-directory-addisontx.hub.arcgis.com/
                        websiteDiscovery: null
                        roster: https://geospatial.nctcog.org/map/rest/services/Boundaries/Boundaries/MapServer/6
                        censusStatus: https://tigerweb.geo.census.gov/tigerwebmain/Files/acs26/tigerweb_acs26_incplace_tx.html
                        countyMembership: https://geospatial.nctcog.org/map/rest/services/RDC/POP_ESTIMATES_REAL_RATES_BY_CITY/MapServer/1
                      rosterLimits:
                        boundaryYear: '2024'
                        boundarySource: City
                        directoryListed: true
                        websiteVerification: NCTCOG index link; live site ownership not confirmed.
                        verificationNotes: []
                      families:
                      - familyId: city.permits
                        status: P
                        evidenceScope: source_discovery_only
                        checkedDate: '2026-09-09'
                        sourceUrl: https://developmentservices.addisontx.gov/Data-Reports
                        method: Official source or report index identified
                        evidence: Official reports index names monthly commercial building permits.
                        constraints: Bulk access, refresh cadence and reuse terms still need a connector proof.
                        alternatives: []
                    meta:
                      catalogVersion: 2026-09-09.f006aca03096
                      researchDate: '2026-09-09'
                      ingestionVerified: false
                      statusDefinitions:
                        M: A public machine-readable query, sample, or count succeeded.
                        D: A public record or document was opened and read.
                        P: An official source or portal was found, but record extraction was not proved.
                        R: Access, terms, account, payment, or reuse restrictions need resolution.
                        U: No source was proved in this research pass; this does not mean the data is unavailable.
                        N: The family or named subtype is explicitly not applicable for this jurisdiction.
                      scope:
                        name: NCTCOG 16-county region
                        counties:
                        - Collin
                        - Dallas
                        - Denton
                        - Ellis
                        - Erath
                        - Hood
                        - Hunt
                        - Johnson
                        - Kaufman
                        - Navarro
                        - Palo Pinto
                        - Parker
                        - Rockwall
                        - Somervell
                        - Tarrant
                        - Wise
                        rosterCheckedDate: '2026-09-08'
                        censusStatusVintage: '2026-01-01'
                        method: Dated NCTCOG and Census roster cross-check.
                        caveat: This is a dated research baseline, not a live ingestion claim.
                      pagination:
                        limit: 20
                        returned: 1
                        nextCursor: null
        '400':
          $ref: '#/components/responses/InvalidParameter'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security: []
      x-auth-class: public
      x-required-scope: []
      x-release-status: available
      x-markdown-url: /api-reference/listDfwResearchCoverage.md
      x-curl-example: curl -X GET 'https://aicdapi.com/api/v1/public/coverage'
      x-rate-limit: '120 requests per 60 seconds per client IP, counted separately for each public endpoint and keyed on the first X-Forwarded-For entry. The allowance is not shared between public endpoints: exhausting one leaves the others available. If the limiter''s own store fails, the request is allowed through rather than refused.'
      x-caching: public, s-maxage=60, stale-while-revalidate=300 on success. Error responses carry no cache directive.
      x-notes:
      - Unknown query keys and repeated query keys are rejected rather than ignored.
      x-pagination: Offset cursor pagination, 1 to 20 items per page with a default of 20. The cursor is invalidated by any filter change and by a new catalog version.
      x-retry-after: Sent on 429 only, as whole seconds.
      x-errors:
      - status: 400
        code: invalid_parameter
      - status: 429
        code: rate_limited
      - status: 500
        code: internal_error
components:
  schemas:
    ResearchCoverageFreshness:
      type: object
      additionalProperties: false
      properties:
        note:
          type: string
        latestOpenedSample:
          type: string
          format: date-time
        latestFilingSample:
          type: string
          format: date-time
        latestSampleRecord:
          type: string
        sourceHistoryClaim:
          type: string
        futureStatusAnomaly:
          type: string
          format: date-time
        fullHistoryVerified:
          type: boolean
    ResearchCoverageEnvelope:
      type: object
      additionalProperties: false
      required:
      - data
      - meta
      properties:
        data:
          type: array
          maxItems: 20
          items:
            oneOf:
            - $ref: '#/components/schemas/CityResearchCoverage'
            - $ref: '#/components/schemas/CountyResearchCoverage'
        meta:
          type: object
          additionalProperties: false
          required:
          - catalogVersion
          - researchDate
          - ingestionVerified
          - statusDefinitions
          - scope
          - pagination
          properties:
            catalogVersion:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}\.[a-f0-9]{12}$
            researchDate:
              type: string
              format: date
            ingestionVerified:
              type: boolean
              const: false
            statusDefinitions:
              type: object
              additionalProperties: false
              required:
              - M
              - D
              - P
              - R
              - U
              - N
              properties:
                M:
                  type: string
                D:
                  type: string
                P:
                  type: string
                R:
                  type: string
                U:
                  type: string
                N:
                  type: string
            scope:
              type: object
              additionalProperties: false
              required:
              - name
              - counties
              - rosterCheckedDate
              - censusStatusVintage
              - method
              - caveat
              properties:
                name:
                  type: string
                  const: NCTCOG 16-county region
                counties:
                  type: array
                  minItems: 16
                  maxItems: 16
                  items:
                    type: string
                rosterCheckedDate:
                  type: string
                  format: date
                censusStatusVintage:
                  type: string
                  format: date
                method:
                  type: string
                caveat:
                  type: string
            pagination:
              type: object
              additionalProperties: false
              required:
              - limit
              - returned
              - nextCursor
              properties:
                limit:
                  type: integer
                  minimum: 1
                  maximum: 20
                returned:
                  type: integer
                  minimum: 0
                  maximum: 20
                nextCursor:
                  type:
                  - string
                  - 'null'
                  maxLength: 4096
    CityResearchCoverage:
      type: object
      additionalProperties: false
      required:
      - kind
      - researchId
      - jurisdictionSlug
      - name
      - active
      - municipalityType
      - censusPlaceGeoid
      - counties
      - regionCounties
      - primaryRegionCounty
      - censusStatus
      - sourceUrls
      - rosterLimits
      - families
      properties:
        kind:
          type: string
          const: city
        researchId:
          type: string
          pattern: ^city:48[0-9]{5}$
        jurisdictionSlug:
          type: string
        name:
          type: string
        active:
          type: boolean
        municipalityType:
          type: string
          enum:
          - city
          - town
          - village
        censusPlaceGeoid:
          type: string
          pattern: ^48[0-9]{5}$
        counties:
          type: array
          minItems: 1
          items:
            type: string
        regionCounties:
          type: array
          minItems: 1
          items:
            type: string
        primaryRegionCounty:
          type: string
        censusStatus:
          type: object
          additionalProperties: false
          required:
          - functionalStatus
          - placeClass
          - vintage
          properties:
            functionalStatus:
              type: string
            placeClass:
              type: string
            vintage:
              type: string
              format: date
        sourceUrls:
          $ref: '#/components/schemas/ResearchSourceUrls'
        rosterLimits:
          type: object
          additionalProperties: false
          required:
          - boundaryYear
          - boundarySource
          - directoryListed
          - websiteVerification
          - verificationNotes
          properties:
            boundaryYear:
              type: string
            boundarySource:
              type: string
            directoryListed:
              type: boolean
            websiteVerification:
              type: string
            verificationNotes:
              type: array
              items:
                type: string
        families:
          type: array
          minItems: 1
          maxItems: 10
          items:
            $ref: '#/components/schemas/ResearchCoverageFamily'
    ProblemEnvelope:
      type: object
      additionalProperties: false
      required:
      - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
          - code
          - message
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
            details: {}
    CountyResearchCoverage:
      type: object
      additionalProperties: false
      required:
      - kind
      - researchId
      - jurisdictionSlug
      - countySlug
      - name
      - active
      - sourceUrls
      - families
      properties:
        kind:
          type: string
          const: county
        researchId:
          type: string
          pattern: ^county:[a-z]+(?:-[a-z]+)*$
        jurisdictionSlug:
          type: string
        countySlug:
          $ref: '#/components/schemas/DfwCountySlug'
        name:
          type: string
        active:
          type: boolean
          const: true
        sourceUrls:
          type: object
          additionalProperties: false
          required:
          - roster
          properties:
            roster:
              type: string
              format: uri
        families:
          type: array
          minItems: 1
          maxItems: 11
          items:
            $ref: '#/components/schemas/ResearchCoverageFamily'
    DfwCountySlug:
      type: string
      enum:
      - collin
      - dallas
      - denton
      - ellis
      - erath
      - hood
      - hunt
      - johnson
      - kaufman
      - navarro
      - palo-pinto
      - parker
      - rockwall
      - somervell
      - tarrant
      - wise
    ResearchEvidenceScope:
      type: string
      enum:
      - named_subtype_only
      - source_discovery_only
      - access_or_reuse_restriction
      - unresolved
      - not_applicable
    ResearchCoverageAlternative:
      type: object
      additionalProperties: false
      required:
      - sourceUrl
      properties:
        title:
          type: string
        status:
          $ref: '#/components/schemas/ResearchCoverageStatus'
        sourceUrl:
          type: string
          format: uri
        checkedDate:
          type: string
          format: date
        method:
          type: string
        evidence:
          type: string
        constraints:
          type: string
    ResearchCoverageStatus:
      type: string
      enum:
      - M
      - D
      - P
      - R
      - U
      - N
      description: Dated evidence level, not production ingestion status.
    ResearchSourceUrls:
      type: object
      additionalProperties: false
      required:
      - official
      - openData
      - websiteDiscovery
      - roster
      - censusStatus
      - countyMembership
      properties:
        official:
          type:
          - string
          - 'null'
          format: uri
        openData:
          type:
          - string
          - 'null'
          format: uri
        websiteDiscovery:
          type:
          - string
          - 'null'
          format: uri
        roster:
          type: string
          format: uri
        censusStatus:
          type: string
          format: uri
        countyMembership:
          type: string
          format: uri
    ErrorCode:
      type: string
      enum:
      - invalid_parameter
      - not_found
      - unauthorized
      - forbidden
      - rate_limited
      - internal_error
    ResearchCoverageFamilyId:
      type: string
      enum:
      - city.permits
      - city.planning_gis
      - city.laws_governance
      - city.finance
      - city.procurement
      - city.service_code
      - city.public_safety
      - city.health_licenses
      - city.infrastructure
      - city.elections_notices
      - county.property_tax
      - county.land_records
      - county.courts
      - county.procurement
      - county.finance
      - county.elections
      - county.development
      - county.gis_infrastructure
      - county.public_safety
      - county.health_environment
      - county.government_records
    ResearchCoverageFamily:
      type: object
      additionalProperties: false
      required:
      - familyId
      - status
      - evidenceScope
      - checkedDate
      - sourceUrl
      - method
      - evidence
      - constraints
      - alternatives
      properties:
        familyId:
          $ref: '#/components/schemas/ResearchCoverageFamilyId'
        status:
          $ref: '#/components/schemas/ResearchCoverageStatus'
        evidenceScope:
          $ref: '#/components/schemas/ResearchEvidenceScope'
        checkedDate:
          type: string
          format: date
        sourceUrl:
          type:
          - string
          - 'null'
          format: uri
        method:
          type: string
        evidence:
          type: string
        constraints:
          type: string
        alternatives:
          type: array
          items:
            $ref: '#/components/schemas/ResearchCoverageAlternative'
        subtype:
          type: string
        subtypes:
          type: array
          items:
            $ref: '#/components/schemas/ResearchCoverageSubtype'
        coverageStart:
          type: string
          format: date
        coverageEnd:
          type: string
          format: date
        recordCount:
          type: integer
          minimum: 0
        coverageQueryUrl:
          type: string
          format: uri
        countQueryUrl:
          type: string
          format: uri
        liveSourceFollowup:
          type: string
        freshness:
          $ref: '#/components/schemas/ResearchCoverageFreshness'
        custodian:
          type: string
        history:
          type: string
        cost:
          type: string
        updateFrequency:
          type: string
        familyConstraints:
          type: string
    ResearchCoverageSubtype:
      type: object
      additionalProperties: false
      required:
      - type
      - status
      - reason
      properties:
        type:
          type: string
        status:
          $ref: '#/components/schemas/ResearchCoverageStatus'
        reason:
          type: string
        url:
          type: string
          format: uri
  responses:
    RateLimited:
      description: More than 120 requests were made by this client IP in 60 seconds.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProblemEnvelope'
          examples:
            rateLimited:
              value:
                error:
                  code: rate_limited
                  message: Rate limit exceeded
    InvalidParameter:
      description: A path or query parameter is invalid or unsupported.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProblemEnvelope'
          examples:
            invalidParameter:
              value:
                error:
                  code: invalid_parameter
                  message: Invalid parameter
    InternalError:
      description: The request could not be completed because of an internal error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProblemEnvelope'
          examples:
            internalError:
              value:
                error:
                  code: internal_error
                  message: Internal server error
  headers:
    PublicCacheControl:
      description: Public CDN cache policy for successful public GET responses.
      schema:
        type: string
        const: public, s-maxage=60, stale-while-revalidate=300
    RetryAfter:
      description: Seconds until this client IP may retry.
      required: true
      schema:
        type: integer
        minimum: 1
  securitySchemes:
    ApiCustomerBearer:
      type: http
      scheme: bearer
      bearerFormat: Opaque service credential
      description: Server-only customer key. civic:read covers changes, batch and health. civic:export covers snapshot creation and pages. Keep test and production keys separate.
x-aicd-reference:
  human: /api-reference
  markdown: /api-reference.md
  operationMarkdownTemplate: /api-reference/{operationId}.md
  openApi: /api/openapi.json
  llmsIndex: /llms.txt
  llmsFull: /llms-full.txt
x-aicd-mcp:
  transport:
    paths:
    - /api/v1/mcp
    methods:
    - POST
    protocol: 'Streamable HTTP carrying JSON-RPC 2.0 over HTTPS. The same path serves two protocol eras. A current-era request identifies itself in the body with a params._meta envelope claim (io.modelcontextprotocol/protocolVersion) together with protocolVersion and clientCapabilities, and is answered with one JSON response. A POST without that envelope is treated as a 2025-era request: it is answered per request with no session, and the reply is an SSE stream whose data frames carry the JSON-RPC result. JSON-RPC batch arrays are accepted only on the 2025-era path; a batch containing a current-era element is refused. The server never issues an Mcp-Session-Id, so nothing has to be kept between calls. Only tools are exposed: there are no resources and no prompts. Clients use initialize, tools/list and tools/call; server/discover reports the supported revision.'
    headers:
    - 'Authorization: Bearer <aicd_... API key> - required on every request. The key must grant mcp:read. A browser session is not accepted here.'
    - 'Content-Type: application/json - required. Any other media type is refused with HTTP 415.'
    - 'Accept: application/json and text/event-stream - required on a 2025-era request, and both media types must be listed; otherwise HTTP 406. Not checked on a 2026-07-28 request.'
    - MCP-Protocol-Version - optional. On a 2025-era request it must be one of 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05 or 2024-10-07. On a request carrying the 2026-07-28 envelope claim it must be 2026-07-28 and must equal the body claim.
    - Mcp-Method - required on a 2026-07-28 request and must agree with the JSON-RPC method in the body; a disagreement is refused.
    - Mcp-Name - required on a 2026-07-28 tools/call and must equal params.name.
    - Origin - optional, but when sent its hostname must match the hostname of the request URL, otherwise HTTP 403. A cross-site browser write is refused before the route runs.
    - Content-Length - optional, but when sent it must parse as a non-negative integer and must not exceed 65,536; otherwise HTTP 400 or HTTP 413.
    - Mcp-Session-Id - never issued and never required. The transport is stateless, so send none.
    sizeLimit: 65,536 bytes for the whole request body, enforced both on the declared Content-Length and on the streamed body (HTTP 413 request_too_large). Civic tool results are separately capped at 16,384 bytes; a result that cannot fit is trimmed, and a result that still cannot fit fails with the tool error response_too_large rather than being returned partially. The REST data-report routes have their own 8 KiB body limit, which does not apply to a submission sent inside an MCP request.
  auth:
    class: bearer_api_key
    scopes:
    - mcp:read
    note: 'Send an opaque AICD API key as `Authorization: Bearer aicd_...`. The same valid key serves the records API and MCP, and every stored key carries the MCP read scope, including tools/list. The two report tools ask for no report permission and never use the paid civic executor or take an extra payment, and the account still needs current paid access. The tool list itself is static: all five tools are always listed, and the difference between accounts is per call, not per list - a civic tool call is billed or refused according to the account''s billing channel (pay-as-you-go settlement, a live subscription period, or an operator channel that rejects payment metadata). Authentication happens before the MCP handler runs and can fail with HTTP 401 unauthorized, HTTP 403 forbidden or a billing code, or HTTP 503 authentication_unavailable; a handler failure returns HTTP 503 mcp_unavailable. Every route response carries Cache-Control: no-store. The separate route /api/mcp is a closed legacy stub that always returns HTTP 403 mcp_prelaunch with no credential check and is not an MCP surface; it is not an alias of /api/v1/mcp.'
  rateLimit: 'On the metered path, a message from an account bound to a subscription that is not a `tools/call` consumes two per-account transport buckets: a minute bucket (60-second window, default 120 requests) and a burst bucket (1-second window, default 30 requests), at the account''s own allowances, which the account console and the public usage limits help show. On exhaustion the request fails with HTTP 429 rate_limited and a Retry-After header carrying whole seconds until the current fixed window ends, minimum 1. A civic `tools/call` is not counted here: the paid quota path charges it. A message from an account on another billing channel is not counted here either. An allowlisted metadata message (`initialize`, `tools/list`, `ping`, `server/discover`, `notifications/initialized`, `notifications/cancelled`) and one of the two report tools take neither bucket: they share one admission instead, a valid key with mcp:read and then a fail-closed per-client-IP report edge limit that refuses with 429 rate_limited and a Retry-After, or with 503 when it cannot be checked. For a report that admission is abuse control only, because the report still needs the account''s current paid access. Report counters surface as tool errors with retryAfterSeconds inside the payload instead of HTTP 429: 5 submissions per account-minute, 30 status reads per account-minute, 20 new reports per account-day, and 20 unresolved reports.'
  releaseStatus: limited
  tools:


# --- truncated at 32 KB (80 KB total) ---
# Full source: https://artifacts.apis.io/aicdapi-com/openapi/aicdapi-com-research-coverage-api-openapi.yml