Skip to content

Using the HTTP API

By default, your Panoramax HTTP API is available on localhost:5000.

The HTTP API allows you to access to collections (sequences), items (pictures) and their metadata. Panoramax API is following the STAC API specification, which is based on OGC API and a widely-used standard for geospatial imagery. More info about STAC is available online.

OpenAPI

API routes are documented is the OpenAPI section, and you can check your instance Swagger documentation in the route /api/docs/swagger (like this for the IGN instance).

🔐 Authentication

If activated at the Panoramax's instance level, some routes might need authentication.

OAuth flow

The main way to authenticate on the API is based on OAuth 2.0.

The authentication is asked to the configured instance's OAuth provider and stored in a session cookie.

The routes that need authentication should redirect to the /api/auth/login route if no session cookie is set.

A logout from the instance can be done via the /api/auth/logout route.

Bearer token

Protected routes can also be accessed with a JWT Bearer token.

Those tokens are needed when using the API without a browser, for example when doing regular curl calls or with our command-line client.

The JWT token should be given to the API via the Authorization header as a bearer token.

Considering your Panoramax server is https://my-panoramax.fr/, you can do:

curl https://my-panoramax.fr/api/users/me --header "Authorization: Bearer <A_JWT_TOKEN>"

And with httpie (at least httpie 3.0.0 is needed):

http -A bearer -a <A_JWT_TOKEN> https://my-panoramax.fr/api/users/me

How to get a token

Via an OAuth logged call

To get a JWT token, a regular user need to use a browser and call /api/users/me/tokens.

This will trigger an OAuth dance, and if the OAuth provider validates the user's credentials, this will return a list of Panoramax tokens like:

[
  {
    "description": "default token",
    "generated_at": "2023-05-11T15:56:59.410095+00:00",
    "id": "e11c255c-6023-4eee-bb47-31566f4ce65f",
    "links": [
      {
        "href": "https://my-panoramax.fr/api/users/me/tokens/e11c255c-6023-4eee-bb47-31566f4ce65f",
        "rel": "self",
        "type": "application/json"
      }
    ]
  }
]

A Panoramax token can be converted to a JWT token by calling (also in a browser, since an authenticated session cookie is needed):

api/users/me/tokens/:id with the ID of a token.

This will return a json with a jwt_token field which is the token needed as Bearer token.

An example result would be:

{
  "description": "default token",
  "generated_at": "2023-05-11T15:56:59.410095+00:00",
  "id": "e11c255c-6023-4eee-bb47-31566f4ce65f",
  "jwt_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnZW92aXNpbyIsInN1YiI6ImUxMWMyNTVjLTYwMjMtNGVlZS1iYjQ3LTMxNTY2ZjRjZTY1ZiJ9.vGJz-AgFgP4T5pZqGVK49-HcZXvOeFZm3EEIYrAJ44M"
}

With this example, accessing a protected route with this jwt token could be done with:

Considering your Panoramax server is https://my-panoramax.fr/, you can do:

curl https://my-panoramax.fr/api/users/me --header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnZW92aXNpbyIsInN1YiI6ImUxMWMyNTVjLTYwMjMtNGVlZS1iYjQ3LTMxNTY2ZjRjZTY1ZiJ9.vGJz-AgFgP4T5pZqGVK49-HcZXvOeFZm3EEIYrAJ44M"

And with httpie (at least httpie 3.0.0 is needed):

http -A bearer -a eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnZW92aXNpbyIsInN1YiI6ImUxMWMyNTVjLTYwMjMtNGVlZS1iYjQ3LTMxNTY2ZjRjZTY1ZiJ9.vGJz-AgFgP4T5pZqGVK49-HcZXvOeFZm3EEIYrAJ44M https://my-panoramax.fr/api/users/me
Via pregenerated token

Tokens can be fearsome, but Panoramax support a nicer way to generate them.

A token not associated to any account can be generated with a POST on /api/auth/tokens/generate:

Considering your Panoramax server is https://my-panoramax.fr/, you can do:

curl -X POST https://my-panoramax.fr/api/auth/tokens/generate

And with httpie (at least httpie 3.0.0 is needed):

http POST https://my-panoramax.fr/api/auth/tokens/generate

This will return a new token, with its JWT counterpart like:

{
  "description": "",
  "generated_at": "2023-05-23T15:58:26.645393+00:00",
  "id": "ee649235-bf10-4b04-a09a-64b1663af6f8",
  "jwt_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnZW92aXNpbyIsInN1YiI6ImVlNjQ5MjM1LWJmMTAtNGIwNC1hMDlhLTY0YjE2NjNhZjZmOCJ9.MoZYN9gsqiCQL3GrN2k6fZ21msrxFFtAZSEA3ClkKc0",
  "links": [
    {
      "href": "https://my-panoramax.fr/api/auth/tokens/ee649235-bf10-4b04-a09a-64b1663af6f8/claim",
      "rel": "claim",
      "type": "application/json"
    }
  ]
}

This JWT token can be saved somewhere, but will not be usable until an account is associated with it.

An account can be associated with it by opening in a browser the claim url in the links section. (the url https://my-panoramax.fr/api/auth/tokens/ee649235-bf10-4b04-a09a-64b1663af6f8/claim in the example below).

Opening the URL will trigger an OAuth dance in the browser, and if the user is successfully logged in, the token will be associated to its account.

Panoramax CLI uses this mechanism to hide token complexity to the users.

JWT token for the instance administrator

An instance administrator can get the JWT token of the default instance's account with the flask command default-account-tokens get, see the administrating section for more details.

Warning

Be sure not to share this token!

Revoking a token

A token can be revoked (definitely deleted) by calling a DELETE on /api/users/me/tokens/<uuid:token_id>

This calls needs to be logged, another token (or even the same one) can be used.

curl -XDELETE https://my-panoramax.fr/api/users/me/tokens/ee649235-bf10-4b04-a09a-64b1663af6f8 --header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnZW92aXNpbyIsInN1YiI6ImVlNjQ5MjM1LWJmMTAtNGIwNC1hMDlhLTY0YjE2NjNhZjZmOCJ9.MoZYN9gsqiCQL3GrN2k6fZ21msrxFFtAZSEA3ClkKc0"
http  -A bearer -a eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnZW92aXNpbyIsInN1YiI6ImVlNjQ5MjM1LWJmMTAtNGIwNC1hMDlhLTY0YjE2NjN DELETE https://my-panoramax.fr/api/users/me/tokens/ee649235-bf10-4b04-a09a-64b1663af6f8

Upload

Panoramax also offers API routes to upload pictures. Many ways are available to work with upload API, like using the command-line client or through any instance website.

You can also use a third-party tool to work directly with HTTP requests. Upload should go through different steps.

You can go through these steps with the following cURL bash commands (considering your Panoramax server is https://my-panoramax.fr/):

Note

Most instances require an authentication for uploading pictures, check the 🔐 Authentication section to know how to pass an authentication token

1. 📁 Upload set creation

Create an 📁 upload set (a batch of uploaded pictures) with POST /api/upload_sets. It will give you back an upload set ID that you will need for next steps. If possible, set the number of files that will be sent on this upload set.

curl -X POST https://my-panoramax.fr/api/upload_sets -d '{"title": "some title", "estimated_nb_files": 2}' --header "Content-Type: application/json"
http https://my-panoramax.fr/api/upload_sets title="some title" estimated_nb_files=2

Note

Check the API documentation to discover all the parameters that can be given to the upload set creation.

They might be used to control the dispatch into collections, the pictures deduplication and sorting, ...

You will have in both Location HTTP response header and in JSON response body the upload set ID. We consider below upload set ID 🪪 is 60d94628-8098-42cc-b684-ffb9aa9d35a7

2. Upload pictures

Upload as many pictures as wanted with POST /api/upload_sets/<UPLOAD_SET ID>/items. A JPEG image file is needed.

curl -X POST https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7/files -F file=@my_picture_001.jpg
http https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7/files --form file@my_picture_001.jpg

Send as many pictures as specified in the provided estimated_nb_files.

Note

Invalid pictures with for example bad metadata will be rejected but still counted as a received file, so the whole process will still be completed, even if some pictures were rejected.

If the number of files cannot be known in advance or if something came up and all the files cannot be sent, the upload set needs to be completed in order for the pictures to be publicly available.

curl -X POST https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7/complete
http POST https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7/complete

Note

The names of the files should be unique in the upload, so a client can send a picture again after changing its metadata.

3. ⏲️ Wait while checking for processing status

The pictures need to be prepared (blurred and derivates needs to be generated) and when everything has been received the pictures are dispatched to one or more collections and useless pictures like when stopped at a traffic light are detected and deleted.

This is done asynchronously, so the waiting time can depend on the server load.

You can check status using GET /api/upload_sets/<UPLOAD_SET ID> to see the progress made on process.

curl https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7
http https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7

The field items_status will tell you the status of each item in the upload set and its associated collections.

The field ready is an easy way to check if all the collections have been created and all the pictures are ready to be served.

Info

The dispatch step done on API consist in creating as many collections as needed based on your upload set. A collection is a continuous sequence of pictures, within a certain time and distance range. So if two pictures are too distant or taken after too much time, a new collection is created.

Status of each received files

You can check the status of each received files.

curl https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7/files
http https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7/files

This is especially useful if you want to check if a picture was rejected, or if it has been detected as a capture duplicate (like for example if several pictures were taken when stopping at a traffic light). In those cases, the file will have a rejected field with the reason.

This call can also help if a client needs to know if it has sent everything it meant to.

4. 📸 Enjoy you pictures

Enjoy your brand-new uploaded pictures by browsing the map or querying the associated collections with GET /api/upload_sets/<UPLOAD_SET ID> !

curl https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7
http https://my-panoramax.fr/api/upload_sets/60d94628-8098-42cc-b684-ffb9aa9d35a7