Collections · GET /v1/collections/{id}/stream
Live progress
Watch a collection fill up over one open connection: places as they arrive, how far it got, and the final counts.
Open the stream
The stream uses server-sent events: one HTTP response that stays open, and we write a short text event to it each time something happens. It takes your key like any other call, and it's free. With curl, -N prints each event as it comes instead of waiting for the end:
curl -N https://api.gmaps.dev/v1/collections/8c1f5e2a-7b3d-4f60-9e14-2a6d0b9c7f31/stream \
-H "Authorization: Bearer $GMAPS_API_KEY"What arrives
Each event has an event line with its type, a data line with JSON, and most have an id line. A small collection looks like this, with the place cut short:
event: plan
data: {"squaresTotal":3,"squaresCovered":1,"jobsTotal":2}
id: 1
event: status
data: {"status":"running"}
id: 2
event: place
data: {"place":{"id":"5b0c8e0a-2f4d-4c1e-9a57-3d2b8f6e1c90","identity":{"name":"Padaria Estrela do Centro"}},"cached":false,"cost":1}
id: 3
event: progress
data: {"jobsDone":1,"jobsTotal":2,"counts":{"placesDelivered":13,"placesFresh":1,"placesCached":12,"creditsCharged":1,"creditsRefunded":0}}
id: 4
event: heartbeat
data: {}
event: progress
data: {"jobsDone":2,"jobsTotal":2,"counts":{"placesDelivered":13,"placesFresh":1,"placesCached":12,"creditsCharged":1,"creditsRefunded":0}}
id: 5
event: done
data: {"status":"succeeded","counts":{"placesDelivered":13,"placesFresh":1,"placesCached":12,"creditsCharged":1,"creditsRefunded":0}}
id: 6| event | data | When it comes |
|---|---|---|
plan | squaresTotal, squaresCovered, jobsTotal | First. How the area was split up: the same numbers the collection has. |
status | status | Once, when the first search starts. |
place | place, cached, cost | Each time a place arrives. cost is what it cost you: 0 when we already had it, 1 for a new place, and 2 when we also found an email for it. |
progress | jobsDone, jobsTotal, counts | After each batch of squares, with the collection's counts so far. |
done | status, counts | Last. The collection ended, with its final status and counts. The stream closes right after it. |
heartbeat | Nothing | About every 15 seconds, so a quiet connection isn't closed along the way. It has no id. Skip it. |
error | code, message | Something broke on our side while the stream was open. The stream closes right after it: connect again from your last id. |
notice | messageKey, params | Set aside for a note about the collection. We don't send it yet. |
Skip any event type you don't know, so a new one never breaks your code.
Not every place comes as an event. The places we already had when the collection started are in it from the first moment, so they never arrive here. A place whose business asked us to leave it out never arrives either. A large collection also stops sending place events after a set number of places, while its progress events keep counting. When it ends, read every place from the collection itself, as Collections shows.
Pick up where you left off
We keep every event that has an id. If the connection drops, connect again with the last id you read in a Last-Event-ID header, and you get only the events after it. If a header is hard to send, ?lastEventId= in the address works too. Without either, you get every event from the start, so connecting late misses nothing:
curl -N https://api.gmaps.dev/v1/collections/8c1f5e2a-7b3d-4f60-9e14-2a6d0b9c7f31/stream \
-H "Authorization: Bearer $GMAPS_API_KEY" \
-H "Last-Event-ID: 4"The SDK does this for you. When the connection drops, it connects again from the last event it gave you. Pass lastEventId to start after an event you already have, and a signal to stop watching.
After maxRetries drops, it gives up and throws a GmapsError. retryMs sets how long it waits between tries. A refusal, like a wrong key or someone else's collection, throws right away.
When it ends
After done, the stream closes. There's nothing more to watch.
We also close a stream after 15 minutes, even if the collection is still running. That's not an error: connect again with your last id.
If the collection had already ended when you connect, you get its events up to done at once, and then the stream closes. Once its places are deleted, 30 days after it started, you get a single done event with the final counts.
If the stream can't open, you get a plain JSON error instead: 404 COLLECTION_NOT_FOUND for an id that's wrong or belongs to another account, 401 UNAUTHORIZED when the key is missing, and 401 INVALID_TOKEN when it's wrong or revoked. Errors lists them all.
Other ways to follow a collection
You don't always want a connection held open. You can also:
- read the collection at
GET /v1/collections/{id}every so often. Itsstatusandcountssay what the events say, and nothing has to stay open. - use a webhook: on a paid plan, we send your server a request when a collection ends, unless you cancelled it.