API tutorial

Ratings

You can read a rating for a location by sending a GET request to the /places/{longitude},{latitude}/ratings endpoint:

πŸ‰$ curl https://api.geosci.de/places/13.176931,52.470632/ratings \
      --header "Authorization: Apikey $API_KEY" | jq .

You can pass the api key as either header parameter, or as a query parameter, like so:

πŸ‡$ curl https://api.geosci.de/places/13.176931,52.470632/ratings?api_key=$API_KEY | jq .

Both calls πŸ‰&πŸ‡ will read all available ratings. You can also directly read a rating by using its name:

πŸ‹$ curl https://api.geosci.de/places/13.176931,52.470632/ratings/shopping \
      --header "Authorization: Apikey $API_KEY" | jq .

The πŸ‹ call will be quicker, as only the requested rating will be returned.

If you need more than one, but specific ratings, you can also list them:

🍊$ curl https://api.geosci.de/places/13.176931,52.470632/ratings?r=shopping,health \
      --header "Authorization: Apikey $API_KEY" | jq .

Which ratings are available at the API? You can find out by heading to https://api.geosci.de/docs/ratings?api_key=$API_KEY. It will render a list of all available ratings with some explanations.

Did you see that some ratings have a score of null? Those are the ratings that are not yet available for the queried location, for example because we have not yet collected enough data to return a meaningful score.

You can also query another travel mode like so:

🚲$ curl https://api.geosci.de/places/13.176931,52.470632/ratings?travel_mode=bike \
      --header "Authorization: Apikey $API_KEY" | jq .
πŸ‘£$ curl https://api.geosci.de/places/13.176931,52.470632/ratings?travel_mode=foot \
      --header "Authorization: Apikey $API_KEY" | jq .
πŸš—$ curl https://api.geosci.de/places/13.176931,52.470632/ratings?travel_mode=car \
      --header "Authorization: Apikey $API_KEY" | jq .

Places

By the way: You can find all the places you queried by calling the /places endpoint:

🍍$ curl https://api.geosci.de/places \
      --header "Authorization: Apikey $API_KEY" | jq .

Places are the locations where you can read ratings for, or generate texts about. For the ratings API, we create places for you automatically when you query a rating, to make the API simpler to use.

However, sometimes you want to query not a single place but an area (e.g. for texts requests), and for those cases you need to create places manually, like so:

🍐$ curl -X POST https://api.geosci.de/places \
      --header "Authorization: Apikey $API_KEY" \
      --header "Content-Type: application/json" \
      --data '{"geometry":{"type":"Polygon","coordinates":[[[13.21339186805244,52.490231162547644],[13.212210100971475,52.49279853353829],[13.207479958131557,52.49378990882633],[13.20037433730073,52.4900500681037],[13.204589271966228,52.48451035272657],[13.213377815096834,52.47804916559801],[13.225222834332925,52.48464108820184],[13.228403860222244,52.489951633847085],[13.224851637590547,52.49414253527897],[13.216869269180336,52.49360944432422],[13.21339186805244,52.490231162547644]]]},"metadata":{"name":"A polygon place!"}}' \
       | jq .

As you can see, you may also add metadata to the place that can help you identify it later on. metadata is a free-form object that can contain any key-value pairs you like.

To create places for a single location, you can also use this quickshot endpoint where you can create a place without metadata (no request body required!):

🍎$ curl -X POST https://api.geosci.de/places/13.31103,52.51570 \
      --header "Authorization: Apikey $API_KEY" | jq .

This is required for the text APIs, which we will cover next.

Texts

Our text APIs create various texts that describe a place or an entire area, such as a neighborhood or city. Because many of them are based on areas and not points, you need to create the place in the API before you can generate the text. You can do using the same quickshot endpoint as for the places (see 🍎). This request will return an ID which you can use to generate the text:

πŸ₯¦$ curl -L -X POST https://api.geosci.de/places/12345/texts/area-descriptions?wait=true \
      --header "Authorization: Apikey $API_KEY" \
      --header "Content-Type: application/json" \
      --data '{"languages":["en","de"],"parameters":{"name":"Berlin-Charlottenburg","geo_level":"neighborhood"}}'
      | jq .

which responds with

{
  "result": {
    "de": "# Berlin-Charlottenburg\n\nBerlin-Charlottenburg\n\n## EinfΓΌhrung\n\nBerlin-Charlottenburg ist ein lebendiger Stadtteil im Herzen Berlins, [...]",
    "en": "# Berlin-Charlottenburg\n\nBerlin-Charlottenburg\n\n## Introduction\n\nBerlin-Charlottenburg is a vibrant suburb located in the heart of Berlin, [...]"
  },
  "attribution": [
    {
      "name": "OSM",
      "license": "https://opendatacommons.org/licenses/odbl/1-0/"
    }
  ],
  "metadata": {
    "explanations": [
      {
        "name": "lagecheck",
        "url": "https://lagecheck.com/check?lat=52.5157&lon=13.31103&address=Berlin-Charlottenburg"
      }
    ]
  }
}

If you paid close attention, you might have noticed that you have been redirected by the POST to GET your response at https://api.geosci.de/places/12345/texts/area-descriptions/689749854432784384?wait=true.

LLMs take time to generate a response. While it is really convenient to get the answer directly in the response, it comes with the challenges that long-running network calls have:

  • potential timeouts

  • network connectivity losses

  • retries on POST requests would do the work twice (and produce twice the cost)

With the above redirect, you are free to retry the GET call in case you get a timeout or other network errors.

Also, if you prefer to treat the text generation asynchronously (e.g. because you want to create hundreds of texts in one go), you can do so by skipping the wait=true entirely. In this case, the API will answer with:

HTTP/1.1 202 Accepted
Location: https://api.geosci.de/places/123456/texts/area-descriptions/689749854432784384
content-length: 0
Retry-After: 30

You can poll the endpoint returned in Location. It will respond with 200 OK (see πŸ₯¦ response) when the text is ready and with 202 ACCEPTED when it still is in progress.

Our other text APIs work similarly, they might just require different parameters (documented in their API endpoint documentation).

Have fun - and let us know if you need any help 😊!