Skip to content

Cities​

Cities (#2064): the /cities index and map, one city page, following a city with its weekly digest and instant alerts, the MapKit token and the map snapshots. A city has a public page at 1+ verified Fundly or 5+ donors. Donor counts, follower counts and where gifts go show only at 5+; donors are never listed by city.


List cities​

GET
/cities

Every city with a verified Fundly or a donor, not hidden by staff. Cities below the page threshold are included with has_page: false (show them as plain text). totals are platform-wide and ignore q and area. near_you is the nearest city with a page within 100 miles of near, else of the signed-in viewer's profile city, else of the edge's viewer location headers when present; null otherwise. Authentication is optional and only feeds near_you.

Authorizations​

BearerAuth

In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.

Type
HTTP (bearer)
or

Parameters​

Query Parameters

q

Matches the city name or its metro's name.

Type
string
sort

active: featured first, then live Fundlies, donors, raised. az: by name.

Type
string
Valid values
"active""az"
Default
"active"
area
Type
string
Valid values
"all""us""intl"
Default
"all"
near

A lat,lng point for near_you.

Type
string
Example"38.58,-121.49"
limit
Type
integer
Minimum
1
Maximum
500
Default
24
offset
Type
integer
Minimum
0
Default
0

Responses​

One page of cities

application/json
JSON
{
"data": [
],
"total": 0,
"totals": {
"cities": 0,
"us_cities": 0,
"countries": 0,
"us_states": 0,
"fundlies": 0,
"fundly_cities": 0,
"raised_cents": 0,
"donors": 0
},
"near_you": {
"slug": "sacramento-ca",
"name": "Sacramento",
"region": "CA",
"country": "US",
"label": "Sacramento, CA",
"photo_url": "string",
"lat": 0,
"lng": 0,
"fundlies_active": 0,
"fundlies_funded": 0,
"donors": 0,
"raised_cents": 0,
"has_page": true,
"metro": {
"slug": "string",
"name": "string"
}
}
}

Playground​

Server
Authorization
Variables
Key
Value

Samples​


City map dots​

GET
/cities/map

One dot per city with a verified Fundly or a donor. Donor counts are null below 5.

Parameters​

Query Parameters

scope
Type
string
Valid values
"us""world"
Default
"world"

Responses​

The dots

application/json
JSON
{
"points": [
]
}

Playground​

Server
Variables
Key
Value

Samples​


The cities map as an image​

GET
/cities/map/snapshot

A redirect to a signed Apple Maps Web Snapshot with the same dots when a MapKit key is configured, else the static map: an SVG of Natural Earth outlines with the dots, in Web Mercator. Use it as an image source; it works for both answers.

Parameters​

Query Parameters

scope
Type
string
Valid values
"us""world"
Default
"us"
w
Type
integer
Minimum
64
Maximum
2048
Default
1152
h
Type
integer
Minimum
64
Maximum
2048
Default
480
scheme
Type
string
Valid values
"light""dark"
Default
"light"

Responses​

The static map

image/svg+xml
JSON
"string"

Playground​

Server
Variables
Key
Value

Samples​


The one-click opt-out page​

GET
/cities/unsubscribe

The link in every city email. Reads only (mail scanners prefetch links): an HTML page with a button that posts back, or the state as JSON when the caller asks for application/json.

Parameters​

Query Parameters

token*
Type
string
Required
Format
"uuid"
kind
Type
string
Valid values
"digest""instant"
Default
"digest"

Responses​

The page, or the state

JSON
"string"

Playground​

Server
Variables
Key
Value

Samples​


One-click opt-out​

POST
/cities/unsubscribe

The List-Unsubscribe-Post target (RFC 8058) and the page's button: turns off that city's weekly digest (kind=digest) or instant alerts (kind=instant) for the follow the token names, and keeps the follow. Idempotent. No session: the token is the authorization. A mail client gets JSON; a browser form (it asks for text/html) is redirected to Settings, /profile/settings?city_digest_off={slug} for a digest.

Parameters​

Query Parameters

token*
Type
string
Required
Format
"uuid"
kind
Type
string
Valid values
"digest""instant"
Default
"digest"

Responses​

Turned off

application/json
JSON
{
"data": "string"
}

Playground​

Server
Variables
Key
Value

Samples​


Get a city page​

GET
/cities/{slug}

One city page. 404 (CITY_NOT_FOUND) unless the city has a page: 1+ verified Fundly or 5+ donors, or forced on by staff, and never while hidden. A slug retired by a rename or a merge serves the surviving city: city.slug is canonical, and a page should redirect to it when it differs. Authentication is optional and only personalizes follow; render the page server-side without it.

Authorizations​

BearerAuth

In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.

Type
HTTP (bearer)
or

Parameters​

Path Parameters

slug*
Type
string
Required
Example"sacramento-ca"

Query Parameters

lang

Fundly titles in this language where a translation exists.

Type
string
Valid values
"en""ru""uk""es"

Responses​

The city

application/json
JSON
"string"

Playground​

Server
Authorization
Variables
Key
Value

Samples​


A city's map as an image​

GET
/cities/{slug}/snapshot

The map around one city (about 60 miles each way) with its dots: a redirect to a signed Apple Maps Web Snapshot when a MapKit key is configured, else the static SVG. 404 unless the city has a page.

Parameters​

Path Parameters

slug*
Type
string
Required

Query Parameters

w
Type
integer
Minimum
64
Maximum
2048
Default
640
h
Type
integer
Minimum
64
Maximum
2048
Default
360
scheme
Type
string
Valid values
"light""dark"
Default
"light"

Responses​

The static map

image/svg+xml
JSON
"string"

Playground​

Server
Variables
Key
Value

Samples​


My follow of a city​

GET
/cities/{slug}/follow

Authorizations​

BearerAuth

In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.

Type
HTTP (bearer)

Parameters​

Path Parameters

slug*
Type
string
Required

Responses​

The follow block

application/json
JSON
{
"data": "string"
}

Playground​

Server
Authorization
Variables
Key
Value

Samples​


Follow a city, or change its notifications​

PUT
/cities/{slug}/follow

Idempotent. Creates the follow with the defaults (weekly digest on, instant alerts off) or changes only the switches given. The bell on the city page sends both false to silence a city without unfollowing. 404 when the city has no page.

Authorizations​

BearerAuth

In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.

Type
HTTP (bearer)

Parameters​

Path Parameters

slug*
Type
string
Required

Request Body​

application/json
JSON
{
"digest": true,
"instant": true
}

Responses​

The follow block after the change

application/json
JSON
{
"data": "string"
}

Playground​

Server
Authorization
Variables
Key
Value
Body

Samples​


Unfollow a city​

DELETE
/cities/{slug}/follow

Idempotent. Works even after the city lost its page.

Authorizations​

BearerAuth

In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.

Type
HTTP (bearer)

Parameters​

Path Parameters

slug*
Type
string
Required

Responses​

The follow block after the change

application/json
JSON
{
"data": "string"
}

Playground​

Server
Authorization
Variables
Key
Value

Samples​


Cities I follow​

GET
/me/city-follows

Settings > Notifications > Cities you follow, newest first, and the Settings > Privacy switch show_followed_cities_to_friends (change it with PATCH /users/{id}). Change a city's switches with PUT /cities/{slug}/follow.

Authorizations​

BearerAuth

In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.

Type
HTTP (bearer)

Responses​

The follows

application/json
JSON
{
"data": [
{
"city": {
"slug": "string",
"name": "string",
"label": "string",
"photo_url": "string",
"has_page": true
},
"digest": true,
"instant": true,
"created_at": "string"
}
],
"show_followed_cities_to_friends": true
}

Playground​

Server
Authorization

Samples​


MapKit JS token​

GET
/maps/token

The token MapKit JS initializes with. Minted (a 30-minute ES256 token for this site's origin) when the server holds a MapKit key, else the static token configured for the site (expires_at null when it has no expiry), else 503 with code MAPKIT_NOT_CONFIGURED, and the page keeps its static map. Never cached.

Responses​

A token

application/json
JSON
{
"token": "string",
"expires_at": "string"
}

Playground​

Samples​


Powered by VitePress OpenAPI

Built with VitePress