Open311 is an open specification that lets civic issue-reporting apps and municipal 311 systems talk to each other through a common read/write API. In practice it works like this: an app looks up a city, reads that city’s list of reportable services, submits a request with a service code and a map location, then polls a service request ID until the city marks it closed. Everything in that loop — the endpoints, the field names, the timestamp format — is fixed by the standard, while the service catalog and the department workflow behind it stay local to each city. Updated for 2026.
That split is the thing most explanations get wrong. The Open311 standard does not define what a city fixes or who picks up the phone. It defines the contract between an app and whatever system the city already uses.
Table of Contents
- What Are Open311 Standards?
- Open standard versus open source
- What the standard is and is not standardized
- How Open311 Standards Work
- How Open311 standards work in one end-to-end example
- The Core Open311 Data Model
- How a Service Request Moves Through the System
- 1. Discovery
- 2. Definition
- 3. Submission
- 4. Assignment
- 5. Field work and status updates
- 6. Closure and reopening
- Realtime, batch and blackbox submission
- Which Parts of Open311 Are Standardized?
- How Open311 APIs Enable City Apps
- Developer libraries worth knowing
- What Makes an Open311 Implementation Interoperable?
- How Cities Use Open311 Beyond 311 Requests
- Common Misunderstandings About Open311
- Frequently Asked Questions
- Is Open311 a software platform?
- Do all Open311 cities use the same service-request categories?
- Can a private company build an app using Open311 data?
- What is the difference between Open311 and a regular 311 API?
- How do developers handle updates when an Open311 implementation changes?
- Does Open311 guarantee that city departments respond within a specific time?
- Conclusion
What Are Open311 Standards?
Open311 is a specification, a set of rules for exchanging civic service-request data, plus a governance idea: the rules are published, not proprietary, so anyone can build against them.
It is not a platform, a piece of software you install, or a call centre. A city can run Open311 on top of a commercial 311 vendor’s work-order system, on its own in-house code, or on a hosted civic reporting service such as FixMyStreet or SeeClickFix. The standard sits above all of those and describes how an outside application reads and writes requests.
Cities adopt it because the alternative is expensive. Without a shared contract, every reporting app has to be rewritten for every municipality, and every city gets locked into one vendor’s interface. A pothole-reporting app that works in San Francisco is useless in your next target city until somebody rewrites it. Open311 is what stops that rewrite from being total.
Open standard versus open source
These two get confused constantly, so here is the short version. An open standard is a public agreement about how systems exchange data — the standard can be implemented by closed software. Open source software is code anyone can read and modify — the code is free, but nothing forces two projects to speak the same protocol. Open311 is an open standard first; the reference implementations around it may or may not be open source.
What the standard is and is not standardized
| Standardized by Open311 | Left to the city |
|---|---|
| API methods, endpoints and required arguments | The list of services it offers |
| Field names such as service_code and jurisdiction_id | Attribute names and picklist values |
| XML with JSON as an option | Which department handles a service |
| Timestamps in W3C date-time, coordinates in WGS84 | Status vocabulary and closing codes |
| UTF-8 encoding | Response-time targets, staffing, budgets |
How Open311 Standards Work
Three parties sit in the loop: the person reporting the problem, the city department responsible for it, and the software connecting the two. Open311 governs the software conversation and the data that travels through it, not the human ones.
A typical system has four moving parts. The reporting app collects a location, a description and an optional photo. The city’s public API accepts the request and assigns a service request ID. The city’s internal work-order or CRM system assigns, completes and closes the request. The app reads the current status back through the same API. The middle two are the city’s business; the outer two are where the standard earns its keep.
Every Open311 deployment also has a small machine-readable manifest called a service discovery file, usually named discovery.yaml. It sits at a well-known path on the server and points to the API endpoint, the areas the city serves, the contact details, and the terms of use. Apps read it first to find out where everything else lives, which is what makes the whole scheme self-describing instead of dependent on a wiki page listing URLs.
How Open311 standards work in one end-to-end example
A resident photographs a pothole on a residential street. The app geolocates the photo, looks up the discovery file for the city’s API, calls the service list, finds the road defect service code, reads that service’s definition to see which extra fields it wants, and posts the report. The API replies with a service request ID. The app then polls that ID every few minutes and shows a status label, until the city closes the request with a note explaining what was done.
Nothing in that sequence requires the app to know which internal system handles the repair, which crew was dispatched, or how long the work will take. That opacity is the design.
The Core Open311 Data Model
Six objects carry nearly everything, and they nest: a service has attributes, attributes have values, requests reference services, and everything is scoped to a jurisdiction.
| Field | What it means | Required |
|---|---|---|
| jurisdiction_id | The city’s or agency’s identifier, e.g. sfgov.org | Required on most calls |
| service_code | Machine name for a reportable service, e.g. street-pothole | Required |
| attribute[code] | Extra per-service field passed as a bracketed parameter | Varies by service |
| service_request_id | The identifier the city returns for a submitted request | Returned, not sent |
| agency_responsible | Department or authority handling the request | Optional in responses |
| expected_datetime | The city’s target date for completion, if it commits to one | Optional |
Attributes are where cities differ most, and each one declares a datatype so a generic app can render it correctly: string, number, datetime, single-value list or multi-value list. A sidewalk defect service might ask for which side of the street the problem is on, using a single-value list with entries such as north, south, east or west. Another city might ask for a numeric block number instead. Same app, same form renderer, different data.
A service request itself carries a status, an optional status note, an optional media URL for an attached photo, and the agency responsible. Status values are free text by design, which is flexible and also the most common source of integration pain — more on that below.
How a Service Request Moves Through the System

The lifecycle is the part that matters operationally, because it is where an app decides what to tell the person waiting for a fix.
1. Discovery
The app fetches the service discovery file to learn the API base URL, the areas covered and the terms of use. Without it, a developer is guessing at URLs.
2. Definition
Two read calls come next. The service list returns every service with its code, name, description and type. The service definition for one code returns that service’s metadata plus its full attribute schema, so the app knows which form fields to ask for before submitting anything.
3. Submission
The app posts a jurisdiction ID, a service code, a location and a description, plus any attributes the service definition demanded and an optional media URL for a photo. XML is the required format; JSON is available on most modern implementations and is what you will want for a new app.
4. Assignment
The city routes the request to a department, either automatically by service code or by a staff member triaging it. Some cities publish the assigned agency back through the API, others keep that internal.
5. Field work and status updates
Crews or caseworkers act, and the city’s system updates the request status. This is the phase people think Open311 governs most tightly and it governs least — internal workflow is entirely the city’s own.
6. Closure and reopening
The city closes the request, usually with a note. If the problem comes back, a well-behaved system reopens the original record rather than orphaning it, so the history stays intact.
Realtime, batch and blackbox submission
Not every city can hand back an ID on the spot, so the standard defines three submission types, declared in the service definition’s metadata.
| Type | What you get back | Typical fit |
|---|---|---|
| Realtime | A service request ID immediately | City systems that assign work on the spot |
| Batch | A token you exchange later for the ID | Queues processed overnight |
| Blackbox | No ID at all | Mailbox-style intake with no tracking |
Batch mode adds one extra round trip: the app stores the token, then later calls the token endpoint to swap it for the real service request ID. Blackbox apps can submit but cannot track, which is a real limitation worth knowing before you promise someone a status screen.
Which Parts of Open311 Are Standardized?
Short answer: the wire format is standardized, the substance is local. A developer can trust that a field called service_code will be present and will mean the same thing everywhere. They cannot trust that a code for potholes will exist, that it will be spelled the same way as in the neighbouring city, or that closing it will take nine days.
Locally configurable pieces include the service catalog itself, the attribute names and their picklist values, department naming, status vocabulary, media handling, whether public requests are searchable, and any authentication rules beyond the standard’s API key parameter. Cities also vary on whether they enforce a jurisdiction ID, whether they cap description length, and how much history they expose.
The specification itself has been frozen for years. Clarifications happen in documentation, but field-level changes are effectively impossible to coordinate across implementations, so in practice cities extend through local convention. Treat any extension you meet as that city’s own dialect, not as part of the standard.
How Open311 APIs Enable City Apps

The API surface is small enough to describe in one list, which is unusual for a municipal interface. GeoReport v2 defines six methods, and they run in this order in a real integration.
- Service list — a GET on the services resource returns every service the city accepts, with codes, names, descriptions and submission types.
- Service definition — a GET on a single service code returns that service’s metadata and its attribute schema, including datatypes and whether each attribute is required.
- Service request creation — a POST to the requests resource submits a report and returns an ID or a token depending on the service type.
- Service request from token — a GET converts a batch token into the corresponding service request ID once the city has processed it.
- Service requests — a GET on the requests resource returns a filtered list, which is how dashboards and open-data pipelines pull records in bulk.
- Single service request — a GET on one service request ID returns its current status, notes and any attached media.
Bulk pulls come with practical limits baked into the spec. The requests list defaults to a 90-day window rather than all history, and a single response caps out around 1000 records, so anything larger means paginating on the date parameter. Descriptions are commonly limited to about 4000 characters. Photos travel as a media URL the city’s system fetches, not as a file upload in the POST body.
Requests are form-encoded. Authentication, when required, is an API key passed alongside the other parameters; the key and the endpoint behaviour are both set by the city, which is why developer onboarding still means reading each city’s own documentation.
| Status | What it means for your code |
|---|---|
| 400 | Malformed request, usually a missing required argument or an attribute value outside its declared list |
| 403 | API key missing, wrong, or not authorized for that jurisdiction |
| 404 | No such service code, request ID or token in that jurisdiction |
Developer libraries worth knowing
You do not have to hand-roll the client. The r311 package wraps the standard for R analysts, Mark-a-Spot implements the GeoReport v2 submission pattern for teams building mobile intake, and codeforsanjose has published a 311 Gateway project whose whole purpose is to give mobile developers one uniform REST interface across jurisdictions that otherwise expose different endpoints. FixMyStreet in the UK has run an Open311 service since 2011, wired into its fault reporting and CRM system, and ships a toolkit for councils.
What Makes an Open311 Implementation Interoperable?
Interoperability comes down to a handful of boring, specific things.
- Consistent identifiers — jurisdiction IDs, service codes and service request IDs behave the same way in every implementation, so they can be stored and compared across cities.
- Documented schemas — attributes declare datatype and requiredness, so a form can be built generically instead of hand-coded per service.
- Machine-readable formats — XML everywhere, JSON widely, UTF-8 throughout, and timestamps in W3C date-time so sorting and comparison behave predictably.
- Stable reference coordinates — WGS84 latitude and longitude, which is what lets a report from one app land correctly on a city’s map system.
- A discovery file — the endpoint is discoverable rather than hardcoded, so an app can add a city by fetching one file.
- Predictable errors — 400, 403 and 404 mean roughly the same thing everywhere, which is the minimum bar for retry logic.
What it does not standardise is status vocabulary, and that is the gap where integrations quietly break. A dashboard that counts closed requests across three cities needs a local mapping table, because one city might write Closed, another Resolved, another Completed. Assume you will maintain that mapping yourself.
How Cities Use Open311 Beyond 311 Requests
The same endpoints get used for things the original 1970s call centre never imagined.
- Open-data publishing — the requests list doubles as a dataset of what residents care about, and analysts pull it with the same pagination logic any pipeline would use.
- Dashboards and accountability — public request volumes and closure rates become visible, which changes the conversation inside a council as much as outside it.
- Third-party app intake — a parking app or a utility company submits its own requests into the city’s system rather than emailing a department.
- Fleet and sensor reporting — connected municipal vehicles and street sensors can file requests as soon as they detect a defect, so reporting stops depending on a resident noticing.
- Cross-agency coordination — a request touching both public works and sanitation carries one ID across both departments instead of two separate tickets.
- Volunteer coordination — community reporting platforms use the standard to fold their volunteers’ reports into the same tracking the city already runs.
None of this requires every city to expose identical capabilities. A small city with two part-time staff may run a blackbox-only endpoint, and that is a perfectly valid Open311 implementation.
Common Misunderstandings About Open311
It is not a CRM replacement. The city’s work-order system still runs the job, the crew, the cost and the closeout. Open311 is the doorway into that system, not the system.
It does not fix service quality. A city can publish a beautiful API and still take three weeks to fix a streetlight. The standard moves information; it does not move crews.
Categories are not universal. You will not find a pothole service code in a rural county with a two-service catalog, and you should not assume neighbouring cities share vocabulary even when they share the specification.
It does not require every agency to run the same technology. That is the entire point — the interface is common, the back office is not.
Adoption is uneven. Plenty of cities run 311 services with no public Open311 endpoint at all. Any app promising nationwide coverage will hit that wall, and it is a wall of coverage rather than of technology.
It is not an emergency channel. Everything in this article covers non-emergency municipal issues. Fire, crime and medical emergencies belong on the emergency number, not on an API.
Frequently Asked Questions
Is Open311 a software platform?
No. Open311 is a published specification for how civic apps exchange service-request data with a city’s systems, plus a set of conventions most implementations follow. The software behind it can be a commercial vendor platform, city-built code or a hosted service such as FixMyStreet. You install nothing to adopt it; you build against it.
Do all Open311 cities use the same service-request categories?
No. Each city publishes its own service catalog with its own codes, names and attributes, and the discovery file points you at it. A road-defect service in one city may ask for the block number while another asks which side of the street. App developers read the service list and service definition at runtime and build forms from what comes back.
Can a private company build an app using Open311 data?
Yes, and it is the main reason the standard exists. Any developer can call a city’s public Open311 endpoints subject to that city’s terms of use and API key rules. The standard carries no licence fee or membership requirement. What varies city by city is whether an API key is needed, what rate limits apply, and whether request data is exposed publicly.
What is the difference between Open311 and a regular 311 API?
A 311 API usually means one vendor’s interface to one city’s system, which is what most cities actually own. Open311 is the cross-vendor, cross-city contract layered on top, so the same client code works against many implementations. A city can expose both at once, and the proprietary one often sits behind the Open311-facing gateway.
How do developers handle updates when an Open311 implementation changes?
Re-read the discovery file and the service definitions rather than caching them forever, because service codes, attributes and picklist values are local choices that can change. Handle 403 and 404 as normal control flow instead of fatal errors, and treat status labels as free text you map yourself. The specification itself is frozen, so changes are local conventions, not breaking revisions.
Does Open311 guarantee that city departments respond within a specific time?
No. Response times are entirely a local service-level decision. The specification supports an optional expected_datetime field so a city can publish a target date, but many leave it empty. If your app promises a timeframe to users, source it from the city’s own commitments rather than assuming the standard provides one.
Conclusion
How Open311 standards work comes down to one fixed contract and a lot of local choice. The contract covers six API methods, a small set of required fields, XML with JSON as an option, and a discovery file that tells a client where to start. Everything else — which services exist, who handles them, how long they take, what a closed status is called — belongs to the city.
If you are building, fetch one city’s discovery file and its service definitions before writing a line of form code, and keep the service catalog in your configuration rather than hardcoded. If you are on the city side, the honest starting point is a small realtime service list for your two or three highest-volume non-emergency categories. Publish it, document the attribute names, and the interoperability benefit shows up faster than a procurement cycle does.


