VibeMap REST API
Welcome to the VibeMap REST API Documentation. VibeMap is still in the very early stages of development, so expect some changes in the near future as we rapidly prototype a minimum viable product. The API is versioned, and we will make every good faith effort to not break backwards compatibility, but be aware that things may be a little fluid in these initial stages.
Access
The API is now accessible at https://api.vibemap.com . The /api part of the path from the previous domain-less server has been removed. Now it is https://api.vibemap.com/<version>/<endpoint>/. Be sure to include the trailing slash!
Also note, if POST-ing JSON, you must also include Content-Type: application/json in the headers
A successful login will return a token that must be used in the headers of all subsequent requests, in the form of "Authorization: Token <token>"
Authentication v0.3
Preface all endpoints with /v0.3/. So, for example, the new registration endpoint is /v0.3/auth/users/
Available Endpoints
User Create (registration)
Use this endpoint to register a new user.
/auth/register/ (POST)
Fields:
- password
curl example
curl -X POST https://api.vibemap.com/v0.3/auth/register/ \
-H "Content-Type: application/json" \
-d '{"email": "cory@vibemap.com", "password": "sup3rs3kr1t"}'
Successful response: 201 CREATED
{
"user":
{"email": "<user's email>", "profile": "<id of the user's profile>"},
"token": "<token to use for authenticated requests>"
}
Unsuccessful response: 400 BAD REQUEST
{"<field name with problem>": ["<detail message 1>", "<detail message 2>"]}
Registration attempts are rate-limited per IP address to 5 per minute. Clients exceeding this rate will have a 429 TOO MANY REQUESTS response returned.
Logging In
/auth/login/ (POST)
Fields:
- password
curl example
curl -X POST https://api.vibemap.com/v0.3/auth/login/ \
-H "Content-Type: application/json" \
-d '{"email": "cory@vibemap.com", "password": "sup3rs3kr1t"}'
Successful response: 200 OK
{
"user":
{"email": "<user's email>", "profile": "<id of the user's profile>"},
"token": "<token to use for authenticated requests>"
}
Unsuccessful response: 400 BAD REQUEST
{
"non_field_errors": [
"Incorrect credentials"
]
}
Login attempts are rate-limited per IP address to 50 per hour. Clients exceeding this rate will have a 429 TOO MANY REQUESTS response returned.
Logging Out
/auth/logout/ (POST)
Headers:
Authorization: Token <token returned from login or registration>
curl example
curl -X POST https://api.vibemap.com/v0.3/auth/logout/ \
-H "Authorization: Token <token>"
Successful response: 204 NO CONTENT
(empty body)
Unsuccessful response: 401 UNAUTHORIZED
{
"detail": "<detail message>"
}
Password Reset
/auth/reset-password/ (POST)
Fields:
curl example
curl -X POST 'https://api.vibemap.com/v0.3/auth/reset-password/' \
-H "Content-Type: application/json" \
-d '{"email": "cory@vibemap.com"}'
All responses will return a 204 NO CONTENT with an empty response body. If the given email exists in our system they should receive the password reset email, which will have a link to a form to change their password. Password reset requests are throttled per IP address to 10 per day. Clients exceeding this limit will have a 429 TOO MANY REQUESTS response returned.
Password Change
/auth/change-password/ (POST)
Headers:
Authorization: Token <token returned from login or registration>
Fields:
current_passwordnew_passwordre_new_password
curl example
curl -X POST 'https://api.vibemap.com/v0.3/auth/change-password/' \
-H "Content-Type: application/json" \
-H "Authorization: Token <logged-in user's token>" \
-d '{
"current_password": "<user's current password>",
"new_password": "<user's new password>",
"re_new_password": "<user's new password again>"
}'
Successful response: 204 NO CONTENT
(empty body)
Unsuccessful response(s):
400 BAD REQUEST
{"<field name with problem>": ["<detail message 1>", "<detail message 2>"]}
401 UNAUTHORIZED
{
"detail": "<detail message>"
}
Profiles
/user-vibe-times/ (POST)
POST a user's vibes to a place, with optional details like time of day and day of week.
Headers:
Authorization: Token <token returned from login or registration>
Fields:
-
hotspots_place(required): The VibeMap ID of the place -
vibe(required): The vibe of the place. Must be in the acceptable list of vibes (see the Swagger docs). Currently, this must be one single string vibe, but we'll work on making it accept an array. -
time_of_day: The time of day that this vibe is associated with this place. Must be in the acceptable list of times of day (also on the Swagger docs; enumerated here for convenience). Can be omitted, in which case it will default toNONSPECIFIC. Also currently must be one single string value; working on making it accept an array. Choices:EARLY_MORNINGMORNINGLUNCHAFTERNOONAFTER_WORKEVENINGLATE_NIGHTNONSPECIFIC
-
day_of_week: The optional day of week to associated with this vibe and place. Can be omitted (null). Must be in the acceptable list of days of week (also on the Swagger docs; enumerated here for convenience). Also currently must be an integer value; working on making it accept an array. Choices:- 0 (Monday)
- 1 (Tuesday)
- 2 (Wednesday)
- 3 (Thursday)
- 4 (Friday)
- 5 (Saturday)
- 6 (Sunday)
- 7 (Public Holidays)
- 8 (Nonspecific, default if omitted)
curl example:
curl -X POST https://api.vibemap.com/v0.3/user-vibe-times/ \
-H "Content-Type: application/json" \
-H "Authorization: Token <token>" \
-d '{"hotspots_place": "<place id>", "vibe": "cool", "time_of_day": "LATE_NIGHT"}'
/user-tips/ (POST)
POST a user's tip to a place.
Headers:
Authorization: Token <token returned from login or registration>
Fields:
hotspots_place(required): The VibeMap ID of the placetip(required): The tip about the place (250 characters max)
curl example:
curl -X POST https://api.vibemap.com/v0.3/user-tips/ \
-H "Content-Type: application/json" \
-H "Authorization: Token <token>" \
-d '{"hotspots_place": "<id of the place>", "tip": "<user's tip>"}'
/profiles/individuals/<profile_id>/ (GET, PUT)
Headers:
Authorization: Token <token returned from login or registration>
Retrieve an authenticated user's profile, or the profile of another user if that user has chosen to make it public. The <profile_id> is returned in the user object upon successful login or registration. This will currently list all the primary keys of all the tips and vibes users have posted. I'm working on making these the more convenient fully hydrated objects, but in the meantime you can use this to verify that posting tips and vibes works as expected.
Make a PUT request to update the authenticated user's profile. Currently, the only update-able field is public, which is a boolean (default false) that controls whether or not the user's profile can be viewed by other authenticated users.
curl example:
curl -X PUT https://api.vibemap.com/v0.3/profiles/individuals/<profile_id>/ \
-H "Content-Type: application/json" \
-H "Authorization: Token <token>" \
-d '{"public": true}'
Vibes
The list of available vibes (all vibes and signature vibes) are available at /vibe-list/. For example:
curl https://api.vibemap.com/v0.3/vibe-list/
Pagination
Results are currently paginated at 50 per page by default. This can be controlled with the per_page parameter (up to 1000 records per page). The top-level keys for a list response (currently, the /events and /places endpoints) are count, next, previous, and results. The next and previous keys contain links to the next and previous pages, and the results key holds the 50 results for that page.
Example passing in per_page:
/v0.3/events/?per_page=200
Retrieve by ID
You can retrieve a specific event or place by its ID, by appending that ID as the last path element after the places or events endpoint, as in:
/v0.3/places/022f9c2b-a5cf-4324-86c5-3eef44fd2f86/
Eventually we'll have geopolitical namespacing and prettier slugs instead of these ugly UUIDs, but that will be in a later version.
Filtering
tile
Preferred Geo Filtering Method
For geo searching, using the Tile Map Service (TMS) Specification <https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification>_ is the preferred method, as it makes caching results much easier. This is done via the tile querystring parameter in the format z/x/y, which are cartesian coordinates in the "Web Mercator" projection. Most mapping libraries will handle this automatically for you. If you inspect the network requests that the Mapbox library makes when requesting a vector tile layer you should see something like:
GET https://tiles.vibemap.com/maps/places/11/326/790.mvt
To request the data from the API to match this tile:
GET https://api.vibemap.com/v0.3/places/?tile=11/326/790
in_bbox
Restrict to events within the given in_bbox parameter. Format must be in southwest_longitude,southwest_latitude,northeast_longitude,northeast_latitude (i.e., min_lon,min_lat,max_lon,max_lat). Example:
/v0.3/events/?in_bbox=-87.68368,41.9098466,-87.660770,41.9232589
Point Radius Search
It is also possible to make a point radius geographic query, by specifying a querystring of point=lon,lat&dist=<distance in meters>. Note the lon,lat ordering. Distance is always in meters (there are 1609.344 meters in one mile):
/v0.3/events/?point=-122.6757860,45.5244499&dist=500
start_date and end_date
Both the start_date and end_date fields on events can be used in range queries, as in start_date_after=YYYY-MM-DD HH:MM&end_date_before=YYYY-MM-DD HH:MM (the hour and minutes are optional).
is_open_at
Filter on places that are open at the given is_open_at parameter. is_open_at must be a timezone-aware ISO 8601 datetime string.
Some things to note about this:
- Virtually no places have data for this yet, this is basically just a proof-of-concept at this point.
- The query is very inefficient at the moment, as it has to pull all records first and then iterate over them to call a method to determine if they are open at the given
is_open_atparameter. So, if there are too many places to try to filter on within a baseline level of performance a400 BAD REQUESTresponse will be returned instead with a message explaining this.
Example:
/v0.3/places/?point=-87.67930,41.91030&dist=150&is_open_at=2020-06-20T21:00:00.000-05:00
Searching
Searching is currently available by using the search=term paramter, as in
/v0.3/events/?search=trivia
This currently performas only a fairly basic case-insensitive partial text search on the name and description fields on events. More advanced search functionality will be added soon.
Ordering
Ordering is currently available on the Event name, start_date, and end_date fields, e.g.
/v0.3/events/?search=trivia&ordering=name
Prepend the field with a - for descending order, as in:
/v0.3/events/?search=trivia&ordering=-start_date
Core API
Auto-generated Core API documentation is available at https://api.vibemap.com/v0.3/schema/