San Antonio Crime Map
Every reported Group A offence SAPD has published since January 2023, mapped by ZIP code, with 42 months of trend behind each one. It tells you which ZIP codes genuinely changed last month and which ones only look like they did. Built from the City’s own open data, and honest about what that data cannot tell you.
Reported offences by ZIP code
SAPD NIBRS Group A offences, 2025-07 to 2026-06 (trailing 12 months). 132,846 offences across 62 ZIP codes.
ZIP codes ranked by the selected measure. A per-1,000 rate is withheld where fewer than 5,000 people live in the ZIP code, and a percentage change is withheld where the prior period held fewer than 50 offences: in both cases the denominator is too small for the number to mean anything.
| ZIP | Offences | Per 1,000 | Per sq mi | vs prior yr | 42-month trend |
|---|---|---|---|---|---|
| 78207 | 7,221 | 133.4 | 956 | +10.1% | |
| 78216 | 6,189 | 147.2 | 440 | -16.0% | |
| 78223 | 5,637 | 98.4 | 131 | +4.8% | |
| 78228 | 4,621 | 83.3 | 409 | -7.9% | |
| 78227 | 4,548 | 103.2 | 328 | -5.8% | |
| 78249 | 3,966 | 64.2 | 269 | -11.2% | |
| 78229 | 3,964 | 112.6 | 698 | -10.4% | |
| 78201 | 3,946 | 90.9 | 552 | -8.1% | |
| 78251 | 3,898 | 63.2 | 268 | -8.7% | |
| 78237 | 3,876 | 105.0 | 552 | -10.5% | |
| 78240 | 3,667 | 64.3 | 326 | -2.6% | |
| 78230 | 3,660 | 87.0 | 353 | -18.9% | |
| 78218 | 3,583 | 93.6 | 328 | -9.0% | |
| 78245 | 3,581 | 39.2 | 108 | -15.2% | |
| 78210 | 3,548 | 102.1 | 466 | +1.3% | |
| 78221 | 3,535 | 85.0 | 108 | +1.8% | |
| 78205 | 3,345 | n/a | 3,413 | -4.2% | |
| 78212 | 3,331 | 124.9 | 472 | -1.0% | |
| 78224 | 3,322 | 160.7 | 217 | -5.5% | |
| 78217 | 3,276 | 96.5 | 330 | -1.1% | |
| 78238 | 3,027 | 115.3 | 325 | -11.2% | |
| 78209 | 2,736 | 63.1 | 273 | -2.4% | |
| 78211 | 2,697 | 88.2 | 269 | -1.6% | |
| 78232 | 2,695 | 74.3 | 226 | -8.2% | |
| 78213 | 2,684 | 64.5 | 344 | -10.9% | |
| 78214 | 2,587 | 118.2 | 193 | -10.0% | |
| 78220 | 2,496 | 134.9 | 222 | -3.6% | |
| 78247 | 2,391 | 46.0 | 183 | -2.8% | |
| 78233 | 2,242 | 47.0 | 162 | -10.3% | |
| 78242 | 2,198 | 61.1 | 281 | -2.8% | |
| 78258 | 2,159 | 41.8 | 127 | -7.6% | |
| 78250 | 2,055 | 35.5 | 213 | -9.0% | |
| 78202 | 1,826 | 183.5 | 739 | -4.1% | |
| 78222 | 1,741 | 69.6 | 105 | -0.3% | |
| 78257 | 1,709 | 164.5 | 29.7 | -20.2% | |
| 78204 | 1,549 | 129.7 | 557 | -15.2% | |
| 78219 | 1,525 | 90.0 | 109 | -3.3% | |
| 78215 | 1,397 | n/a | 1,330 | -15.3% | |
| 78256 | 1,230 | 102.4 | 147 | -20.8% | |
| 78259 | 1,160 | 43.1 | 67.0 | -2.5% | |
| 78254 | 1,142 | 14.5 | 43.0 | -15.3% | |
| 78225 | 892 | 67.6 | 467 | +0.7% | |
| 78226 | 781 | 113.1 | 202 | +10.3% | |
| 78203 | 713 | n/a | 540 | +6.4% | |
| 78244 | 700 | 18.5 | 89.7 | -4.4% | |
| 78208 | 623 | n/a | 617 | +7.2% | |
| 78253 | 583 | 8.6 | 10.9 | -3.8% | |
| 78231 | 502 | 50.4 | 111 | -5.6% | |
| 78235 | 432 | n/a | 204 | -19.7% | |
| 78252 | 424 | 23.2 | 13.9 | -19.4% | |
| 78248 | 409 | 29.0 | 102 | -3.3% | |
| 78239 | 294 | 9.8 | 43.8 | +1.7% | |
| 78255 | 151 | 8.3 | 8.4 | -38.1% | |
| 78260 | 140 | 3.7 | 5.8 | -23.5% | |
| 78264 | 98 | 8.4 | 1.3 | +32.4% | |
| 78266 | 68 | 9.3 | 1.7 | -18.1% | |
| 78234 | 32 | 5.1 | 6.1 | — | |
| 78236 | 26 | 3.4 | 2.0 | — | |
| 78261 | 8 | 0.3 | 0.3 | — | |
| 78206 | 4 | n/a | 400 | — | |
| 78243 | 3 | n/a | 8.6 | — | |
| 78263 | 3 | n/a | 0.1 | — |
What actually changed in 2026-06
Nothing did. Not one of the 51 ZIP codes we can test moved far enough from its own expected range to be distinguishable from ordinary month-to-month noise. Several of them changed by more than 20%, and that change still means nothing. Below is the evidence, including the ZIPs whose headline percentages look alarming.
Ranked by how far each ZIP code departed from its own expected count — not by percentage change. Expected is that ZIP's own 24-month baseline, adjusted for the seasonal pattern and for how many days the month has. The comparison is quasi-Poisson: offence counts cluster, so their variance genuinely exceeds their mean, and a plain Poisson test would call several ZIP codes "unusual" every single month just by misjudging the noise. A ZIP is only called unusual beyond 3.0 standard deviations, because testing 51 ZIP codes at once at the conventional 95% threshold would flag about 3 of them by chance alone. Withheld below 30 expected offences.
| ZIP | Observed | Expected | Change | Std devs | Verdict |
|---|---|---|---|---|---|
| 78225 | 106 | 74 | +51% | +2.9 | Within normal range |
| 78227 | 319 | 403 | -22% | -2.4 | Within normal range |
| 78258 | 141 | 192 | -24% | -2.4 | Within normal range |
| 78238 | 223 | 274 | -25% | -2.2 | Within normal range |
| 78233 | 165 | 202 | -17% | -2.1 | Within normal range |
| 78247 | 238 | 202 | +11% | +2.1 | Within normal range |
| 78251 | 290 | 347 | -9% | -1.8 | Within normal range |
| 78252 | 27 | 41 | — | -1.7 | Within normal range |
Read the third and fifth columns together. That is the entire point of this panel: a ZIP code can move by half and still be doing nothing unusual, because a small denominator moves easily. Percentage change is the number every other crime map leads with, and it is the number most likely to mislead you.
Which day of the week
Offences against the person and offences against property run on opposite weekly clocks. Bars show each day against an average day (the dashed line = 100).
| Mon | 102 |
|---|---|
| Tue | 93 |
| Wed | 90 |
| Thu | 94 |
| Fri | 97 |
| Sat | 107 |
| Sun | 116 |
| Mon | 110 |
|---|---|
| Tue | 106 |
| Wed | 101 |
| Thu | 99 |
| Fri | 100 |
| Sat | 94 |
| Sun | 89 |
| Mon | 101 |
|---|---|
| Tue | 98 |
| Wed | 97 |
| Thu | 101 |
| Fri | 104 |
| Sat | 104 |
| Sun | 97 |
Do not read this as when crime happens. The City publishes the date an offence was reported, not the date it occurred, and the two come apart in a very specific way. You discover the break-in on Monday morning; businesses report over the weekend on Monday. That is almost certainly why property offences peak on a Monday and bottom out on a Sunday — it is the weekend's backlog arriving, not a Monday crime wave. Offences against the person, which tend to be reported the day they happen, show the pattern you would actually expect: they peak on the weekend. We publish the weekday shape because it is real and it is in the data. We are telling you what it does and does not mean because most of what you can do with it is wrong.
Take the data
Everything above is built from these two files, and you can have both. The CSV is one row per ZIP code, per month, per offence type — the shape you want for a spreadsheet or a notebook. No signup, no email, no attribution required to us.
Download CSV JSON (indexed cube) JSON (ZIP geometry)
The underlying records are published by the City of San Antonio under CC-BY (City of San Antonio) — the City is the source and deserves the credit. If our processing of it is useful to you, a link back to this page is welcome but not required. Cite it as: BrandShyp, “San Antonio reported offences by ZIP code”, derived from City of San Antonio open data (SAPD Offenses), built 2026-07-12.
Source: City of San Antonio open data — SAPD Offences (CC-BY (City of San Antonio)). NIBRS Group A offenses only. Population: U.S. Census ACS 5-year (2023), table B01003. We count offences, not incidents: the 516,255 published offences arise from 472,301 distinct police reports, because one report can carry several offences. A dashboard that counts reports will show a smaller number than this one and both will be correct. Data through 2026-06; the City publishes monthly, so the most recent weeks are not yet included. 5,196 of 516,255 records (1.01%) carry no usable ZIP code and are not mapped. Built 2026-07-12.
Read this before you read the map
A crime map that does not explain itself is closer to a rumour than a record. Here is exactly what this one is.
It shows reports, not convictions, and not all crime
Every number here is an offence reported to SAPD. Some reports are later unfounded. Nobody on this map has been convicted of anything, and no individual is named, because the City’s data contains no names, no addresses, and no coordinates. That is a feature, not a gap.
It also is not all crime. The published dataset covers NIBRS Group A offences only, which excludes DUI, disorderly conduct, and trespass, among others. Crimes that are never reported appear nowhere in it, and for some categories that is most of them.
ZIP code is as precise as the data goes
You may have seen crime maps that drop a pin on a block. They are working from a private police records feed. The City’s public dataset has no street address and no latitude or longitude: the finest geography it publishes is the ZIP code. So this map stops at the ZIP code, rather than inventing a precision it does not have.
A ZIP code is also not a neighbourhood. It is a mail-delivery boundary that can span a wealthy subdivision, an industrial park, and a highway interchange at once. Treat a ZIP-level figure as a coarse signal, never as a verdict on a street.
The part most crime maps get wrong
Dividing by residents is how you produce a lie
The instinct is to rank ZIP codes by offences per resident. Do that naively here and downtown 78205 comes out at roughly 6,100 offences per 1,000 residents, which reads as six crimes for every person who lives there.
That number is not measuring danger. It is measuring the Riverwalk. About 2,100 people live in 78205, while millions of visitors, commuters, and workers pass through it. The offences are real; the denominator is wrong. The same distortion hits the Pearl area (78215) and the military annexes (78235, 78243).
So this map defaults to absolute counts, and it withholds the per-resident rate entirely for any ZIP code with fewer than 5,000 residents rather than publishing a figure it knows is misleading. Even above that line, a retail corridor like 78216 carries the airport and North Star Mall, so its rate still reflects people who do not live there. Daytime population is not in the data, and we will not pretend otherwise.
We also give you a second denominator that has no opinion about who sleeps where: offences per square mile. It is not a better denominator, it is a different one, with a bias of its own — it flatters anything large and empty. Switch between the two. Where they disagree about a ZIP code, the disagreement is telling you something that either number alone would have hidden.
This is why the change over time view exists. Comparing a ZIP code against its own past needs no population denominator at all, which makes it the most trustworthy number on this page.
It has a small-numbers trap of its own, and we close it the same way. A ZIP code that went from two offences to four is up 100%, a figure that would top the rankings while telling you nothing. So no percentage change is shown where the prior period held fewer than 50 offences, and the colour scale is set by the 90th percentile of movement across the city rather than by its single most extreme ZIP code, which would otherwise flatten every real change into grey.
The trap that is hiding in your calendar
February is not safer. February is shorter.
Here is a mistake almost every crime dashboard makes, and it is invisible until someone points at it. Compare February to July on raw monthly counts and February comes out roughly 8% lower. Print that next to a downward arrow and you have just told the city that crime falls in February.
It does not. February has 28 days and July has 31. That is a difference of about 10% in the amount of time available for anything to happen at all. Nearly the entire “drop” is the calendar. Any month-to-month comparison that has not divided by the number of days in the month is measuring the length of the month.
So every figure on this page that compares one period to another is computed on a per-day basis first. Once you remove the calendar artefact, a genuine seasonal pattern does emerge underneath it, and it is a much smaller one than the raw numbers suggest: San Antonio runs a few percent busier in high summer and quieter in midwinter.
This is the third denominator trap on this page, and it is the same mistake as the other two wearing different clothes. Divide by the wrong thing and the number you publish will be about the divisor rather than the city. Residents, area, days: pick the wrong one and the map lies confidently.
Why we will not tell you crime is “up 51%”
A percentage change is the number every crime map leads with, and it is the number most likely to mislead you, because it is really a ranking of small denominators. A ZIP code with a modest baseline can swing by half on nothing more than an ordinary month.
So the What actually changed panel above does not rank by percentage. It asks a harder and more useful question: given what this ZIP code normally does at this time of year, is this month actually surprising? Each ZIP is compared against its own baseline, adjusted for the season and the length of the month, and we report how many standard deviations away it landed.
The percentage change is shown right next to it, deliberately, so that you can watch the two disagree. They frequently do. That gap is the entire argument for building this thing.
Two details that most published analysis skips, and both change the answer:
Offence counts are overdispersed. Crime clusters, so real month-to-month variance is well above what a textbook Poisson model assumes — in some ZIP codes several times above it. Test against plain Poisson and you will discover “statistically significant” spikes every single month that are nothing at all. We estimate each ZIP code’s own dispersion from its own history and widen the interval to match.
We are testing dozens of ZIP codes at once. At the reflexive 95% confidence threshold, roughly three of San Antonio’s ZIP codes would be flagged as unusual by chance alone, every month, forever. A map that reported them would manufacture a scare story on a monthly schedule. We only call a ZIP code unusual beyond three standard deviations.
The honest consequence: on a typical month, this panel tells you that nothing unusual happened. That is not a broken feature. That is the answer, and almost nobody publishes it.
How this was built
Reproducible end to end. Every input is public, and you can check any figure here against the source.
The pipeline
Offence records come from the City of San Antonio’s open data portal (SAPD Offenses, CC BY licence) through its CKAN SQL API. They are aggregated to one cell per ZIP code, per month, per offence type, and joined to the City’s own ZIP boundary layer, which is projected to flat SVG geometry at build time. No map library, no tiles, and no third-party tracker loads on this page.
The build asserts its own totals. It re-counts the source table independently and refuses to publish if the aggregate does not reconcile to the row count, because the City’s datastore truncates large responses silently and a partial extract would look perfectly normal.
What we throw away, and why we tell you
Of 516,255 published records, 5,196 (1.01%) carry a blank or unmappable ZIP code. They are excluded, because there is nowhere honest to put them. The alternative, quietly assigning them somewhere, is how a map starts lying.
We count offences, not incidents. Those 516,255 offences come from 472,301 distinct police reports, because a single report can carry more than one offence. A dashboard that counts reports will show you a smaller number than this one, and neither of us is wrong. Ask which is being counted before you compare two crime figures.
The City republishes monthly, so the most recent few weeks are never present. If you need what happened last night, this is the wrong tool, and we would rather say so than imply a freshness we do not have.
Every figure in this section is read live from the same data file the map is drawn from, so it cannot drift out of step with the map above it. Data built 2026-07-12. Population: U.S. Census ACS 5-year (2023), table B01003.
Why an IT contractor built a crime map
Because this is the work. A government agency hands you a messy public dataset with a silent truncation bug, no coordinates, a denominator that produces nonsense, and a 1% slice that does not fit anywhere. The job is not to make a pretty dashboard. The job is to find the traps before they end up in a published figure that somebody makes a decision on.
Everything on this page is the same discipline we bring to a federal or municipal data contract: reconcile against the source, refuse to ship what does not add up, and state the limitations on the face of the artifact rather than in a footnote nobody reads.
We are a San Antonio software and data firm working across federal and local government. If your agency or team has a dataset that needs to become something people can actually use, and needs to be defensible when someone challenges a number in it, that is the conversation to have.
The code behind this map, the reconciliation checks, and the methodology are all available on request.
Show me how you would handle my dataset
We'll send a copy and, if you want, help you take the next step. No spam.
Related free tools
Auditable AI Data Analysis
Ask a question of your own data and get an answer with the full trace showing how it was derived.
STIG to NIST 800-53 Mapper
Paste a STIG rule, a CCI, or a whole checklist and get the Rev 5 controls it maps to, with the trace.
Accessibility Checker
Scan a page against WCAG 2.1 AA and Section 508 and get the specific failures, not a score.
Schedule Your Technical Briefing
Skip the email queue. Book a direct 30-minute discovery session on our technical calendar.
Pick a date
Available times
All times shown in Central (Chicago)You're booked.
A confirmation email is on its way from [email protected].
If you need to reschedule, reply to the confirmation email and we’ll handle it.