Skip to content

HackJerseyCity/scfs-api-

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SCFS API

Ad-hoc scoring API for SeeClickFix issues. Give it an issue ID, get back interaction and outcome sentiment scores powered by GPT-4o-mini.

Built to back a browser extension that displays scores directly on SeeClickFix issue pages.

How it works

  1. You send a SeeClickFix issue ID (e.g. 18326635 from seeclickfix.com/.../issues/18326635)
  2. The API fetches the issue details and full comment thread from the SeeClickFix v2 API
  3. It identifies city employees, flags auto-generated comments, and sends the thread to GPT-4o-mini
  4. The LLM scores two dimensions:
    • Interaction — how did city staff communicate with residents?
    • Outcome — was the reported problem actually resolved?
  5. Results are cached in SQLite. Subsequent requests return instantly.

API

Score an issue

GET /api/issues/{issue_id}

Fetches, scores, and returns results. First call hits the SeeClickFix API + LLM (a few seconds). Cached calls return in ~30ms.

Parameter Type Default Description
issue_id path required SeeClickFix issue ID
force query false Re-fetch and re-score even if cached

Example

curl https://scfs-api.hackjc.org/api/issues/18326635

Response

{
  "issue_id": 18326635,
  "status": "Open",
  "summary": "Construction on Street/Sidewalk",
  "description": "There is construction at this address that has been ...",
  "address": "123 Example St, Jersey City, NJ",
  "request_type": "Building and Streets",
  "department": "Code Compliance",
  "html_url": "https://seeclickfix.com/issues/18326635",
  "created_at": "2025-02-14T12:00:00-05:00",
  "closed_at": null,
  "interaction": {
    "label": "negative",
    "confidence": 0.9,
    "reasoning": "Residents expressed frustration with the city's responses, indicating a lack of effective communication and resolution."
  },
  "outcome": {
    "label": "negative",
    "confidence": 0.9,
    "reasoning": "The issue remains unresolved despite multiple complaints and follow-ups from residents."
  },
  "employees": [
    {
      "commenter_id": 12345,
      "name_raw": "Code Compliance Inspector - Brian",
      "name_parsed": "Brian",
      "title_parsed": "Code Compliance Inspector",
      "department": "Code Compliance"
    }
  ],
  "comments": [
    {
      "id": 67890,
      "comment": "Thank you for reporting an issue to the City of Jersey City...",
      "created_at": "2025-02-14T14:00:00-05:00",
      "commenter_name": "Code Compliance Inspector - Brian",
      "commenter_role": "Verified Official",
      "is_auto_generated": false
    }
  ],
  "cached": false
}

The cached field tells you whether this was a fresh score (false) or served from cache (true).

Force re-score

curl https://scfs-api.hackjc.org/api/issues/18326635?force=true

Errors

Status Meaning
404 Issue not found on SeeClickFix
500 LLM or internal error

Health check

GET /up

Returns "ok" with status 200.

OpenAPI docs

GET /docs

Interactive Swagger UI with request/response schemas.

Sentiment labels

Both interaction and outcome use the same label set:

Label Interaction meaning Outcome meaning
positive Staff were responsive, helpful, professional Problem was fixed, action was taken
negative Staff were dismissive, confrontational, unresponsive Issue ignored, closed without resolution
neutral No resident interaction to evaluate Unclear resolution, in progress, jurisdictional
mixed Some good, some bad exchanges Partial resolution or conflicting signals

Each label comes with a confidence score (0.0–1.0) and a one-sentence reasoning.

Setup

Requirements

  • Python 3.11+
  • OpenAI API key

Local development

python3 -m venv .venv
source .venv/bin/activate
pip install -e .

export OPENAI_API_KEY=sk-...
python -m src.entrypoint

Server starts on http://localhost:8000.

Environment variables

Variable Default Description
OPENAI_API_KEY required OpenAI API key
OPENAI_MODEL gpt-4o-mini Model for scoring
LLM_BACKEND openai openai or ollama
OLLAMA_URL http://localhost:11434 Ollama server URL
OLLAMA_MODEL llama3.1:8b Ollama model name
DATA_DIR ./data SQLite database directory
WEB_HOST 0.0.0.0 Bind address
WEB_PORT 8000 Bind port
CORS_ORIGINS * Allowed CORS origins (comma-separated)

Deploy

Uses Kamal to deploy to scfs-api.hackjc.org:

kamal setup    # first time
kamal deploy   # subsequent deploys

Requires KAMAL_REGISTRY_PASSWORD and OPENAI_API_KEY env vars.

About

Inference API For SeeClickFix sentiment analysis

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors