DDDailyDog/ API docs

Reference

API reference

Generated from the OpenAPI 3.1 document — the machine-readable source of truth. Every mock response below is exactly what a dd_test_ key returns; the console on each endpoint sends real requests with the public test key.

Restaurants

Establishments keyed by CAMIS permit number.

Search restaurants

GET/api/v1/restaurants/search

Name or street search — the typeahead endpoint. Best matches first. **Location-aware queries.** Append a place to the name and the search scopes to it: `q=dos toros williamsburg` searches for “dos toros” in Williamsburg's zip codes. Recognized locations (matched from the end of the query): ~180 NYC neighborhood names and abbreviations (`williamsburg`, `east village`, `hell's kitchen`, `les`, `uws`, `lic`, `fidi`…), borough names and slang (`brooklyn`, `bk`, `staten island`), and bare NYC zip codes (`q=pizza 11211`). If nothing matches in the location, the search automatically falls back citywide — a place word never makes results worse. Partial place names match as you type — `q=joes willia` already scopes to Williamsburg — and a query whose trailing token matches nothing is retried once without it, so suggestions never vanish mid-word. **Punctuation-insensitive names.** Matching ignores apostrophes, periods, hyphens, and ampersands on both sides: `q=joes` finds JOE'S PIZZA, `q=lindustrie` finds L'INDUSTRIE PIZZERIA. **Typo-tolerant matching.** Slight misspellings still match: `q=chipotel` and `q=chiptole` both find CHIPOTLE MEXICAN GRILL. Exact matches always outrank fuzzy ones, and the closest spelling wins among fuzzy candidates — garbage strings return nothing rather than noise. **Proximity ranking.** Pass `lat` + `lng` (together) and equally-good name matches sort nearest first — `q=chipotle` from SoHo returns the Spring Street location before the Bronx one — and every result gains an additive `distanceMeters`. Distance never outranks a better name match; it breaks ties.

Parameters

NameTypeDescription
q *stringName or address fragment, 2–120 chars. Optionally suffixed with a neighborhood, borough, or zip.
limitintegerMax results, 1–25 (default 10).
latnumberOptional origin latitude (NYC bounds; requires lng). Enables proximity ranking + distanceMeters.
lngnumberOptional origin longitude (NYC bounds; requires lat).

Response — the `data` object

FieldTypeDescription
camisstringDOHMH permit number — the establishment's id.
namestringDoing-business-as name.
addressstringStreet address (borough is its own field).
boroughstringBorough.
zipstring | nullZIP code.
cuisinestring | nullCuisine description.
gradestring | nullPosted grade: A|B|C|Z|P|N (Z/P = pending, N = not yet graded).
scoreinteger | nullLatest inspection score — LOWER is better; 0–13 is the A band.
closedbooleanCurrently marked closed by the Health Department.
riskLevelLOW | MODERATE | HIGH | SEVERELOW | MODERATE | HIGH | SEVERE.
riskScoreinteger0–100, higher is worse.
lastInspectedAtstring | nullMost recent inspection.
latitudenumber | null
longitudenumber | null
openViolationsintegerItems open right now (latest-cycle citations).
request · cURL
curl "https://www.dailydog.ai/api/v1/restaurants/search?q=example" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "camis": "90000001",
      "name": "THE GILDED SPOON",
      "address": "12 TEST STREET",
      "borough": "Manhattan",
      "zip": "10001",
      "cuisine": "French",
      "grade": "A",
      "score": 9,
      "closed": false,
      "riskLevel": "LOW",
      "riskScore": 4,
      "lastInspectedAt": "2026-05-01",
      "latitude": 40.75,
      "longitude": -73.99,
      "openViolations": 1
    }
  ]
}

Browse & filter restaurants

GET/api/v1/restaurants

The whole city, filterable. Grade/score/risk/closure filters are computed from each establishment's full record, so filtered pages can return fewer than `limit` rows — keep following `meta.nextCursor`.

Paginated — follow meta.nextCursor until null.

Parameters

NameTypeDescription
qstringName or address fragment.
boroughstringComma list of boroughs.
zipstringComma list of ZIP codes.
cuisinestringComma list of cuisines (see /v1/meta/cuisines).
gradestringComma list of current grades (A,B,C,Z,P,N).
riskLevelstringComma list of risk levels.
minScoreintegerCurrent inspection score at least this (higher is worse).
maxScoreintegerCurrent inspection score at most this.
closedbooleanOnly establishments currently marked closed (or not).
hasOpenViolationsbooleanOnly establishments with (or without) open items.
verminSincestringHad a vermin-category citation on/after this date.
inspectedSincestringLast inspected on/after this date.
inspectedUntilstringLast inspected on/before this date.
sortname | -name | lastInspectedAt | -lastInspectedAt`name` or `lastInspectedAt`; prefix `-` for descending (default `-lastInspectedAt`).
limitintegerPage size, 1–100 (default 20).
cursorstringOpaque page cursor from the previous response's `meta.nextCursor`.

Response — the `data` object

FieldTypeDescription
camisstringDOHMH permit number — the establishment's id.
namestringDoing-business-as name.
addressstringStreet address (borough is its own field).
boroughstringBorough.
zipstring | nullZIP code.
cuisinestring | nullCuisine description.
gradestring | nullPosted grade: A|B|C|Z|P|N (Z/P = pending, N = not yet graded).
scoreinteger | nullLatest inspection score — LOWER is better; 0–13 is the A band.
closedbooleanCurrently marked closed by the Health Department.
riskLevelLOW | MODERATE | HIGH | SEVERELOW | MODERATE | HIGH | SEVERE.
riskScoreinteger0–100, higher is worse.
lastInspectedAtstring | nullMost recent inspection.
latitudenumber | null
longitudenumber | null
openViolationsintegerItems open right now (latest-cycle citations).
request · cURL
curl "https://www.dailydog.ai/api/v1/restaurants" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "camis": "90000005",
      "name": "MIDNIGHT DINER",
      "address": "700 EXAMPLE CONCOURSE",
      "borough": "Bronx",
      "zip": "10451",
      "cuisine": "American",
      "grade": "C",
      "score": 38,
      "closed": false,
      "riskLevel": "HIGH",
      "riskScore": 58,
      "lastInspectedAt": "2026-06-05",
      "latitude": 40.827,
      "longitude": -73.925,
      "openViolations": 3
    }
  ],
  "meta": {
    "nextCursor": "bzoyMA",
    "returned": 1
  }
}

Restaurants near a point

GET/api/v1/restaurants/nearby

Nearest-first within `radius` meters, each with `distanceMeters`.

Parameters

NameTypeDescription
lat *numberNYC latitude.
lng *numberNYC longitude.
radiusintegerMeters, 1–2000 (default 300).
limitintegerMax results, 1–50 (default 20).
gradestringComma list of grades to keep.
cuisinestringComma list of cuisines to keep.
riskLevelstringComma list of risk levels to keep.
maxScoreintegerKeep scores at or below this.

Response — the `data` object

FieldTypeDescription
camisstringDOHMH permit number — the establishment's id.
namestringDoing-business-as name.
addressstringStreet address (borough is its own field).
boroughstringBorough.
zipstring | nullZIP code.
cuisinestring | nullCuisine description.
gradestring | nullPosted grade: A|B|C|Z|P|N (Z/P = pending, N = not yet graded).
scoreinteger | nullLatest inspection score — LOWER is better; 0–13 is the A band.
closedbooleanCurrently marked closed by the Health Department.
riskLevelLOW | MODERATE | HIGH | SEVERELOW | MODERATE | HIGH | SEVERE.
riskScoreinteger0–100, higher is worse.
lastInspectedAtstring | nullMost recent inspection.
latitudenumber | null
longitudenumber | null
openViolationsintegerItems open right now (latest-cycle citations).
distanceMetersintegerDistance from the query point.
request · cURL
curl "https://www.dailydog.ai/api/v1/restaurants/nearby?lat=40.75&lng=-73.99" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "camis": "90000001",
      "name": "THE GILDED SPOON",
      "address": "12 TEST STREET",
      "borough": "Manhattan",
      "zip": "10001",
      "cuisine": "French",
      "grade": "A",
      "score": 9,
      "closed": false,
      "riskLevel": "LOW",
      "riskScore": 4,
      "lastInspectedAt": "2026-05-01",
      "latitude": 40.75,
      "longitude": -73.99,
      "openViolations": 1,
      "distanceMeters": 142
    }
  ]
}

Full restaurant profile

GET/api/v1/restaurants/{camis}

Identity, posted grade, the full risk assessment (inspections AND the hearing docket), the 3-year vermin report, and the money. **Recency weighting.** The `vermin` and `sanitary` blocks carry additive `weighted` variants of their flat counts: each finding is weighted 0.5^(ageDays/365) — a 12-month half-life — so a citation from three weeks ago counts ~1.0 while one from three years ago counts ~0.125. Use the weighted numbers when you want 'how bad is it now'; the flat counts remain unchanged for compatibility. **Owner response signal.** When the establishment's operator has uploaded proof that they've corrected a currently-open violation — a pest-control invoice, a refrigeration repair receipt, a re-issued certificate — the profile carries a `remediation` object and `sanitary.ownerResponseSignal` becomes `"documented_fixes"`. Both are null otherwise. This is owner-submitted and UNVERIFIED: it is a transparent response indicator, pending re-inspection, and it never moves the grade, score, or risk (those stay anchored to official city records). Render it as information alongside the record, not as a rating — e.g. “Owner has documented fixes for 3 of 5 open items — pending re-inspection”, using `remediation.documentedOpenViolations` of `remediation.openViolations`. Try it against the fixture city with a `dd_test_` key: CAMIS `90000003` has a documented fix on file.

Parameters

NameTypeDescription
camis * (path)stringDOHMH permit number.

Response — the `data` object

FieldTypeDescription
restaurantRestaurantSummary
gradeDatestring | nullWhen the posted grade was issued.
riskobject
scoreinteger0–100, higher is worse.
levelLOW | MODERATE | HIGH | SEVERELOW | MODERATE | HIGH | SEVERE.
factorsarray<object>
keystringStable factor key.
labelstringHuman label.
countintegerMatching records.
detailstringWhy it matters.
verminVerminReport
sanitarySanitaryReportThe food-safety story only — computed from health-inspection records; enforcement and administrative records are excluded. Food categories: vermin, food_temp, hygiene, facility.
statsRestaurantStats
communityCommunityBlockCommunity-report rollup for the establishment. `counts` are over the non-hidden set; `scoreAdjustment` is the capped, decaying dock in [-8, 0], surfaced as its own labeled line (never silently blended). Praise never adds points.
remediationobject | nullThe owner-response signal, or null when nothing is documented against an open violation. Owner-submitted proof of fix, UNVERIFIED and pending re-inspection — presentation only, never a score change.
openViolationsintegerViolations open right now — the set the signal is measured against.
documentedOpenViolationsintegerOpen violations with at least one owner-uploaded document.
categoriesarray<vermin | food_temp | hygiene | facility | admin | other>Distinct categories among the documented open violations.
lastDocumentedAtstring | nullMost recent upload date among documented open violations.
request · cURL
curl "https://www.dailydog.ai/api/v1/restaurants/90000005" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": {
    "restaurant": {
      "camis": "90000005",
      "name": "MIDNIGHT DINER",
      "address": "700 EXAMPLE CONCOURSE",
      "borough": "Bronx",
      "zip": "10451",
      "cuisine": "American",
      "grade": "C",
      "score": 38,
      "closed": false,
      "riskLevel": "HIGH",
      "riskScore": 58,
      "lastInspectedAt": "2026-06-05",
      "latitude": 40.827,
      "longitude": -73.925,
      "openViolations": 3
    },
    "gradeDate": "2026-06-05",
    "risk": {
      "score": 58,
      "level": "HIGH",
      "factors": [
        {
          "key": "vermin",
          "label": "Vermin activity cited",
          "count": 3,
          "detail": "Roach, rodent, or fly evidence — the violations most likely to escalate to closure when they recur."
        },
        {
          "key": "grade_trouble",
          "label": "Letter grade at risk",
          "count": 1,
          "detail": "A C grade keeps customers away and invites a compliance inspection."
        }
      ]
    },
    "vermin": {
      "mice": 2,
      "rats": 1,
      "roaches": 2,
      "flies": 0,
      "other": 0,
      "conducive": 1,
      "lastSightedAt": "2026-06-05",
      "weighted": {
        "rats": 1,
        "mice": 1.9,
        "roaches": 1.9,
        "flies": 0,
        "other": 0,
        "conducive": 0.7
      }
    },
    "sanitary": {
      "latestCycleScore": 38,
      "latestInitialScore": 38,
      "weighted": {
        "criticalFood": 4.2,
        "closures": 0.7,
        "worstScoreWeight": 0.67
      },
      "worstScore36mo": 42,
      "criticalFood24mo": 5,
      "openFoodViolations": 3,
      "closures36mo": 1,
      "ownerResponseSignal": null
    },
    "stats": {
      "openViolations": 3,
      "totalViolations": 6,
      "criticalViolations": 5,
      "inspectionCount": 2,
      "closureCount": 1,
      "oathSummonses": 0,
      "finesImposedCents": 0,
      "finesDueCents": 0,
      "defaultedHearings": 0
    },
    "community": {
      "counts": {
        "pest": 1,
        "food_poisoning": 1,
        "sanitation_other": 0,
        "praise_taste": 0,
        "praise_clean": 1
      },
      "lastReportAt": "2026-07-30",
      "scoreAdjustment": -4
    },
    "remediation": null
  }
}

Inspection history

GET/api/v1/restaurants/{camis}/inspections

Every inspection visit, newest first. Lower scores are better; 0–13 is the A band.

Parameters

NameTypeDescription
camis * (path)stringDOHMH permit number.

Response — the `data` object

FieldTypeDescription
inspectedAtstringVisit date.
typestring | nullInspection program/type.
scoreinteger | nullScore issued at this visit (lower is better).
gradestring | nullGrade issued at this visit, if any.
actionstring | nullThe Health Department's action line.
closedRestaurantbooleanThis visit closed the establishment.
violationsarray<Violation>
request · cURL
curl "https://www.dailydog.ai/api/v1/restaurants/90000005/inspections" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "inspectedAt": "2026-06-05",
      "type": "Cycle Inspection / Initial Inspection",
      "score": 38,
      "grade": "C",
      "action": "Violations were cited in the following area(s).",
      "closedRestaurant": false,
      "violations": [
        {
          "code": "04L",
          "description": "Evidence of mice or live mice present in facility's food and/or non-food areas.",
          "critical": true,
          "inspectedAt": "2026-06-05",
          "inspectionType": "Cycle Inspection / Initial Inspection",
          "category": "vermin"
        },
        {
          "code": "04K",
          "description": "Evidence of rats or live rats present in facility's food and/or non-food areas.",
          "critical": true,
          "inspectedAt": "2026-06-05",
          "inspectionType": "Cycle Inspection / Initial Inspection",
          "category": "vermin"
        },
        {
          "code": "04M",
          "description": "Live roaches present in facility's food and/or non-food area.",
          "critical": true,
          "inspectedAt": "2026-06-05",
          "inspectionType": "Cycle Inspection / Initial Inspection",
          "category": "vermin"
        }
      ]
    }
  ]
}

Violations

GET/api/v1/restaurants/{camis}/violations

The flat violation list, newest first.

Parameters

NameTypeDescription
camis * (path)stringDOHMH permit number.
openbooleantrue = only citations from the most recent inspection (what a re-inspection re-checks).

Response — the `data` object

FieldTypeDescription
codestring | nullDOHMH violation code.
descriptionstringWhat was cited.
criticalbooleanCritical citations drive the score and re-inspections.
inspectedAtstringInspection date.
inspectionTypestring | nullInspection program/type.
categoryvermin | food_temp | hygiene | facility | admin | otherContract category.
request · cURL
curl "https://www.dailydog.ai/api/v1/restaurants/90000005/violations" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "code": "04L",
      "description": "Evidence of mice or live mice present in facility's food and/or non-food areas.",
      "critical": true,
      "inspectedAt": "2026-06-05",
      "inspectionType": "Cycle Inspection / Initial Inspection",
      "category": "vermin"
    },
    {
      "code": "04K",
      "description": "Evidence of rats or live rats present in facility's food and/or non-food areas.",
      "critical": true,
      "inspectedAt": "2026-06-05",
      "inspectionType": "Cycle Inspection / Initial Inspection",
      "category": "vermin"
    }
  ]
}

Batch profiles (max 50)

POST/api/v1/restaurants/batch

Refresh a saved list in one call. Unknown ids come back in `meta.notFound`.

Paginated — follow meta.nextCursor until null.

Request body

application/json
{
  "camis": [
    "90000003",
    "90000005",
    "00000000"
  ]
}

Response — the `data` object

FieldTypeDescription
restaurantRestaurantSummary
gradeDatestring | nullWhen the posted grade was issued.
riskobject
scoreinteger0–100, higher is worse.
levelLOW | MODERATE | HIGH | SEVERELOW | MODERATE | HIGH | SEVERE.
factorsarray<object>
keystringStable factor key.
labelstringHuman label.
countintegerMatching records.
detailstringWhy it matters.
verminVerminReport
sanitarySanitaryReportThe food-safety story only — computed from health-inspection records; enforcement and administrative records are excluded. Food categories: vermin, food_temp, hygiene, facility.
statsRestaurantStats
communityCommunityBlockCommunity-report rollup for the establishment. `counts` are over the non-hidden set; `scoreAdjustment` is the capped, decaying dock in [-8, 0], surfaced as its own labeled line (never silently blended). Praise never adds points.
remediationobject | nullThe owner-response signal, or null when nothing is documented against an open violation. Owner-submitted proof of fix, UNVERIFIED and pending re-inspection — presentation only, never a score change.
openViolationsintegerViolations open right now — the set the signal is measured against.
documentedOpenViolationsintegerOpen violations with at least one owner-uploaded document.
categoriesarray<vermin | food_temp | hygiene | facility | admin | other>Distinct categories among the documented open violations.
lastDocumentedAtstring | nullMost recent upload date among documented open violations.
request · cURL
curl -X POST "https://www.dailydog.ai/api/v1/restaurants/batch" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985" \
  -H "Content-Type: application/json" \
  -d '{"camis":["90000003","90000005","00000000"]}'
mock response (fixture city)
{
  "data": [
    {
      "restaurant": {
        "camis": "90000003",
        "name": "DRAGON PALACE",
        "address": "230 SAMPLE BOULEVARD",
        "borough": "Manhattan",
        "zip": "10013",
        "cuisine": "Chinese",
        "grade": "B",
        "score": 18,
        "closed": false,
        "riskLevel": "MODERATE",
        "riskScore": 32,
        "lastInspectedAt": "2026-04-02",
        "latitude": 40.717,
        "longitude": -73.998,
        "openViolations": 2
      },
      "gradeDate": "2026-04-02",
      "risk": {
        "score": 32,
        "level": "MODERATE",
        "factors": [
          {
            "key": "grade_trouble",
            "label": "Letter grade at risk",
            "count": 2,
            "detail": "The score must come down at the next cycle to keep the B from becoming a C."
          }
        ]
      },
      "vermin": {
        "mice": 0,
        "rats": 0,
        "roaches": 0,
        "flies": 0,
        "other": 0,
        "conducive": 0,
        "lastSightedAt": null,
        "weighted": {
          "rats": 0,
          "mice": 0,
          "roaches": 0,
          "flies": 0,
          "other": 0,
          "conducive": 0
        }
      },
      "sanitary": {
        "latestCycleScore": 18,
        "latestInitialScore": 18,
        "weighted": {
          "criticalFood": 1.7,
          "closures": 0,
          "worstScoreWeight": 0.58
        },
        "worstScore36mo": 22,
        "criticalFood24mo": 2,
        "openFoodViolations": 2,
        "closures36mo": 0,
        "ownerResponseSignal": "documented_fixes"
      },
      "stats": {
        "openViolations": 2,
        "totalViolations": 3,
        "criticalViolations": 2,
        "inspectionCount": 2,
        "closureCount": 0,
        "oathSummonses": 0,
        "finesImposedCents": 0,
        "finesDueCents": 0,
        "defaultedHearings": 0
      },
      "community": {
        "counts": {
          "pest": 0,
          "food_poisoning": 0,
          "sanitation_other": 0,
          "praise_taste": 0,
          "praise_clean": 0
        },
        "lastReportAt": null,
        "scoreAdjustment": 0
      },
      "remediation": {
        "openViolations": 2,
        "documentedOpenViolations": 1,
        "categories": [
          "hygiene"
        ],
        "lastDocumentedAt": "2026-05-20"
      }
    },
    {
      "restaurant": {
        "camis": "90000005",
        "name": "MIDNIGHT DINER",
        "address": "700 EXAMPLE CONCOURSE",
        "borough": "Bronx",
        "zip": "10451",
        "cuisine": "American",
        "grade": "C",
        "score": 38,
        "closed": false,
        "riskLevel": "HIGH",
        "riskScore": 58,
        "lastInspectedAt": "2026-06-05",
        "latitude": 40.827,
        "longitude": -73.925,
        "openViolations": 3
      },
      "gradeDate": "2026-06-05",
      "risk": {
        "score": 58,
        "level": "HIGH",
        "factors": [
          {
            "key": "vermin",
            "label": "Vermin activity cited",
            "count": 3,
            "detail": "Roach, rodent, or fly evidence — the violations most likely to escalate to closure when they recur."
          },
          {
            "key": "grade_trouble",
            "label": "Letter grade at risk",
            "count": 1,
            "detail": "A C grade keeps customers away and invites a compliance inspection."
          }
        ]
      },
      "vermin": {
        "mice": 2,
        "rats": 1,
        "roaches": 2,
        "flies": 0,
        "other": 0,
        "conducive": 1,
        "lastSightedAt": "2026-06-05",
        "weighted": {
          "rats": 1,
          "mice": 1.9,
          "roaches": 1.9,
          "flies": 0,
          "other": 0,
          "conducive": 0.7
        }
      },
      "sanitary": {
        "latestCycleScore": 38,
        "latestInitialScore": 38,
        "weighted": {
          "criticalFood": 4.2,
          "closures": 0.7,
          "worstScoreWeight": 0.67
        },
        "worstScore36mo": 42,
        "criticalFood24mo": 5,
        "openFoodViolations": 3,
        "closures36mo": 1,
        "ownerResponseSignal": null
      },
      "stats": {
        "openViolations": 3,
        "totalViolations": 6,
        "criticalViolations": 5,
        "inspectionCount": 2,
        "closureCount": 1,
        "oathSummonses": 0,
        "finesImposedCents": 0,
        "finesDueCents": 0,
        "defaultedHearings": 0
      },
      "community": {
        "counts": {
          "pest": 1,
          "food_poisoning": 1,
          "sanitation_other": 0,
          "praise_taste": 0,
          "praise_clean": 1
        },
        "lastReportAt": "2026-07-30",
        "scoreAdjustment": -4
      },
      "remediation": null
    }
  ],
  "meta": {
    "notFound": [
      "00000000"
    ]
  }
}

City feeds

City-wide violation and inspection streams.

City-wide violation search

GET/api/v1/violations

The headline query: "every rat citation in Brooklyn this month". Newest first. Geo filtering: pass `lat`+`lng` (NYC coordinates) with an optional `radius` in meters (default 1000, max 5000) to pull citations within a circle — built for map viewports; combines with every other filter.

Paginated — follow meta.nextCursor until null.

Parameters

NameTypeDescription
codestringComma list of violation codes (see /v1/meta/violation-codes).
categoryvermin | food_temp | hygiene | facility | admin | otherComma list of categories.
criticalbooleanOnly critical (or non-critical) citations.
boroughstringComma list of boroughs.
zipstringComma list of ZIP codes.
cuisinestringComma list of cuisines.
qstringEstablishment-name fragment.
sincestringCited on/after this date.
untilstringCited on/before this date.
latnumberCircle center latitude (NYC bounds; requires lng).
lngnumberCircle center longitude (NYC bounds; requires lat).
radiusintegerCircle radius in meters, 1–5000 (default 1000). Only with lat/lng.
limitintegerPage size, 1–100 (default 20).
cursorstringOpaque page cursor from the previous response's `meta.nextCursor`.

Response — the `data` object

FieldTypeDescription
codestring | nullDOHMH violation code.
descriptionstringWhat was cited.
criticalbooleanCritical citations drive the score and re-inspections.
inspectedAtstringInspection date.
inspectionTypestring | nullInspection program/type.
categoryvermin | food_temp | hygiene | facility | admin | otherContract category.
camisstringEstablishment id.
restaurantNamestringEstablishment name.
addressstringStreet address.
boroughstringBorough.
latitudenumber | nullEstablishment latitude (null when the record lacks coordinates).
longitudenumber | nullEstablishment longitude.
zipstring | nullZIP code.
request · cURL
curl "https://www.dailydog.ai/api/v1/violations" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "code": "04L",
      "description": "Evidence of mice or live mice present in facility's food and/or non-food areas.",
      "critical": true,
      "inspectedAt": "2026-06-05",
      "inspectionType": "Cycle Inspection / Initial Inspection",
      "category": "vermin",
      "camis": "90000005",
      "restaurantName": "MIDNIGHT DINER",
      "address": "700 EXAMPLE CONCOURSE",
      "borough": "Bronx"
    }
  ],
  "meta": {
    "nextCursor": null,
    "returned": 1
  }
}

City-wide inspection feed

GET/api/v1/inspections

"What closed this week" — one row per inspection visit, newest first.

Paginated — follow meta.nextCursor until null.

Parameters

NameTypeDescription
boroughstringComma list of boroughs.
gradestringComma list of grades issued at the visit.
minScoreintegerScore at least this (higher is worse).
closedRestaurantbooleanOnly visits that closed (or didn't close) the establishment.
sincestringInspected on/after this date.
untilstringInspected on/before this date.
limitintegerPage size, 1–100 (default 20).
cursorstringOpaque page cursor from the previous response's `meta.nextCursor`.

Response — the `data` object

FieldTypeDescription
camisstringEstablishment id.
namestringEstablishment name.
addressstringStreet address.
boroughstringBorough.
inspectedAtstringVisit date.
typestring | nullInspection program/type.
scoreinteger | nullScore issued (lower is better).
gradestring | nullGrade issued, if any.
closedRestaurantbooleanThis visit closed the establishment.
request · cURL
curl "https://www.dailydog.ai/api/v1/inspections" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "camis": "90000007",
      "name": "CROWN FRIED CLUCK",
      "address": "1490 PLACEHOLDER AVENUE",
      "borough": "Brooklyn",
      "inspectedAt": "2026-07-01",
      "type": "Cycle Inspection / Initial Inspection",
      "score": 51,
      "grade": null,
      "closedRestaurant": true
    }
  ],
  "meta": {
    "nextCursor": null,
    "returned": 1
  }
}

Meta & stats

Enumerations for filter UIs, and aggregates.

Cuisine enumeration

GET/api/v1/meta/cuisines

Most common first — feed your filter UI.

request · cURL
curl "https://www.dailydog.ai/api/v1/meta/cuisines" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    "American",
    "Chinese",
    "Pizza"
  ]
}

Borough enumeration

GET/api/v1/meta/boroughs

request · cURL
curl "https://www.dailydog.ai/api/v1/meta/boroughs" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    "Bronx",
    "Brooklyn",
    "Manhattan",
    "Queens",
    "Staten Island"
  ]
}

Violation-code enumeration

GET/api/v1/meta/violation-codes

Code → description → contract category, most cited first.

Response — the `data` object

FieldTypeDescription
codestringDOHMH violation code.
descriptionstringWhat the code means.
categoryvermin | food_temp | hygiene | facility | admin | otherContract category.
request · cURL
curl "https://www.dailydog.ai/api/v1/meta/violation-codes" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "code": "02B",
      "description": "Hot food item not held at or above 140°F.",
      "category": "food_temp"
    },
    {
      "code": "02G",
      "description": "Cold food item held above 41°F.",
      "category": "food_temp"
    },
    {
      "code": "04H",
      "description": "Raw food not properly washed prior to serving.",
      "category": "hygiene"
    }
  ]
}

City-wide restaurant aggregates

GET/api/v1/stats/restaurants

`byGrade` counts distinct establishments graded that letter on an inspection in the last 12 months; `byBorough` counts distinct establishments on record. Cached 6 hours.

Parameters

NameTypeDescription
boroughstringNarrow to one borough.
cuisinestringNarrow to one cuisine.

Response — the `data` object

FieldTypeDescription
establishmentsintegerDistinct establishments on record.
byGradeobjectDistinct establishments graded that letter in the last 12 months.
byBoroughobjectDistinct establishments per borough.
violationsLast30DaysintegerCitations recorded in the last 30 days.
request · cURL
curl "https://www.dailydog.ai/api/v1/stats/restaurants" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": {
    "establishments": 8,
    "byGrade": {
      "A": 2,
      "B": 2,
      "C": 2,
      "Z": 1,
      "P": 1
    },
    "byBorough": {
      "Manhattan": 2,
      "Brooklyn": 2,
      "Queens": 2,
      "Bronx": 1,
      "Staten Island": 1
    },
    "violationsLast30Days": 6
  }
}

Properties

Buildings keyed by BBL (borough-block-lot).

Search addresses

GET/api/v1/properties/search

Free-text address → tax lots (BBL) with the public page slug.

Parameters

NameTypeDescription
q *stringAddress fragment, 3–120 chars.
limitintegerMax results, 1–25 (default 10).

Response — the `data` object

FieldTypeDescription
bblstring10-digit borough-block-lot.
addressstringStreet line.
boroughstringBorough.
slugstringPublic page: dailydog.ai/property/<slug>.
request · cURL
curl "https://www.dailydog.ai/api/v1/properties/search?q=example" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "bbl": "1011850028",
      "address": "302 West 76 Street",
      "borough": "Manhattan",
      "slug": "302-west-76-street-new-york"
    }
  ]
}

Property profile

GET/api/v1/properties/{bbl}

Risk score, open counts, penalty dollars, defaults, per-agency rollup.

Parameters

NameTypeDescription
bbl * (path)string10-digit borough-block-lot.

Response — the `data` object

FieldTypeDescription
bblstring10-digit borough-block-lot.
addressstringAddress on record.
boroughstringBorough.
riskLevelLOW | MODERATE | HIGH | SEVERELOW | MODERATE | HIGH | SEVERE.
riskScoreinteger0–100, higher is worse.
openViolationsintegerViolations open right now.
totalRecordsintegerRecords across every city system swept.
finesImposedCentsintegerPenalties imposed. Integer cents.
finesDueCentsintegerPenalties currently due — judgment exposure. Integer cents.
defaultedHearingsintegerMissed hearings that became default judgments.
agenciesarray<object>
agencystringEnforcement system.
openCountintegerOpen records there.
request · cURL
curl "https://www.dailydog.ai/api/v1/properties/3900020002" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": {
    "bbl": "3900020002",
    "address": "250 FIXTURE AVENUE",
    "borough": "Brooklyn",
    "riskLevel": "HIGH",
    "riskScore": 71,
    "openViolations": 6,
    "totalRecords": 87,
    "finesImposedCents": 8125000,
    "finesDueCents": 6650000,
    "defaultedHearings": 3,
    "agencies": [
      {
        "agency": "ECB",
        "openCount": 4
      },
      {
        "agency": "DOB",
        "openCount": 2
      }
    ]
  }
}

Itemized violations at a lot

GET/api/v1/properties/{bbl}/violations

The monitoring contract: poll with `since=` set to your last check to see only what's new.

Paginated — follow meta.nextCursor until null.

Parameters

NameTypeDescription
bbl * (path)string10-digit borough-block-lot.
agencystringComma list of agencies (ECB, DOB, DOB_NOW…).
statusopen | closed`open` or `closed`.
sincestringIssued on/after this date.
untilstringIssued on/before this date.
sortdate | -date | penalty | -penalty`date` or `penalty`; prefix `-` for descending (default `-date`).
limitintegerPage size, 1–100 (default 20).
cursorstringOpaque page cursor from the previous response's `meta.nextCursor`.

Response — the `data` object

FieldTypeDescription
identifierstringViolation/summons number — matches the city's paperwork.
agencystringEnforcement system (ECB, DOB…).
recordTypestringRecord class.
statusstringCurrent status line.
descriptionstringWhat was cited.
isOpenbooleanStill demands action.
issuedAtstring | nullIssue date.
statusAtstring | nullLast status/hearing date.
penaltyImposedCentsintegerPenalty imposed. Integer cents.
penaltyDueCentsintegerBalance currently due. Integer cents.
request · cURL
curl "https://www.dailydog.ai/api/v1/properties/3900020002/violations" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "identifier": "039900001R",
      "agency": "ECB",
      "recordType": "OATH summons (DOB)",
      "status": "DEFAULTED — $32,500 due",
      "description": "Work without a permit: interior demolition observed at cellar level.",
      "isOpen": true,
      "issuedAt": "2026-03-02",
      "statusAt": "2026-05-10",
      "penaltyImposedCents": 3250000,
      "penaltyDueCents": 3250000
    }
  ],
  "meta": {
    "nextCursor": null,
    "returned": 1
  }
}

Permit & job filings at a lot

GET/api/v1/properties/{bbl}/permits

What's open at the BBL before you file anew — permit history included.

Paginated — follow meta.nextCursor until null.

Parameters

NameTypeDescription
bbl * (path)string10-digit borough-block-lot.
statusopen | closed`open` or `closed`.
sincestringIssued on/after this date.
untilstringIssued on/before this date.
sortdate | -date`date` or `-date` (default `-date`).
limitintegerPage size, 1–100 (default 20).
cursorstringOpaque page cursor from the previous response's `meta.nextCursor`.

Response — the `data` object

FieldTypeDescription
identifierstringJob/permit number.
agencystringDOB | DOB_NOW.
recordTypestringFiling class.
statusstringCurrent status line.
descriptionstringScope of work.
isOpenbooleanStill open (not signed off/closed).
issuedAtstring | nullIssue/filing date.
expiresAtstring | nullPermit expiration.
statusAtstring | nullLast status date.
request · cURL
curl "https://www.dailydog.ai/api/v1/properties/3900020002/permits" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "identifier": "390004567",
      "agency": "DOB",
      "recordType": "Alteration job filing",
      "status": "PERMIT ISSUED",
      "description": "Facade repair, front elevation",
      "isOpen": true,
      "issuedAt": "2025-11-03",
      "expiresAt": "2026-11-03",
      "statusAt": "2025-11-03"
    }
  ],
  "meta": {
    "nextCursor": null,
    "returned": 1
  }
}

The compliance calendar

GET/api/v1/properties/{bbl}/deadlines

DailyDog-derived, not raw city data: every recurring obligation the building owes — facade cycles (FISP/LL11), benchmarking (LL84), emissions (LL97), elevator CAT1, boiler tests, HPD registration and more — with due dates, statuses, penalties, and what to do about each.

Parameters

NameTypeDescription
bbl * (path)string10-digit borough-block-lot.
statusstringComma list of ok, due_soon, overdue, action_needed, unverifiable.
dueBeforestringOnly obligations due on/before this date.

Response — the `data` object

FieldTypeDescription
kindstringStable obligation key (facade_filing, benchmarking, elevator_cat1…).
labelstringHuman label.
statusok | due_soon | overdue | action_needed | unverifiableObligation status.
dueDatestring | nullNext date something is owed.
lastEvidenceAtstring | nullMost recent satisfying filing the city shows.
basisstringPlain-English rule + citation.
penaltystringWhat missing it costs.
verifiablebooleanFalse when no public record can confirm compliance — treat as a reminder.
whatToDostringThe playbook: what to actually do, and what to have ready.
guideUrlstring | nullStep-by-step guide on dailydog.ai.
request · cURL
curl "https://www.dailydog.ai/api/v1/properties/3900020002/deadlines" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "kind": "facade_filing",
      "label": "Facade inspection report (FISP / LL11)",
      "status": "overdue",
      "dueDate": "2026-02-21",
      "lastEvidenceAt": null,
      "basis": "DOB shows no facade report filed for the current 5-year cycle window.",
      "penalty": "$1,000/month failure-to-file plus an ECB violation.",
      "verifiable": true,
      "whatToDo": "Retain a QEWI to inspect and file the cycle report in DOB NOW immediately."
    },
    {
      "kind": "elevator_cat1",
      "label": "Elevator CAT1 annual test",
      "status": "due_soon",
      "dueDate": "2026-09-30",
      "lastEvidenceAt": "2025-09-12",
      "basis": "Every registered elevator device needs an annual CAT1 test filed with DOB.",
      "penalty": "$3,000 per device per year unfiled, plus $250/month late surcharges.",
      "verifiable": true,
      "whatToDo": "Schedule the CAT1 test with your elevator agency before the window closes."
    }
  ]
}

Portfolio screening (max 25)

POST/api/v1/properties/batch

Up to 25 BBLs → the full profile per lot. Profiles are cached server-side for 6 hours, so repeated sweeps are fast. Unknown BBLs come back in `meta.notFound`.

Paginated — follow meta.nextCursor until null.

Request body

application/json
{
  "bbls": [
    "3900020002",
    "1900010001"
  ]
}

Response — the `data` object

FieldTypeDescription
bblstring10-digit borough-block-lot.
addressstringAddress on record.
boroughstringBorough.
riskLevelLOW | MODERATE | HIGH | SEVERELOW | MODERATE | HIGH | SEVERE.
riskScoreinteger0–100, higher is worse.
openViolationsintegerViolations open right now.
totalRecordsintegerRecords across every city system swept.
finesImposedCentsintegerPenalties imposed. Integer cents.
finesDueCentsintegerPenalties currently due — judgment exposure. Integer cents.
defaultedHearingsintegerMissed hearings that became default judgments.
agenciesarray<object>
agencystringEnforcement system.
openCountintegerOpen records there.
request · cURL
curl -X POST "https://www.dailydog.ai/api/v1/properties/batch" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985" \
  -H "Content-Type: application/json" \
  -d '{"bbls":["3900020002","1900010001"]}'
mock response (fixture city)
{
  "data": [
    {
      "bbl": "3900020002",
      "address": "250 FIXTURE AVENUE",
      "borough": "Brooklyn",
      "riskLevel": "HIGH",
      "riskScore": 71,
      "openViolations": 6,
      "totalRecords": 87,
      "finesImposedCents": 8125000,
      "finesDueCents": 6650000,
      "defaultedHearings": 3,
      "agencies": [
        {
          "agency": "ECB",
          "openCount": 4
        },
        {
          "agency": "DOB",
          "openCount": 2
        }
      ]
    }
  ],
  "meta": {
    "notFound": []
  }
}

Contractors

Companies as the city dockets them, keyed by slug.

Browse companies

GET/api/v1/contractors

The enforcement docket, company by company. Sorting by `-finesDueCents` narrows to companies with money on the books (the records can't rank an empty balance).

Paginated — follow meta.nextCursor until null.

Parameters

NameTypeDescription
qstringCompany-name fragment.
riskLevelstringComma list of risk levels (balance-weighted at browse level).
minFinesDueCentsintegerOnly companies owing at least this (integer cents).
minTicketsintegerOnly companies with at least this many summonses.
sortstring`tickets`, `finesDueCents`, or `name`; prefix `-` for descending (default `-tickets`).
limitintegerPage size, 1–100 (default 20).
cursorstringOpaque page cursor from the previous response's `meta.nextCursor`.

Response — the `data` object

FieldTypeDescription
slugstringCanonical company slug — the id for the profile endpoints.
namestringCompany name as the city dockets it.
ticketCountintegerSummonses on the docket.
finesDueCentsintegerOutstanding balance. Integer cents.
riskLevelLOW | MODERATE | HIGH | SEVEREBalance-weighted at browse/search level; the profile carries the full assessment.
request · cURL
curl "https://www.dailydog.ai/api/v1/contractors" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "slug": "test-titan-construction",
      "name": "Test Titan Construction Corp",
      "ticketCount": 42,
      "finesDueCents": 24800000,
      "riskLevel": "SEVERE"
    }
  ],
  "meta": {
    "nextCursor": null,
    "returned": 1
  }
}

Search companies

GET/api/v1/contractors/search

Name search, biggest outstanding balances first.

Parameters

NameTypeDescription
q *stringCompany-name fragment, 3–120 chars.
limitintegerMax results, 1–25 (default 10).

Response — the `data` object

FieldTypeDescription
slugstringCanonical company slug — the id for the profile endpoints.
namestringCompany name as the city dockets it.
ticketCountintegerSummonses on the docket.
finesDueCentsintegerOutstanding balance. Integer cents.
riskLevelLOW | MODERATE | HIGH | SEVEREBalance-weighted at browse/search level; the profile carries the full assessment.
request · cURL
curl "https://www.dailydog.ai/api/v1/contractors/search?q=example" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "slug": "test-titan-construction",
      "name": "Test Titan Construction Corp",
      "ticketCount": 42,
      "finesDueCents": 24800000,
      "riskLevel": "SEVERE"
    }
  ]
}

Company docket profile

GET/api/v1/contractors/{slug}

Totals across every docket spelling of the company, plus the reopen-window savings envelope (the floor a granted new hearing erases; the ceiling if charges dismiss).

Parameters

NameTypeDescription
slug * (path)stringCanonical company slug from search/browse.

Response — the `data` object

FieldTypeDescription
slugstringCanonical company slug.
namestringPrimary docket spelling.
riskLevelLOW | MODERATE | HIGH | SEVEREFull reputation assessment.
ticketsintegerSummonses across every docket spelling.
openTicketsintegerTickets still demanding action (money due or hearing ahead).
finesImposedCentsintegerPenalties imposed. Integer cents.
finesDueCentsintegerOutstanding balance. Integer cents.
defaultedHearingsintegerUnpaid default judgments.
reopenableSavingsMinCentsintegerFloor: default inflation a granted new hearing erases (live 75-day windows only). Integer cents.
reopenableSavingsMaxCentsintegerCeiling: everything at stake in live windows if charges dismiss. Integer cents.
request · cURL
curl "https://www.dailydog.ai/api/v1/contractors/test-titan-construction" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": {
    "slug": "test-titan-construction",
    "name": "Test Titan Construction Corp",
    "riskLevel": "SEVERE",
    "tickets": 42,
    "openTickets": 17,
    "finesImposedCents": 31250000,
    "finesDueCents": 24800000,
    "defaultedHearings": 11,
    "reopenableSavingsMinCents": 4350000,
    "reopenableSavingsMaxCents": 7100000
  }
}

The itemized docket

GET/api/v1/contractors/{slug}/tickets

Every summons, newest first. `reopenableOnly=true` is the savings play: defaults whose 75-day new-hearing window is still open, each with its deadline. `hearingAfter=` surfaces upcoming hearings for self-monitoring.

Paginated — follow meta.nextCursor until null.

Parameters

NameTypeDescription
slug * (path)stringCanonical company slug.
statusstringComma list of open, defaulted, closed.
hearingAfterstringOnly tickets with a hearing on/after this date.
reopenableOnlybooleanOnly defaults with a live reopen window.
sincestringIssued on/after this date.
untilstringIssued on/before this date.
limitintegerPage size, 1–100 (default 20).
cursorstringOpaque page cursor from the previous response's `meta.nextCursor`.

Response — the `data` object

FieldTypeDescription
ticketstring10-character summons number — matches the city's paperwork.
chargestringLead charge description.
issuedstring | nullViolation date.
hearingDatestring | nullHearing date (past or scheduled).
hearingResultstringThe city's hearing result/status line.
statusopen | defaulted | closedopen | defaulted | closed.
dueCentsintegerBalance due on this ticket. Integer cents.
imposedCentsintegerPenalty imposed. Integer cents.
soughtCentsintegerScheduled amount sought — what losing at a normal hearing costs. Integer cents.
defaultedbooleanA missed hearing turned this into a default judgment.
reopenableUntilstring | nullLast day a new-hearing request is auto-granted; null when no live window.
request · cURL
curl "https://www.dailydog.ai/api/v1/contractors/test-titan-construction/tickets" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "ticket": "039912345Z",
      "charge": "WORK WITHOUT A PERMIT",
      "issued": "2026-06-10",
      "hearingDate": "2026-07-08",
      "hearingResult": "DEFAULTED",
      "status": "defaulted",
      "dueCents": 2500000,
      "imposedCents": 2500000,
      "soughtCents": 625000,
      "defaulted": true,
      "reopenableUntil": "2026-09-21"
    }
  ],
  "meta": {
    "nextCursor": null,
    "returned": 1
  }
}

Bid-list screening (max 25)

POST/api/v1/contractors/batch

Up to 25 slugs → docket profiles. Unknown slugs come back in `meta.notFound`.

Paginated — follow meta.nextCursor until null.

Request body

application/json
{
  "slugs": [
    "test-titan-construction",
    "test-borough-builders"
  ]
}

Response — the `data` object

FieldTypeDescription
slugstringCanonical company slug.
namestringPrimary docket spelling.
riskLevelLOW | MODERATE | HIGH | SEVEREFull reputation assessment.
ticketsintegerSummonses across every docket spelling.
openTicketsintegerTickets still demanding action (money due or hearing ahead).
finesImposedCentsintegerPenalties imposed. Integer cents.
finesDueCentsintegerOutstanding balance. Integer cents.
defaultedHearingsintegerUnpaid default judgments.
reopenableSavingsMinCentsintegerFloor: default inflation a granted new hearing erases (live 75-day windows only). Integer cents.
reopenableSavingsMaxCentsintegerCeiling: everything at stake in live windows if charges dismiss. Integer cents.
request · cURL
curl -X POST "https://www.dailydog.ai/api/v1/contractors/batch" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985" \
  -H "Content-Type: application/json" \
  -d '{"slugs":["test-titan-construction","test-borough-builders"]}'
mock response (fixture city)
{
  "data": [
    {
      "slug": "test-titan-construction",
      "name": "Test Titan Construction Corp",
      "riskLevel": "SEVERE",
      "tickets": 42,
      "openTickets": 17,
      "finesImposedCents": 31250000,
      "finesDueCents": 24800000,
      "defaultedHearings": 11,
      "reopenableSavingsMinCents": 4350000,
      "reopenableSavingsMaxCents": 7100000
    }
  ],
  "meta": {
    "notFound": []
  }
}

Community reports

User-submitted issue reports and praise for an establishment, plus the per-download profile that attributes them. Device-keyed (send the app's per-install id as `X-Device-Id`); the server stores only a salted hash and never exposes it. Unverified negative reports move the score by a small, capped, decaying amount shown as its own labeled line — never silently blended. Hidden reports are retained but excluded from every public surface.

List community reports

GET/api/v1/restaurants/{camis}/reports

Active, upheld, and disputed reports for an establishment, newest first — hidden reports NEVER appear. Each entry carries a render-time `author` ({displayName, avatarId}); the device hash is never exposed. Filter by `kind` (comma-separated).

Paginated — follow meta.nextCursor until null.

Parameters

NameTypeDescription
camis * (path)stringDOHMH permit number.
kindstringFilter by kind (comma-separated): pest | food_poisoning | sanitation_other | praise_taste | praise_clean.
limitintegerPage size, 1–100 (default 20).
cursorstringOpaque page cursor from the previous response's `meta.nextCursor`.

Response — the `data` object

FieldTypeDescription
idstringReport id.
kindpest | food_poisoning | sanitation_other | praise_taste | praise_cleanReport kind.
pestSubtypestring | nullFor pest reports: rats | mice | roaches | flies | other; null otherwise.
bodystringThe reporter's description (20–500 chars, shown verbatim).
createdAtstringReport date (day precision on public surfaces).
photoIdsarray<string>
authorCommunityAuthor
request · cURL
curl "https://www.dailydog.ai/api/v1/restaurants/90000005/reports" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "id": "clr9y3m1b0001",
      "kind": "pest",
      "pestSubtype": "mice",
      "body": "Saw a mouse dart under the counter near the register around closing time.",
      "createdAt": "2026-07-30",
      "photoIds": [
        "clr9y3m1b0002"
      ],
      "author": {
        "displayName": "Bodega Regular",
        "avatarId": "clr8x2k9a0000"
      }
    }
  ],
  "meta": {
    "nextCursor": null,
    "returned": 1
  }
}

Submit a community report

POST/api/v1/restaurants/{camis}/reports

File a report. **Requires the `X-Device-Id` header** (the app's per-install id; absent → 400). JSON body with optional base64 photos (JPEG/PNG, ≤4MB each, max 3; EXIF is stripped server-side by re-encoding). Caps ride the device — the establishment itself is never capped: each device may file at most 3 reports per establishment per UTC day and 25 per day citywide (hidden reports count toward neither). Either trips a 429 whose error body carries a `scope` field (`establishment` | `device`).

Parameters

NameTypeDescription
camis * (path)stringDOHMH permit number.

Request body

application/json
{
  "kind": "pest",
  "pestSubtype": "mice",
  "body": "Saw a mouse dart under the counter near the register at close.",
  "photos": []
}

Response — the `data` object

FieldTypeDescription
idstringReport id.
kindpest | food_poisoning | sanitation_other | praise_taste | praise_cleanReport kind.
pestSubtypestring | nullFor pest reports: rats | mice | roaches | flies | other; null otherwise.
bodystringThe reporter's description (20–500 chars, shown verbatim).
createdAtstringReport date (day precision on public surfaces).
photoIdsarray<string>
authorCommunityAuthor
request · cURL
curl -X POST "https://www.dailydog.ai/api/v1/restaurants/90000005/reports" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985" \
  -H "Content-Type: application/json" \
  -d '{"kind":"pest","pestSubtype":"mice","body":"Saw a mouse dart under the counter near the register at close.","photos":[]}'
mock response (fixture city)
{
  "data": {
    "id": "clr9y3m1b0001",
    "kind": "pest",
    "pestSubtype": "mice",
    "body": "Saw a mouse dart under the counter near the register around closing time.",
    "createdAt": "2026-07-30",
    "photoIds": [
      "clr9y3m1b0002"
    ],
    "author": {
      "displayName": "Bodega Regular",
      "avatarId": "clr8x2k9a0000"
    }
  }
}

Serve a report photo

GET/api/v1/reports/photos/{photoId}

Public image bytes for a report photo, served with `X-Content-Type-Options: nosniff` and an allowlist-derived content type.

Parameters

NameTypeDescription
photoId * (path)stringPhoto id from a report's `photoIds`.
request · cURL
curl "https://www.dailydog.ai/api/v1/reports/photos/fixture-photo-1" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{}

Get your profile

GET/api/v1/profile

The caller's profile. **Requires `X-Device-Id`.** Returns the claimed username (or null), the stable fun default, the resolved displayName, avatarId (null → render a monogram), and rename-throttle timing.

Response — the `data` object

FieldTypeDescription
usernamestring | nullClaimed username, or null if never claimed.
funDefaultstringStable generated display name for an unclaimed device.
displayNamestringusername ?? funDefault — what surfaces render.
avatarIdstring | nullOpaque avatar id, or null (render a monogram).
createdAtstring | nullISO timestamp the profile row was created, or null.
renamedAtstring | nullISO timestamp of the last username change, or null.
canRenameAtstring | nullISO timestamp when the next rename is allowed, or null (now).
request · cURL
curl "https://www.dailydog.ai/api/v1/profile" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": {
    "username": "Bodega Regular",
    "funDefault": "Silly Foodie",
    "displayName": "Bodega Regular",
    "avatarId": "clr8x2k9a0000",
    "createdAt": "2026-07-01T00:00:00.000Z",
    "renamedAt": "2026-07-01T00:00:00.000Z",
    "canRenameAt": "2026-07-15T00:00:00.000Z"
  }
}

Claim or rename your username

PATCH/api/v1/profile

Claim or change the caller's username. **Requires `X-Device-Id`.** 3–20 chars from [a-zA-Z0-9_ .-], case preserved but unique case-insensitively; reserved/impersonation handles refused. 409 when taken; 429 when the 14-day rename throttle is active.

Request body

application/json
{
  "username": "Bodega Regular"
}

Response — the `data` object

FieldTypeDescription
usernamestring | nullClaimed username, or null if never claimed.
funDefaultstringStable generated display name for an unclaimed device.
displayNamestringusername ?? funDefault — what surfaces render.
avatarIdstring | nullOpaque avatar id, or null (render a monogram).
createdAtstring | nullISO timestamp the profile row was created, or null.
renamedAtstring | nullISO timestamp of the last username change, or null.
canRenameAtstring | nullISO timestamp when the next rename is allowed, or null (now).
request · cURL
curl -X PATCH "https://www.dailydog.ai/api/v1/profile" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985" \
  -H "Content-Type: application/json" \
  -d '{"username":"Bodega Regular"}'
mock response (fixture city)
{
  "data": {
    "username": "Bodega Regular",
    "funDefault": "Silly Foodie",
    "displayName": "Bodega Regular",
    "avatarId": "clr8x2k9a0000",
    "createdAt": "2026-07-01T00:00:00.000Z",
    "renamedAt": "2026-07-01T00:00:00.000Z",
    "canRenameAt": "2026-07-15T00:00:00.000Z"
  }
}

Erase your profile and reviews

DELETE/api/v1/profile

Erases the device from the service. **Requires `X-Device-Id`.** The profile (the username is freed for anyone to claim), the avatar, and every report the device has filed — including hidden and disputed ones — disappear from every public surface, the community score, and the device's own history immediately. DailyDog retains an internal audit copy for fraud prevention, moderation integrity, and legal compliance; it is never served anywhere. Idempotent: repeating the call returns 204 with nothing left to erase.

request · cURL
curl -X DELETE "https://www.dailydog.ai/api/v1/profile" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985" \
  -H "Content-Type: application/json" \
  -d 'null'
mock response (fixture city)
{}

Set your avatar

POST/api/v1/profile/avatar

Upload an avatar. **Requires `X-Device-Id`.** JSON body with a base64 image (JPEG/PNG); re-encoded to a 512px JPEG (≤1MB) with EXIF stripped. Returns the refreshed profile.

Request body

application/json
{
  "image": "<base64-image>"
}

Response — the `data` object

FieldTypeDescription
usernamestring | nullClaimed username, or null if never claimed.
funDefaultstringStable generated display name for an unclaimed device.
displayNamestringusername ?? funDefault — what surfaces render.
avatarIdstring | nullOpaque avatar id, or null (render a monogram).
createdAtstring | nullISO timestamp the profile row was created, or null.
renamedAtstring | nullISO timestamp of the last username change, or null.
canRenameAtstring | nullISO timestamp when the next rename is allowed, or null (now).
request · cURL
curl -X POST "https://www.dailydog.ai/api/v1/profile/avatar" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985" \
  -H "Content-Type: application/json" \
  -d '{"image":"<base64-image>"}'
mock response (fixture city)
{
  "data": {
    "username": "Bodega Regular",
    "funDefault": "Silly Foodie",
    "displayName": "Bodega Regular",
    "avatarId": "clr8x2k9a0000",
    "createdAt": "2026-07-01T00:00:00.000Z",
    "renamedAt": "2026-07-01T00:00:00.000Z",
    "canRenameAt": "2026-07-15T00:00:00.000Z"
  }
}

Check username availability

GET/api/v1/profile/username-check

Live availability for a candidate username. `X-Device-Id` optional — when sent, the caller's own current handle reads as available.

Parameters

NameTypeDescription
username *stringCandidate username.

Response — the `data` object

FieldTypeDescription
availablebooleanWhether the candidate username can be claimed.
reasonstringWhy not, when unavailable.
request · cURL
curl "https://www.dailydog.ai/api/v1/profile/username-check?username=…" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": {
    "available": true
  }
}

Your report history

GET/api/v1/profile/reports

The caller's OWN reports, newest first — INCLUDING hidden ones, each marked with its `status`. This is the only surface that shows a device its hidden reports. **Requires `X-Device-Id`.**

Paginated — follow meta.nextCursor until null.

Parameters

NameTypeDescription
limitintegerPage size, 1–100 (default 20).
cursorstringOpaque page cursor from the previous response's `meta.nextCursor`.

Response — the `data` object

FieldTypeDescription
idstringReport id.
kindpest | food_poisoning | sanitation_other | praise_taste | praise_cleanReport kind.
pestSubtypestring | nullFor pest reports: rats | mice | roaches | flies | other; null otherwise.
bodystringThe reporter's description (20–500 chars, shown verbatim).
createdAtstringReport date (day precision on public surfaces).
photoIdsarray<string>
authorCommunityAuthor
camisstringThe establishment this report is about.
statusactive | disputed | hidden | upheldactive | disputed | upheld | hidden — honest, including hidden.
request · cURL
curl "https://www.dailydog.ai/api/v1/profile/reports" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": [
    {
      "id": "clr9y3m1b0009",
      "camis": "41234567",
      "kind": "sanitation_other",
      "pestSubtype": null,
      "body": "This report was hidden after review.",
      "status": "hidden",
      "createdAt": "2026-07-20",
      "photoIds": [],
      "author": {
        "displayName": "Bodega Regular",
        "avatarId": "clr8x2k9a0000"
      }
    }
  ],
  "meta": {
    "nextCursor": null,
    "returned": 1
  }
}

Serve an avatar

GET/api/v1/profiles/avatars/{id}

Public avatar bytes by opaque profile id (never the device hash), served with `nosniff`.

Parameters

NameTypeDescription
id * (path)stringAvatar id from an author's `avatarId`.
request · cURL
curl "https://www.dailydog.ai/api/v1/profiles/avatars/fixture-avatar-1" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{}

Platform

Key introspection, health, and this document.

Key introspection & usage

GET/api/v1/me

Response — the `data` object

FieldTypeDescription
namestringKey name.
tierstringstandard | unlimited.
modelive | testlive | test — test keys answer from the fixture city.
createdAtstringISO timestamp.
usageobject
todayintegerRequests since midnight UTC.
last30DaysintegerRequests over 30 days.
dailyLimitinteger | nullYour commissioned daily limit; null = unlimited.
request · cURL
curl "https://www.dailydog.ai/api/v1/me" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "data": {
    "name": "My food app",
    "tier": "standard",
    "mode": "live",
    "createdAt": "2026-07-21T14:02:11.000Z",
    "usage": {
      "today": 412,
      "last30Days": 8907,
      "dailyLimit": 50000
    }
  }
}

Liveness

GET/api/v1/health

request · cURL
curl "https://www.dailydog.ai/api/v1/health" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{
  "status": "ok",
  "version": "1.1"
}

This document

GET/api/v1/openapi.json

request · cURL
curl "https://www.dailydog.ai/api/v1/openapi.json" \
  -H "Authorization: Bearer dd_test_d23d83e5ee04c87b1fee30680033c31aa0ef7985"
mock response (fixture city)
{}