Skip to content

Bash (Linux/macOS/WSL)

If you want to use bash instead of any of the above introduced connectors, you can choose any language, which allows to send HTTP requests. Using bash or Powershell you can use wget for example. Before getting started, one last recommendation: While it is possible to run the commands inline, we recommend you to paste them one-by-one into a shell script! This will facilitate all future requests and furthermore make debugging much easier. Furthermore, some of the operations are time critical. When embedded in a script, you do not have to worry about that. If you prefer reading to writing yourself, the code that is to be created in this tutorial can also be found here.


To be able to use OKAPI, you have to authenticate. We use services from Auth0 for that. Therefore, before being able to send any requests to our server, you have to get a token from Auth0. This token is received by sending a HTTP POST request to Auth0. As every HTTP request, it contains a header, and a body. When using wget, it is most easy to send the body as a file. Depending on the programming language you will work with in the future, you can use build-in data types for that (for example structs in Matlab, or dicts and lists in Python). The body file to send an authentication request to Auth0 looks as follows:

    "username": "your-username",
    "password": "your-password",
    "audience": "",
    "client_id": "jrk0ZTrTuApxUstXcXdu9r71IX5IeKD3",
    "scope": "scopes-are-ignored-for-now"
Create a file like this using an editor of your choice and save it (for example under the name authentication_request.json). Insert your password and email address. For the scope you can currently put any string, but make sure that you do not omit that field. Now, you are ready to send the request to the server:

wget --server-response --quiet --body-file=authentication_request.json --output-document=token.json --header="content-type: application/json" --method=POST

You see that the request is split into the body (make sure to use your filename) and the header. In the header you only need to define the content-type. Furthermore, you tell wget where to save the output. As we want to use the token afterwards, it makes sense to save it to a file (for example token.json). Now execute the command and inspect the response. It should contain the statement HTTP/1.1 200 OK. The token that is returned should look like the following:

    "access_token": "very_long_string_with_token",
    "scope": "string_with_your_scopes",
    "expires_in": 86400,
    "token_type": "Bearer"
Important in here are the scope and expires_in fields: In the first, all the endpoints you have access to are defined. If you have requested the Demo account, you have full access to all available endpoints for a duration of 30 days. After that, the endpoints depend on your plan. The Free plan will give you access to every endpoint necessary in this tutorial. The second field tells you how long the token is valid in seconds. Current standard is 86400 seconds ( = 1 day). After that, you would have to get the token again. If you are using OKAPI frequently, you could just create a recurring job (for example using cronjob), which refreshes your token automatically once per day.

Sending a request

Now you have finished the authentication, so you are ready to send your first request. Using wget, the command looks as follows:

ACCESS_TOKEN_VALUE=`cat token.json | jq --raw-output .access_token`

wget --content-on-error \
     --output-document=request_response.json \
     --body-file=pass_prediction_request.json \
     --header="Content-Type: application/json" \
     --header="Accept: application/json" \
     --header="Authorization: Bearer ${ACCESS_TOKEN_VALUE}" \
     --method=POST \

sleep 3

The first line in there is a „short-cut“, to get the token from the token.json file. For this, you read the content from that file, pipe it to the jq programm which returns the content of the field access_token into the variable ACCESS_TOKEN_VARIABLE. Note the „ around the command! The second line is the actual request. It is very similar to the command to retrieve the access token: Again, you define a body (given as a file, we address this in a bit) and the header. This time, the header needs to know the content-type and the accept value. Furthermore, you include the access token, which is why we copied it into the variable (if you are unable to use jq, you have to copy-paste the value of the access token into the request). This time, instead of using the GET method we use POST. The request is sent to the OKAPI service, using the endpoint for pass prediction requests. Also as before, the response from the server is written to an output file, which we call request_response.json. The sleep is included in the command to give the server a moment to process the request before you continue (which is important during the next step).

Now, the last thing that is needed is to provide input on the pass prediction you actually want to perform. In the command stated above, the request is defined in the file pass_prediction_request.json and looks as follows:

    "orbit": {
        "type": "tle.txt",
        "content": "1 25544U 98067A   18218.76369510  .00001449  00000-0  29472-4 0  9993\n2 25544  51.6423 126.6422 0005481  33.3092  62.9075 15.53806849126382"
    "ground_location": {
        "type": "ground_loc.json",
        "content" :{
        "type": "tw.json",
        "content": {

Note that the two lines of the TLE are merged into one and the line break is expressed as \n. You have to keep the format exactly as described above. The location of the ground station is given in WGS-84 coordinates. Longitude and latitude are given in degree, the altitude in km. The service will return all passes of the satellite during the defined time window. Submit a TLE string that is close to the time window defined (maximum a couple of days old). The older the TLE, the less accurate the results that are returned.

Now, execute the command. It should send the message, and the server returns a HTTP/1.1 202 Accepted, if everything went well. If you get a http code 401, something was wrong with your authentication. If you get a timeout, you either misspelled the server’s address, or our server is down. If you get a 500, most probable your request contained some wrong format. In that case (and in all other cases), check out the response. A good response looks like this:

    "request_id": "87e3a5ab-e1f0-4387-8416-c90a8f2675b0",
    "status": {
        "type": "REMARK",
        "text": "Service request has been submitted successfully"

Most important is the request_id. Use this value to retrieve the result from your computation. In the state message, you will get some further information if the request was not accepted.

Receiving the result

You have now sent the first request, now it is time to collect the response. Your request needs a certain time for processing. For the pass prediction, it is generally less than a second, but give the server some time. If you asked for a response too soon, the server will return a 202 instead of 200, which means that the results are being processed now. The results you receive are incomplete. You can use sleep 2 for the bash to wait for 2 seconds.

The command to retrieve the results is:

request_id=`cat request_response.json | jq '.request_id' | sed -e 's/^"//' -e 's/"$//'`
wget --content-on-error \
     --output-document=pass_prediction_result.json \
     --header="Authorization: Bearer ${ACCESS_TOKEN_VALUE}" \${request_id}/summary

The first line is again a shortcut to read the request_id from the server response of the request and strip the quotes from the request_id. If you have no access to jq, you can also just copy the number from that file. Same is valid for the access token, which is assumed to be contained in the same variable as for the request sent before. You can directly execute this command. You should receive a HTTP/1.1 200 OK from the server. This means, all went well. Possible other responses are:

  • 202: It indicates that the results are being processed now and the received content is not complete yet.
  • 404: In this case either no pass was calculated because the satellite is not seen from the groundstation during the time window (this will be changed soon), or your request has not been processed yet.
  • 422: Unprocessible entity. Here, something was wrong with your request, which could not be detected by the API directly. Most probable, there is a defect in the TLE string. Check our the response, there should be more information available in the state message.

If everything went fine, look at your pass_prediction_result.json file. It contains a summary of all passes of the object during the specified time interval. For a more readable version of the result, use cat pass_prediction_results.json | jq . in your terminal.