WebApp AI Fetch Issue - Looking for help

I am creating a WebApp for school, utilizing Mapillary’s graph API calls:

const res = await fetch(
`https://graph.mapillary.com/images?` +
`access_token=${token}` +
`&fields=id,geometry,is_pano` +
`&limit=1` +
`&bbox=${minLon},${minLat},${maxLon},${maxLat}` +
`&is_pano=true` );

Right now, I hold a cache of just 5 images and location data. Just two days ago this method was working flawlessly, and using this json: country-bounding-boxes/bounding-boxes.json at master · sandstrom/country-bounding-boxes · GitHub , I was able to fetch 5 images “randomly” within the bounding boxes. Seems like there was just a shadow update, or the API is down? Whenever I run my webapp to debug, I get status: 500 and the err: “Bounding box area is too large. Maximum allowed area is 0.001 square degrees, but got 143.560 square degrees”. Is there a changelog available for this update? I’m not really sure how to deal with this, as the assignment is due tomorrow, so it’s pretty bad timing lol. Any suggestions? I could try constraining the boxes, but that would most likely fail as they would be too specific to grab any data in such a small space.

Edit:

More details for now -

I am using bounding boxes determined by a bbox JSON to randomly select a country to pull image data from. Once a country is determined, random images are then called from within that bbox through an api call to fetch the number of images required to fill a round queue (currently 5). Previously, the requirement for how large this box could be was seemingly much larger. However, I am assuming this update that presumably dropped some time this past weekend constrains that requirement from somewhere > 100 to <= 0.001 square degrees, which on the surface is something like ~5 square miles or (13 sq km). This means that for rural countries or countries with lower image coverage, it is much more difficult to pull a variety of images given a large country bbox. Am I misunderstanding the current situation? I cannot find an easy fix for this update other than some kind of systematic search.

cc: @knikel

Would switching to tiles be better?

For fetching lots of data or data across a wide area, we’d recommend using Mapillary vector tiles as they’re lightweight and fast.

For this use case, you could convert the bounding box to tile x/y/z coordinates and use Mapillary coverage tiles: https://www.mapillary.com/developer/api-documentation#coverage-tiles

Thanks I will try and implement that. Could I also please ask you to confirm whether the bbox area constraint was a recent change? I need that to get an extension and prove that a vector tile version change is required.

Yes, this was a recent change. We made some updates to how we retrieve image data as part of the API and this includes limiting the maximum requested area.

1 Like

There are two things that happened

  1. Implementation bug when handling bounding boxes
  2. We added a size constraint to the bbox (the area shouldn’t be larger than 0.01 square degree)

We had to finally introduce the bbox limit due to breaking changes in our internal indexing services (We have to index around 2.7B images spatially). The current limits are not perfect but seem reasonable. We’ll update the documentation accordingly. Apologies for the issues.

Edited the post to reflect the current value bbox size constraint.

1 Like

You mean square degrees? However the error message says 0.001 square degrees?

Anyway, I am not amused.

1 Like

Yes, square degrees. The change is not fully rolled out yet, we’re still tweaking the parameters to find a good balance between the load and latencies. As it currently stands, 0.01 square degrees seems to be performing well. Future changes will be communicated better - it’s a mistake we own that we haven’t had that limit before and we’re only adding it now. I’ll post an update here once the changes are through and the documentation is updated.

1 Like

Hey everyone, the API changes last night. I’ve also updated the documentation about the bbox size limits, the latest verion is in this section: https://www.mapillary.com/developer/api-documentation#image

What is still not working great is handling very small bounding boxes (e.g. 15x15m).
To shed more light, behind the scenes the indexing works on S2 cell level 17 and we’re using bounding box to S2 cell union algorithm.

If there is an interest, we could potentially expose s2_tokens parameter of type vec[string]limited to e.g. 100 tokens per request. We could do that for /images and /map_features endpoints. WDYT?

1 Like

For my api use case, I’m not entirely sure if that would be a significant fix. My current implementation is a tile/graph hybrid. Pick a random point within country bboxes → fetch coverage tile and parse for coverage data with pbf and vectortilejs → extract seq id → query graph using seq id → get img for viewer. Tile fetch to api call is much more complex than the previous bbox solution and doesn’t work nearly as well, but I think S2 wouldn’t make much of a change, as I’m trying to search for any random image data, but S2 would likely only improve precision. If you think there’s a better implementation, let me know, but this is all I came up with so far.

1 Like

Same here, could we at least increase the limit to 0.017 (zoom 10 tile equivalent) ?

Also I’ve switched to download zoom 11 tile equivalent tile, using graph API, but I’m now getting b’{“error”:{“code”:1,“message”:“An unknown error occurred”,“error_subcode”:99}}' message :woman_tipping_hand:

URL: https://graph.mapillary.com/map_features?access_token=MLY|xxx|xxx&fields=geometry,images&bbox=14.1301,54.77534585936448,14.23828125,54.8353&object_values=information--pedestrians-crossing--g1,information--trail-crossing--g2&start_last_seen_at=2025-01-01T00:00:00Z&end_last_seen_at=2025-09-31T23:59:59Z

Retrying the same URL eventually downloads the data, but after few 30s timeouts, pretty unreliable.

@knikel are you able to chime in?

1 Like

I encountered a problem using the is_pano=true filter and the image limit after this latest update. @knikel

As you can see, one returns an empty array, and the other does return the content within that 5km x 5km radius, but with a 16-second response time.

graph.mapillary.com/images?access_token=XXX&fields=id,computed_geometry&is_pano=true&bbox=-15.6252,27.7186,-15.5745,27.7635&limit=1

vs

graph.mapillary.com/images?access_token=XXX&fields=id,computed_geometry&is_pano=true&bbox=-15.6252,27.7186,-15.5745,27.7635&limit=5000

On the other hand, I would like to mention that with other tests Making the radius similar to the limit value could optimize the response speed, but it would still be very slow and inaccurate, since what I need is to limit the images, not their equivalence to the search radius.

EX:

5km x 5km = 10-16 seconds Radius = 3.54km

graph.mapillary.com/images?access_token=XXX&fields=id,computed_geometry&is_pano=true&bbox=-15.6252,27.7186,-15.5745,27.7635&limit=500

I hope you can give me an answer soon, as this way I can’t get a maximum radius with a single 360 ​​image effectively.

Thanks for flagging these issues everyone! These increased latencies are related to deprecating the spatial indexing service we’ve been using behind these APIs.

Our current indexing solution is based on S2 cells and the increased latency correlates with how densely given area is covered with images. For example querying a 1km x 1km bbox in an area with 500 images will be faster than one with 5000. I’m collecting the stats on these latencies so we can fine tune how this works in the future.

@IreuN :

Same here, could we at least increase the limit to 0.017 (zoom 10 tile equivalent) ?

We’re not planning to increase limits soon, we’re not happy yet with stability of these APIs.

Also I’ve switched to download zoom 11 tile equivalent tile, using graph API, but I’m now getting b’{“error”:{“code”:1,“message”:“An unknown error occurred”,“error_subcode”:99}}’ message :woman_tipping_hand:

You’re already hitting the hard timeout of 30s, meaning there is a lot of data to query in the area you’re filtering for. I’d suggest splitting the bbox into e.g. 2 or 4 and making multiple requests with parts of that bbox. We’ll have improved error messages at some point too.

If you’re using Python, you might want to also take a look at GitHub - mapillary/mapillary-python-sdk: A Python 3 library built on the Mapillary API v4 to facilitate retrieving and working with Mapillary data. where APIs are based on vector tile parsing + Graph API filling in the missing metadata gaps. Perhaps that could work out of the box for you?

@cristiandavilatwd : The issue you’re facing is related to the chages in how we do spatial lookups. The latency is related to the amount of images in S2 cells overlapping with the bbox you’re querying. I’d suggest splitting the bbox and sending multiple requests for now. I agree, the latencies in “dense” areas are not great, I’ll see what we can do to improve them short term.

Regarding limits, keep in mind that max is 2000, with no pagination for these parameters.

We ackownledge that historically these (spatial) APIs are limited and we’d like to revise them at some point.

1 Like

@knikel may you look at this?

I’ve created this URL https://graph.mapillary.com/map_features?access_token=MLY|xxx|xxx&fields=geometry,images&bbox=18.52294921875,50.44351305245806,18.544921875,50.45750402042057&object_values=information--pedestrians-crossing--g1,information--trail-crossing--g2&start_last_seen_at=2025-06-01T00:00:00Z

The BBOX is like this (or at least I think so)

From vector API (https://tiles.mapillary.com/maps/vtp/mly_map_feature_traffic_sign/2/14/9035/5524?access_token=XXX I am getting these crossings:

0 = {dict: 4} {‘geometry’: {‘coordinates’: [414, 2201], ‘type’: ‘Point’}, ‘id’: 4, ‘properties’: {‘first_seen_at’: 1753169617394, ‘id’: 1883100132481784, ‘last_seen_at’: 1753172223389, ‘value’: ‘information–pedestrians-crossing–g1’}, ‘type’: ‘Feature’}
1 = {dict: 4} {‘geometry’: {‘coordinates’: [379, 2107], ‘type’: ‘Point’}, ‘id’: 6, ‘properties’: {‘first_seen_at’: 1753172189445, ‘id’: 3957877184465395, ‘last_seen_at’: 1753172189445, ‘value’: ‘information–pedestrians-crossing–g1’}, ‘type’: ‘Feature’}
2 = {dict: 4} {‘geometry’: {‘coordinates’: [469, 1996], ‘type’: ‘Point’}, ‘id’: 42, ‘properties’: {‘first_seen_at’: 1661698169673, ‘id’: 1106090519997466, ‘last_seen_at’: 1753169415391, ‘value’: ‘information–pedestrians-crossing–g1’}, ‘type’: ‘Feature’}

these are also shown via WebAPP:

Yet from the map_features API (first link in this post) I’m getting an empty list, could you help me to find out why?

{
   "data": [
      
   ]
}

EDIT: ah..

IMPORTANT: Querying map feature data with the bbox parameter is suitable for relatively small area (must be smaller than 0.01 degrees square).

Yes, that 500 error isn’t your fault; Mapillary just added the max bbox limit that you saw. What Nikola said is the fastest way to keep getting random images without going over that tiny 0.001 sq deg limit: switch to vector tiles. You can change your country bbox to tile x, y, and z and then pull coverage that way. It’s much faster and gets around the API bbox limit. For now, if you need a quick fix, you can just break up your big bbox into smaller pieces that are under the limit and request them one after the other. But tiles are the best long-term answer.