Scopes
A scope is one question your app is allowed to ask. Users grant them individually, so assume you'll often hold a subset of what you requested.
Request the narrowest set that makes your product work. Every extra scope is another line in the connect dialog, another thing to justify in your developer application, and another reason for someone to decline.
Choosing between the tiers
The question to ask yourself is: would an answer do?
If you're drawing a live map with a moving dot, you need coordinates and the sensitive tier is honest. If you're deciding whether to unlock a door, send a notification, tag a photo, or verify a transaction, an answer does — and the standard tier is both easier to get approved and cheaper to hold.
Some common mistakes:
- Reaching for
location.latest.readto check proximity. Uselocation.verify.zone. You get inside/outside without ever holding a position, and without the sensitive-tier friction. - Reaching for
location.history.readto build a timeline. Uselocation.visits.read. You get "arrived at the gym 9:15, left 10:40", which is what a timeline actually displays. - Polling
current-placeevery thirty seconds. Register a rule instead. Polling burns your budget and still tells you late; a rule tells you when it happens.
Scopes that depend on places
Five scopes are about the user's own named places — location.place.current, location.place.presence, location.visits.read, location.lookup.place, and location.rules.place for standing rules.
For these, the user picks which places you may ask about when they connect you, and can change that later without re-minting your token. Holding the scope doesn't mean seeing every place: a place that wasn't shared with you is invisible, and indistinguishable from one that doesn't exist.
Design for the case where a user shares nothing. current-place will answer no_place forever, and that's a legitimate configuration, not an error.
Scope changes over time
Your app's declared scopes can be narrowed by an admin during review. Because the effective set is the intersection of the user's grant and your app's current declaration, that takes effect immediately on live tokens — a call you made yesterday may 403 today.
Handle 403 by degrading the feature, not by retrying.
Scope reference
Every scope, the endpoints it unlocks, and its tier.
| Scope | Tier | Grants |
|---|---|---|
location.verify.zonePOST /v1/answers/verify-zone | Standard | Ask whether you are inside a zone the app names (yes/no only) |
location.place.currentGET /v1/answers/current-place | Standard | Ask which of your shared places you are at right now |
location.place.presenceGET /v1/answers/places/:place_id/presence | Standard | Ask whether you are at one specific shared place (yes/no only) |
location.visits.readGET /v1/visits | Standard | Read your visit history as place labels and time windows |
location.lookup.placeGET /v1/lookup/place?at= | Standard | Look up which shared place you were at, at a specific moment |
location.rules.placePOST/GET/DELETE /v1/rules/place | Standard | Get notified when you arrive at or leave a shared place |
location.rules.zonePOST/GET/DELETE /v1/rules/zone | Standard | Get notified when you enter or leave a zone the app names |
location.latest.readGET /v1/locations/latest | Sensitive | Read your exact current coordinates |
location.history.readGET /v1/locations/timerange | Sensitive | Read your exact coordinates over time ranges |
location.lookupGET /v1/locations/lookup?at= | Sensitive | Read your exact coordinates at a specific moment |