Hi, I registered an app (App ID 39193178030328240) with READ switched on. The vector tiles work with my client token. But every Graph API request returns nothing. GET /{image_id} gives error 100, subcode 33 (“missing permissions”), and /images?bbox=… returns an empty list, even at the Eiffel Tower. Is there an approval step for new apps? Thank you!
Thank you for the post. You don’t need an approval, it should work.Try this one:
1. Empty /images?bbox=…: the order is west,south,east,north, so longitude comes first. For the Eiffel Tower:
https://graph.mapillary.com/images?bbox=2.29,48.85,2.30,48.86&fields=id&access_token=MLY|...
2. Error 100 / subcode 33 on GET /{image_id}: despite the wording, this usually means the ID isn’t a valid image ID (for example a sequence ID or an old-style key). Use a numeric id returned by the bbox call above (or the id from the vector tiles):
https://graph.mapillary.com/ID_RETURNED?fields=id,thumb_1024_url&access_token=MLY|...
If it still fails, post the full request URL with the token removed and we’ll take a look.
__
BR, Yaro
Same issue here: a new app registered today (2026-10-21), App ID 30592537330350355, READ scope on.
The client token itself is valid: vector tiles return 200 with it, while a made-up token gets 403 from the tiles and 400 “Error validating application” from Graph. But the Graph API returns nothing:
-
Your Eiffel Tower example, longitude first:
GET https://graph.mapillary.com/images?bbox=2.29,48.85,2.30,48.86&fields=id&access_token=MLY|…
→ 200 {“data”:} -
An image id taken from the vector tiles (z14 tile over Barcelona, layer “image”):
GET https://graph.mapillary.com/1087262524033451?fields=id,thumb_1024_url&access_token=MLY|…
→ {“error”:{“message”:“Unsupported get request. Object with ID ‘1087262524033451’ does not exist, cannot be loaded due to missing permissions, or does not support this operation”,“type”:“MLYApiException”,“code”:100,“error_subcode”:33}} -
MapillaryJS 4.1.2 with the same token and image id: “Failed to cache image (1087262524033451)”.
Larger boxes (±0.04°, around 41.39,2.17) also fail after about 30 s with 500, code 1, subcode 99.
Is there anything missing on the app side, or is this a problem with newly registered apps? Thanks!
@Yaro , @caglarpmeta - could you chime in on this one?
I’ve just created a new app with the only capability READ, and I was able to get something back. And there are not many options, but READ/WRITE/UPLOAD, so there might be something interesting. Let’s try to pinpoint the problem (and find what’s failing).
As a first step, let’s sync on the exact steps.
If you have bash, you can try this script (or a part of it) below:
#!/usr/bin/env bash
# Mapillary API probe using only shell built-ins and curl.
# The token is read from MAPILLARY_TOKEN and is never printed.
set -u
set -o pipefail
: "${MAPILLARY_TOKEN:?Set MAPILLARY_TOKEN before running this script}"
IMAGE_ID="${1:-}"
INCLUDE_LARGE_BBOX="${INCLUDE_LARGE_BBOX:-0}"
CURL_TIMEOUT="${CURL_TIMEOUT:-90}"
LAST_GRAPH_BODY=""
SMALL_BBOX="2.29,48.85,2.30,48.86"
LARGE_BBOX="2.13,41.35,2.21,41.43"
# Tile containing the centre of SMALL_BBOX at zoom 14.
TILE_SCHEMA="mly1_public"
TILE_Z="14"
TILE_X="8296"
TILE_Y="5636"
print_separator() {
printf '\n%s\n' '------------------------------------------------------------'
}
run_graph_images() {
local label="$1"
local bbox="$2"
local output curl_status metadata http_code total_time size_download
print_separator
printf '%s\n' "$label"
printf 'GET https://graph.mapillary.com/images\n'
printf ' bbox=%s\n' "$bbox"
printf ' fields=id\n'
printf ' limit=1\n'
printf ' access_token=<redacted>\n\n'
output="$(
curl \
--silent \
--show-error \
--get \
--connect-timeout 10 \
--max-time "$CURL_TIMEOUT" \
--data-urlencode "bbox=${bbox}" \
--data-urlencode 'fields=id' \
--data-urlencode 'limit=1' \
--data-urlencode "access_token=${MAPILLARY_TOKEN}" \
--write-out $'\n__CURL_METADATA__%{http_code}|%{time_total}|%{size_download}' \
'https://graph.mapillary.com/images'
)"
curl_status=$?
LAST_GRAPH_BODY="${output%$'\n__CURL_METADATA__'*}"
metadata="${output##*$'\n__CURL_METADATA__'}"
IFS='|' read -r http_code total_time size_download <<< "$metadata"
printf '%s\n' "$LAST_GRAPH_BODY"
printf 'HTTP %s | total %ss | bytes %s\n' \
"$http_code" "$total_time" "$size_download"
if [[ $curl_status -ne 0 ]]; then
printf 'curl exit code: %s\n' "$curl_status"
fi
}
extract_first_image_id() {
local json="$1"
local marker='"id":"'
local remainder
if [[ "$json" != *"$marker"* ]]; then
return 1
fi
remainder="${json#*"$marker"}"
printf '%s' "${remainder%%\"*}"
}
run_direct_image() {
local image_id="$1"
print_separator
printf 'Direct image lookup\n'
printf 'GET https://graph.mapillary.com/%s\n' "$image_id"
printf ' fields=id,thumb_1024_url\n'
printf ' access_token=<redacted>\n\n'
curl \
--silent \
--show-error \
--get \
--connect-timeout 10 \
--max-time "$CURL_TIMEOUT" \
--data-urlencode 'fields=id,thumb_1024_url' \
--data-urlencode "access_token=${MAPILLARY_TOKEN}" \
--write-out $'\nHTTP %{http_code} | total %{time_total}s | bytes %{size_download}\n' \
"https://graph.mapillary.com/${image_id}"
local status=$?
if [[ $status -ne 0 ]]; then
printf 'curl exit code: %s\n' "$status"
fi
}
run_public_tile() {
print_separator
printf 'Public Mapillary vector tile\n'
printf 'GET https://tiles.mapillary.com/maps/vtp/%s/2/%s/%s/%s\n' \
"$TILE_SCHEMA" "$TILE_Z" "$TILE_X" "$TILE_Y"
printf ' access_token=<redacted>\n\n'
# The protobuf body is discarded so binary data is not printed to the terminal.
curl \
--silent \
--show-error \
--get \
--connect-timeout 10 \
--max-time "$CURL_TIMEOUT" \
--data-urlencode "access_token=${MAPILLARY_TOKEN}" \
--output /dev/null \
--write-out $'HTTP %{http_code} | total %{time_total}s | bytes %{size_download} | content-type %{content_type}\n' \
"https://tiles.mapillary.com/maps/vtp/${TILE_SCHEMA}/2/${TILE_Z}/${TILE_X}/${TILE_Y}"
local status=$?
if [[ $status -ne 0 ]]; then
printf 'curl exit code: %s\n' "$status"
fi
}
run_graph_images 'Small-bbox image search' "$SMALL_BBOX"
if [[ -z "$IMAGE_ID" ]]; then
IMAGE_ID="$(extract_first_image_id "$LAST_GRAPH_BODY")"
if [[ -n "$IMAGE_ID" ]]; then
printf 'Selected first image ID returned by the bbox search: %s\n' "$IMAGE_ID"
fi
fi
if [[ -n "$IMAGE_ID" ]]; then
run_direct_image "$IMAGE_ID"
else
print_separator
printf '%s\n' 'Direct image lookup skipped: the bbox response contained no image ID.'
fi
run_public_tile
if [[ "$INCLUDE_LARGE_BBOX" == "1" ]]; then
run_graph_images 'Large-bbox diagnostic (currently takes about 30 seconds)' "$LARGE_BBOX"
fi
print_separator
printf '%s\n' 'Done.'
I was using it for testing, so it’s not production code that someone validated, but it looks pretty simple.
Be sure to run this before running it (in the same terminal):
export MAPILLARY_TOKEN='YOUR_TOKEN'
then save the shared script content to some file (e.g. scipt_file.sh or whatever works for you).
then (or whatever you prefer in order to run it) chmod +x scipt_file.sh
and then just ./scipt_file.sh
This will reduce the chance of us trying different things.
Let me know how it went, or if that doesn’t work for you to run it, and let’s figure out another way.
__
BR, Yaro
Thanks, Yaro.
I created a fresh app with READ only on the same account, and it works: image lookup by id and small bbox searches return data. My original app (30592537330350355) still gets {“data”:[]} for bbox searches and code 100 / subcode 33 for any image id, although its token is valid (a wrong token gets code 190). So something about that specific app blocks entity reads. I’ve switched to the new app and it works now.
I am happy it works; at the same time, I have no idea why it didn’t work before
I might dig it up a bit later, out of curiosity, but at least for now you are not blocked.
__
BR, Yaro
Same issue here. New app registered on 2026-10-29, Client ID 28793508383638787, READ scope only (I also tried a second fresh app with the same result). The token is valid: vector tiles return data (13k+ images in the z14 tile over the Eiffel Tower), but /images?bbox=2.29,48.85,2.30,48.86&fields=id returns {"data":[]}, and GET /781464177166885?fields=id (an id taken from those tiles) returns code 100 / subcode 33. Any idea what blocks entity reads for this app?
Thanks for the details. We reproduced this: in the developer dashboard, both Client token and Client secret copy as MLY||…. Only the Client token works for the Graph API. The Client secret is accepted (so tiles work), but it can’t see any images, which gives exactly the empty results and error 100/33 you’re seeing.
Please click View in the Client token column and copy the value shown as Access Token (fully visible, not *****).
Separately, very large bounding boxes over dense cities can currently time out with a 500. Until we fix that, please use smaller boxes, for example about 0.01° × 0.01°.
Since this secret is now in the chat log, reset it in the dashboard if the app matters.
Oh, sorry @yung.sun.xxi , I missed the part “still gets {“data”:[]}”, I saw “and it works” and my brain probably turned off.
Thanks @caglarpmeta for checking.
__
BR, Yaro