Join the Student Life Cities API
Cities and city guides
Cities and city guides
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/jointhestudentlife-com:jointhestudentlife-com-cities-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Student Life Cities API
version: 1.0.0
summary: Student cities, events, ticket prices and partner deals.
description: 'Open, keyless JSON API of The Student Life (jointhestudentlife.com): the cities where we run student communities, their guides, upcoming events with ticket prices and status, partner deals and pricing. Read endpoints need no authentication. Data refreshes whenever the website does. For AI agents, the same data is available as an MCP server at https://jointhestudentlife.com/mcp. Versioning and deprecation policy: the version is in the path (/api/v1); inside v1 we aim to only add things; a breaking change ships as /api/v2 and is announced on https://jointhestudentlife.com/developers#versioning before the old version changes, with Deprecation (RFC 9745) and, once a date is set, Sunset (RFC 8594) headers on affected endpoints. Rate limits are best effort per client, reported in RateLimit and X-RateLimit headers. Pagination is cursor based. Sandbox: POST /api/contact accepts dry_run to validate without sending.'
contact:
name: The Student Life
email: support@jointhestudentlife.com
url: https://jointhestudentlife.com/developers
x-deprecation-policy: https://jointhestudentlife.com/developers#versioning
servers:
- url: https://jointhestudentlife.com
security: []
tags:
- name: Cities
description: Cities and city guides
paths:
/api/v1:
get:
operationId: getApiIndex
summary: List the endpoints
tags:
- Cities
responses:
'200':
description: Index of endpoints
content:
application/json:
schema:
type: object
headers:
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
X-RateLimit-Limit:
$ref: '#/components/headers/X-RateLimit-Limit'
X-RateLimit-Remaining:
$ref: '#/components/headers/X-RateLimit-Remaining'
X-RateLimit-Reset:
$ref: '#/components/headers/X-RateLimit-Reset'
API-Version:
$ref: '#/components/headers/API-Version'
'429':
$ref: '#/components/responses/TooManyRequests'
/api/v1/cities:
get:
operationId: searchCities
summary: Search cities
description: Cities where The Student Life runs communities and events, with links to each city guide, festival page and Halloween page.
tags:
- Cities
parameters:
- name: q
in: query
description: City or country name, partial is fine.
schema:
type: string
example: berlin
- name: country
in: query
description: Country name or two letter code.
schema:
type: string
example: DE
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 100
description: Page size.
- $ref: '#/components/parameters/Cursor'
responses:
'200':
description: Matching cities
content:
application/json:
schema:
$ref: '#/components/schemas/CityList'
headers:
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
X-RateLimit-Limit:
$ref: '#/components/headers/X-RateLimit-Limit'
X-RateLimit-Remaining:
$ref: '#/components/headers/X-RateLimit-Remaining'
X-RateLimit-Reset:
$ref: '#/components/headers/X-RateLimit-Reset'
API-Version:
$ref: '#/components/headers/API-Version'
'429':
$ref: '#/components/responses/TooManyRequests'
default:
$ref: '#/components/responses/Error'
/api/v1/cities/{slug}:
get:
operationId: getCityGuide
summary: Get a city guide
description: Costs, neighbourhoods, universities, housing tips, places and upcoming events for one city.
tags:
- Cities
parameters:
- name: slug
in: path
required: true
description: City slug from searchCities, or a city name.
schema:
type: string
example: lisbon
responses:
'200':
description: City guide
content:
application/json:
schema:
$ref: '#/components/schemas/CityGuide'
headers:
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
X-RateLimit-Limit:
$ref: '#/components/headers/X-RateLimit-Limit'
X-RateLimit-Remaining:
$ref: '#/components/headers/X-RateLimit-Remaining'
X-RateLimit-Reset:
$ref: '#/components/headers/X-RateLimit-Reset'
API-Version:
$ref: '#/components/headers/API-Version'
'404':
$ref: '#/components/responses/Error'
'429':
$ref: '#/components/responses/TooManyRequests'
default:
$ref: '#/components/responses/Error'
components:
headers:
RateLimit:
description: 'Current window: limit, remaining and seconds until reset (draft-ietf-httpapi-ratelimit-headers).'
schema:
type: string
example: limit=120, remaining=119, reset=60
X-RateLimit-Limit:
schema:
type: integer
X-RateLimit-Remaining:
schema:
type: integer
X-RateLimit-Reset:
description: Unix time when the window resets.
schema:
type: integer
RateLimit-Policy:
description: Quota policy.
schema:
type: string
example: 120;w=60
API-Version:
description: Major version that served the response.
schema:
type: string
example: '1'
Retry-After:
description: Seconds to wait after a 429.
schema:
type: integer
schemas:
CityGuide:
allOf:
- $ref: '#/components/schemas/CityCard'
- type: object
properties:
about:
type: string
monthly_costs:
type: array
items:
type: object
properties:
label:
type: string
value:
type: string
universities:
type: array
items:
type: object
properties:
name:
type: string
url:
type: string
upcoming_events:
type: array
items:
$ref: '#/components/schemas/Event'
Event:
type: object
properties:
id:
type: string
type:
type: string
enum:
- halloween
- welcome_festival
- semester_kickoff
- orientation_week
name:
type: string
city:
type: string
city_slug:
type:
- string
- 'null'
start:
type: string
end:
type:
- string
- 'null'
timezone:
type:
- string
- 'null'
venue:
type:
- object
- 'null'
properties:
name:
type: string
address:
type:
- string
- 'null'
age_min:
type:
- integer
- 'null'
url:
type: string
format: uri
status:
type: string
enum:
- upcoming
- past
tickets:
type: object
properties:
status:
type: string
enum:
- on_sale
- opens_soon
- coming_soon
- sales_closed
- see_page
- ended
description: 'opens_soon: published, but sales open at sales_open_at. sales_closed: the organiser closed ticket sales.'
options:
type: array
items:
$ref: '#/components/schemas/TicketOption'
early_access:
type:
- object
- 'null'
buy_url:
type: string
format: uri
note:
type: string
sales_open_at:
type:
- string
- 'null'
format: date-time
description: When ticket sales open, for status opens_soon.
waitlist_open:
type: boolean
whatsapp_group:
type:
- string
- 'null'
entry_rule:
type:
- string
- 'null'
Error:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
enum:
- bad_request
- not_found
- method_not_allowed
- internal_error
- rate_limited
- expired
- too_large
message:
type: string
status:
type: integer
docs:
type: string
format: uri
TicketOption:
type: object
properties:
name:
type: string
price:
type: number
currency:
type: string
CityCard:
type: object
properties:
slug:
type: string
name:
type: string
country:
type: string
country_code:
type: string
summary:
type: string
festival_name:
type: string
city_guide_url:
type: string
format: uri
festival_url:
type: string
format: uri
halloween_url:
type:
- string
- 'null'
format: uri
CityList:
type: object
properties:
total:
type: integer
cities:
type: array
items:
$ref: '#/components/schemas/CityCard'
next_cursor:
type:
- string
- 'null'
description: Pass as cursor to get the next page; null on the last page.
responses:
TooManyRequests:
description: Rate limited
headers:
Retry-After:
$ref: '#/components/headers/Retry-After'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
X-RateLimit-Limit:
$ref: '#/components/headers/X-RateLimit-Limit'
X-RateLimit-Remaining:
$ref: '#/components/headers/X-RateLimit-Remaining'
X-RateLimit-Reset:
$ref: '#/components/headers/X-RateLimit-Reset'
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Error:
description: Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
parameters:
Cursor:
name: cursor
in: query
description: 'Opaque cursor: the next_cursor of the previous page. Leave out for the first page.'
schema:
type: string
externalDocs:
description: For AI agents and developers
url: https://jointhestudentlife.com/developers