1
Your town
2
Contact
3
Setup needs
4
Review
Step 1 of 4
Tell us about your town
Basic information helps us make sure Pinpoint 311 is the right fit and that we can follow up with anything useful.
Please enter your municipality name
Please select a state
<1K5K10K25K 50K100K250K500K+
~10,000 residents
Helps us understand your existing setup.
Step 2 of 4
Who should we be in touch with?
We'll reach out with setup guidance and answer any questions. We don't share or sell your information.
Required
Required
Please enter a valid email address
Required
Step 3 of 4
A bit more about your setup
This helps us send you relevant deployment guidance and check if there's anything we can do to help.
Step 4 of 4
Review & submit
Double-check everything looks right, then submit. We'll be in touch within a couple of days.
After submitting, we'll send you the deployment link right away so you can get started. We'll follow up via email with setup guidance tailored to your situation.

Complete Setup Guide

Everything you need to go from zero to a fully running Pinpoint 311 deployment, step by step.

15–30 min basic · 45–60 min full production
Setup Guide
Get Running
Server, code, config, start & login · ~15 min
▾
Make It Yours
Boundaries, services, branding & legal
▾
Go Live
Domain, checklist & maintenance
▾
Get Running
Server, code, config, start & login
Steps 1–5
▾
1
Set Up Your Server
Get a server, SSH in, and install Docker
▾

1a. Get a Server

You need a Linux server (Ubuntu recommended). Use any cloud provider — Oracle Cloud (free tier), AWS, Google Cloud, DigitalOcean, or an on-premise machine.

Minimum Specs Details
CPU 1 vCPU (2+ recommended for production)
RAM 1 GB minimum (2+ GB recommended)
Disk 20 GB+
OS Ubuntu 22.04 or 24.04 LTS recommended

1b. SSH Into Your Server

From your local machine, connect to the server using SSH:

# Replace with your server's IP address and key file ssh -i your-key.pem ubuntu@your-server-ip # Or if using password auth: ssh ubuntu@your-server-ip

💡 All remaining steps are run on the server, not your local machine.

1c. Install Docker & Docker Compose

First, check if Docker is already installed:

docker --version && docker compose version

If Docker is not installed, run these commands:

# Install Docker using the official convenience script curl -fsSL https://get.docker.com | sudo sh # Allow your user to run Docker without sudo sudo usermod -aG docker $USER # Log out and back in for group changes to take effect exit

SSH back in, then verify Docker is working:

docker --version docker compose version

💡 If Docker is already installed, skip this step entirely.

1d. Open Firewall Ports

Your cloud provider's firewall (security groups / network rules) must allow inbound traffic on these ports:

Port Protocol Purpose
22 TCP SSH access (already open if you can connect)
80 TCP HTTP — web traffic & Let's Encrypt certificate validation
443 TCP HTTPS — secure web traffic (auto-enabled with a domain)

Where to configure this depends on your cloud provider:

Provider Where to Open Ports
Oracle Cloud Networking → Virtual Cloud Networks → Security Lists → Add Ingress Rules
AWS EC2 → Security Groups → Edit Inbound Rules
Google Cloud VPC Network → Firewall → Create Firewall Rule
DigitalOcean Networking → Firewalls → Create Firewall

If your server also has a local firewall (e.g. ufw on Ubuntu), open the ports there too:

sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable
⚠️
If port 80 or 443 is blocked, your site won't load and SSL certificates won't auto-provision. This is the most common setup issue — make sure both ports are open before running docker compose up.

Recommended (Optional Providers)

Service Why & Provider Options
Cloud Services (GCP / AWS / Azure) Vertex AI / Bedrock / Azure OpenAI, Maps, Translation, KMS PII encryption & Secret Manager
SSO / Auth Provider Staff SSO, MFA, passkeys — Auth0 (free tier), Microsoft Entra ID (Azure AD), Okta, or generic OIDC
GIS & Mapping Google Maps, Esri ArcGIS Online/Enterprise, Azure Maps, or Apple MapKit JS
Custom Domain e.g. 311.yourtown.gov
SMTP Server Confirmation & status emails (any SMTP provider)
2
Download the Latest Release
Get the stable release package from GitHub
▾

On your server, download and extract the latest release:

# Auto-download the latest release VERSION=$(curl -s https://api.github.com/repos/Pinpoint-311/Pinpoint-311/releases/latest | grep '"tag_name"' | cut -d'"' -f4) curl -L "https://github.com/Pinpoint-311/Pinpoint-311/archive/refs/tags/${VERSION}.tar.gz" -o pinpoint.tar.gz tar -xzf pinpoint.tar.gz cd Pinpoint-311-${VERSION#v}

💡 Or download directly from the Releases page — click the latest version and download "Source code (tar.gz)".

3
Configure Environment Variables
Set your database password and secret key
▾
# 1. Generate a secure 32-byte secret key first openssl rand -hex 32 # 2. Copy the config file and edit it cp .env.example .env nano .env
🔒
Your .env file never leaves your server. This ensures your API keys and Resident Data stay securely within your own infrastructure.
⚠️
Crucial DNS Step: If you are using a custom domain (e.g., 311.yourcity.gov), you MUST point your DNS A-Record to this server's IP address before moving to Step 4. If you set DOMAIN below but the DNS is not pointed, the server will fail to start and throw SSL Protocol errors.

Required variables

Variable What to set
DOMAIN Your domain (e.g., 311.yourcity.gov), or localhost for local testing
DB_PASSWORD A strong, unique database password
SECRET_KEY Paste the secure key you generated above
ADMIN_EMAIL Your admin contact email
INITIAL_ADMIN_PASSWORD A strong temporary password for seeding the initial local admin account during bootstrap
💡
Most API keys can be configured later via the Admin Console. You only need DB_PASSWORD, SECRET_KEY, and DOMAIN to start.
4
Start the System
Build and launch all services
▾

Build & Start (recommended)

docker compose up --build -d

Verify

docker compose ps

You should see backend, frontend, db, redis, caddy, and worker — all Up or healthy.

Access points

Portal URL
Resident Portal http://localhost/
Staff Dashboard http://localhost/staff
Admin Console http://localhost/admin
Research Lab http://localhost/research
API Docs http://localhost/api/docs
5
Log In to Admin Console
One-click admin access for initial setup
▾

After the containers start, you need to log into the Admin Console to configure your system.

Option A: Browser (Recommended)

  1. Open http://your-server-ip/login in your browser
  2. You'll see a "Welcome to Pinpoint 311" card with an "Enter Admin Console" button
  3. Click the button — you'll be automatically logged in as admin

💡 If your browser shows an SSL error, use port 8000 instead: http://your-server-ip:8000/login

Option B: Terminal

Alternatively, run this on the server (pass -F "password=..." if INITIAL_ADMIN_PASSWORD is set):

curl -X POST http://localhost:8000/api/auth/bootstrap -F "password=YOUR_INITIAL_ADMIN_PASSWORD"

Copy the login_url from the JSON response and open it in your browser.

⚠️
Bootstrap access is one-time only — once you configure Auth0 (Step 6), the button disappears and all logins go through SSO.
💡
If the login page doesn't load, containers may still be starting: docker compose ps — all services should show "healthy".
Connect Services
Auth0, AI, Maps, staff, email & SMS
Steps 6–11
▾
6
Configure SSO (Auth0 Preset)
Zero-password staff authentication with MFA (Auth0, Azure AD, or Okta)
▾
ℹ️
Provider Flexibility: Pinpoint 311 supports multiple SSO providers (Auth0, Microsoft Entra ID / Azure AD, Okta, or any generic OIDC provider). This guide walks through Auth0 as a popular turnkey option with a generous free tier.

1. Create an Auth0 account

Go to auth0.com and create a free account (or use your organization's existing tenant). The free tier supports up to 7,000 active users.

2. Create an application

  • In the Auth0 Dashboard, go to Applications → Create Application
  • Choose Regular Web Application
  • In the app's Settings tab, copy the Domain, Client ID, and Client Secret
⚠️
Important: Under the app's Organizations tab, ensure "Require users to belong to an organization" is DISABLED. If this is checked, all staff logins will fail with an unauthorized error.

3. Configure callback URLs

Setting Value
Allowed Callback URLs https://311.yourtown.gov/api/auth/callback
Allowed Logout URLs https://311.yourtown.gov/staff
Allowed Web Origins https://311.yourtown.gov
⚠️
Common Issue: The callback URL must exactly match your domain with /api/auth/callback appended. A single typo here will cause staff logins to fail silently.

4. Enable MFA (recommended)

In the Auth0 Dashboard, go to Security → Multi-factor Auth and enable MFA. Staff will be prompted to set up a second factor on their first login.

5. Social login (optional)

Under Authentication → Social, add Google and Microsoft connections so staff can log in with their existing work accounts.

6. Enter credentials in Admin Console

Go to Setup & Integration → Auth0, enter your Auth0 Domain, Client ID, and Client Secret, and save.

🔒
Once Auth0 is configured, bootstrap access is automatically disabled. All staff logins use Auth0 SSO with passkey support.
7
Cloud Services: AI, KMS & Secrets (GCP Preset)
Vertex AI, Translation, KMS encryption & Secret Manager
▾
ℹ️
Provider Flexibility: While this guide details Google Cloud (Vertex AI, Cloud KMS, and Secret Manager), Pinpoint 311 also supports AWS (Bedrock, AWS KMS, Secrets Manager) and Azure (Azure OpenAI, Azure Key Vault), or local keys and self-hosted models.

1. Create or select a GCP project

Go to console.cloud.google.com and create a new project or select an existing one. Note your Project ID (not the project name).

💡
Billing must be enabled on your GCP project even if you stay within the free tier. Most API usage for a single municipality will fall within Google's generous free quotas.

2. Enable APIs

Go to APIs & Services → Library and enable all four:

API What it powers
Cloud KMS API PII encryption at rest (HSM-backed, FIPS 140-2)
Cloud Translation API Multi-language support (109 languages)
Vertex AI API AI request analysis, priority scoring, photo assessment, duplicate detection
Secret Manager API Enterprise secrets vault for production credentials

3. Create KMS Key Ring & Key

Navigate to Security → Key Management:

  • Create Key Ring — name it (e.g., pinpoint311) and select a location (e.g., us-central1)
  • Create Key inside the ring (e.g., pii-encryption), purpose: Symmetric encrypt/decrypt
  • Optional: Set automatic rotation (e.g., every 90 days). After rotation, use the Re-encrypt All PII Data button in Admin Console to migrate historical data

4. Create a Service Account

Go to IAM & Admin → Service Accounts → Create. Grant it these roles:

Role Purpose
Cloud KMS CryptoKey Encrypter/Decrypter Encrypt/decrypt PII data
Cloud Translation API User Translate submissions
Vertex AI User AI-powered analysis
Secret Manager Admin Manage secrets vault

5. Download the JSON key

On the Service Account page, go to Keys → Add Key → Create new key → JSON. Download and keep this file secure — it's your master credential.

6. Enter in Admin Console

Go to Setup & Integration → Google Cloud:

  • Enter your Project ID, KMS Location, Key Ring, and Key ID
  • Upload or paste your Service Account JSON key
  • Click Save GCP Settings

7. Migrate Secrets (optional)

Click Migrate to Secret Manager to vault all API credentials (Maps key, SMTP password, Twilio token, etc.) into GCP.

⚠️
Two bootstrap keys (GCP_SERVICE_ACCOUNT_JSON and GOOGLE_CLOUD_PROJECT) always stay in the local DB — they're the master keys needed to access Secret Manager itself.
8
Configure Maps (Google Maps Preset)
Location picker, boundary maps, address autocomplete (Google, Esri, Azure)
▾
ℹ️
Provider Flexibility: Pinpoint 311 features a pluggable GIS architecture supporting Google Maps, Esri ArcGIS Online & Enterprise, Azure Maps, or Apple MapKit JS. This guide covers the Google Maps setup.

1. Create an API key

2. Restrict the key

Restriction Value
API restrictions Maps JavaScript, Places, Geocoding
Website restrictions https://311.yourtown.gov/*

3. Enter in Admin Console

Go to Setup & Integration → Google Maps and paste your API key. If you activated Secret Manager in Step 7, this key is automatically vaulted into GCP.

4. Enable 3D buildings (optional)

For 45° tilt, rotation, and 3D buildings on the map:

  • Go to Google Cloud Console → Maps → Map Management
  • Create a Map ID with map type: Vector
  • Enter the Map ID in Admin Console → Google Maps → Map ID
💡
No extra cost — same Dynamic Maps pricing ($7 per 1,000 loads, $200/month free credit from Google). Most municipalities never exceed the free tier.
9
Add Staff Users
Invite team members and assign roles
▾

In the Admin Console, go to Staff Management and add your team:

Role Access Level Best For
Admin Full Admin Console + all operations IT staff, department heads
Staff View, manage, and resolve requests Field workers, dispatchers
Researcher Privacy-preserved analytics only Analysts, council members

Staff log in via Auth0 SSO — no passwords stored in the system.

🔐
Staff PII (names, emails, phone numbers) is now encrypted with Google KMS since Step 7 was configured. All personal data is protected at rest.
10
Email Notifications
SMTP for submission confirmations & status updates
▾

Choose your SMTP provider

Provider Host Port Username
Gmail smtp.gmail.com 587 Your Gmail address
SendGrid smtp.sendgrid.net 587 apikey (literal)
Org relay Your server's SMTP host Varies Varies
⚠️
Gmail users: You must enable 2FA on your Google account first, then generate an App Password under Security → App Passwords. Use the app password as your SMTP password.

Enter the host, port, from address, username, and password in Admin Console → Setup & Integration → Email (SMTP) and click Save SMTP Settings.

✉️
All notification emails automatically include your municipality's branding (logo, colors, name) — set those up in Step 14.
11
SMS Notifications (Optional)
Twilio or custom HTTP API for text alerts
▾

Option A: Twilio (recommended)

  • Create an account at twilio.com
  • Note your Account SID and Auth Token from the Console Dashboard
  • Go to Phone Numbers → Manage → Buy a number — get a number with SMS capability
  • In Admin Console → SMS Notifications, select "Twilio" and enter your credentials

Option B: Custom HTTP API

If you have an existing SMS gateway, select "Custom HTTP API" and provide your endpoint URL. Pinpoint sends a POST request with:

{ "to": "+1234567890", "message": "Your request #123 has been updated..." }
💡
SMS is fully optional. Email notifications cover all the same status updates. SMS adds real-time text alerts for residents who opt in.
Make It Yours
Boundaries, services, branding & legal
Steps 12–14
▾
12
Municipality Boundaries
GeoJSON service area
▾

Requests outside the boundary are automatically rejected. Get your file from:

Upload in Setup & Integration → Municipality Boundaries.

13
Services & Departments
Categories, routing, custom questions
▾

In Admin Console → Services, create categories (Pothole, Streetlight, etc.):

Setting Description
Routing Township Handled, Third-Party, or Road-Based
Department Which team handles it
Questions Follow-up questions per service
💡
Road-Based routing splits jurisdiction per street — all configured without code.
14
Branding & Legal
Logo, colors, privacy policy, terms of service
▾

Branding

In Admin Console → Branding:

  • Municipality Name — headers, emails, portal
  • Logo — nav, emails, portal
  • Primary & Secondary Colors
  • Font

Auto-applied to Resident Portal, all emails, SMS, and Staff Dashboard.

Legal Documents

In Branding → Legal Documents:

  • Privacy Policy — data collection, retention, rights
  • Terms of Service — includes non-emergency disclaimer
  • Accessibility — WCAG 2.1 AA, Section 508

All support Markdown formatting. Sensible defaults included.

Go Live
Domain, checklist & maintenance
Steps 15–16
▾
15
Custom Domain
Auto HTTPS via Let's Encrypt
▾

1. Point DNS

Type Name Value
A 311.yourtown.gov Your server IP

2. Update .env

DOMAIN=311.yourtown.gov

3. Restart Caddy

docker compose restart caddy

Caddy auto-provisions SSL and redirects HTTP → HTTPS.

16
Go-Live Checklist & Maintenance
Launch verification, backups, updates
▾

Pre-Launch Checklist

✓ Item
☐ Secure DB_PASSWORD and SECRET_KEY (not defaults)
☐ Auth0 configured, bootstrap disabled
☐ Google Maps key working
☐ Municipality boundary uploaded
☐ At least one service category
☐ At least one department with staff
☐ SMTP email configured and tested
☐ Branding set (logo, name, colors)
☐ Legal documents reviewed
☐ Custom domain with HTTPS
☐ Full lifecycle test: submit → staff → resolve → email

Automatic Updates (Optional)

# Enable docker compose up -d watchtower # Disable docker compose stop watchtower # Status docker compose ps watchtower
💡
Works perfectly without Watchtower. Use for hands-off updates, or disable for manual control.

Database Backups

Automated (recommended): Configure S3-compatible storage in Admin Console → Setup & Integration → Database Backups:

Field Description
S3 Bucket Your bucket name (AWS S3, Oracle Object Storage, MinIO, etc.)
Access Key IAM access key with s3:PutObject, s3:GetObject permissions
Secret Key Corresponding secret key
Encryption Key Passphrase for AES-256 backup encryption — store this securely
Endpoint Optional: Custom endpoint for Oracle/MinIO (leave blank for AWS)
⚠️
Privacy note: Backups contain a full database snapshot including resident PII. Without the encryption key, backups are unreadable. Keep this key in a separate, secure location.

Manual: Take a one-off backup any time:

docker compose exec db pg_dump -U township township_db > backup_$(date +%Y%m%d).sql

Manual Updates

# Download the new release VERSION=v1.1.6 # Replace with latest version curl -L "https://github.com/Pinpoint-311/Pinpoint-311/archive/refs/tags/${VERSION}.tar.gz" | tar -xz # Copy your .env into the new version cp .env Pinpoint-311-${VERSION#v}/ cd Pinpoint-311-${VERSION#v} # Rebuild and restart docker compose up --build -d

Database Migrations

Migrations run automatically on startup. To run manually:

docker compose exec backend alembic upgrade head

View Logs

docker compose logs -f backend

Record Retention

State Period
Texas 10 years
NJ, PA, WI 7 years
NY, MI, WA, CT 6 years
CA, FL, most 5 years (default)
GA, MA 3 years

Need help? We're here for you.

GitHub Repository → Report an Issue Donate (tax-deductible)

© 2024–2026 Pinpoint 311 · MIT License · Fiscally sponsored by Hack Club 501(c)(3)

✦ Setup Assistant

👋 Hi! I'm the Pinpoint 311 setup assistant. I can help you with deployment, configuration, Docker, Auth0, Google Cloud, and anything else in the setup guide. What can I help with?