I want to build an automated script which builds an new VPS Server on the page vultr.com. They also have an API Access and I could create it and receive also anything I need. The problem is, vultr sends an response with a number as the key of every VPS Server. I used this command to create the VPS and get the number of the server back:

idofserver=$(curl -H 'API-KEY: "HERE IS MY PRIVATE API KEY"' \
             https://api.vultr.com/v1/server/create \
            --data 'DCID=9' --data 'VPSPLANID=201' --data 'OSID=244' \
            | jq '."SUBID"' | /bin/sed 's/"//g')

And it also gives me back the number without the ". So the response in the command line looks like: 2342738. And the variable also got changed to the number. Because when I enter "echo $idofserver", I got the number 2342738 back.

After that line I do in a loop that command:

echo "VULRT IS WORKING ID: $idofserver"
response=$(curl -H 'API-KEY: "HERE IS MY PRIVATE API KEY"' \
           https://api.vultr.com/v1/server/list 100>/dev/null)
status=$(echo "$response" | jq '."$idofserver"' | jq '."status"')

It also returns "VULTR IS WORKING ID: 2342738". But it stays in a complete loop, because it doesn't change the variable $status to active. The while loop condition is: while [ $status != "active" ]; do

I tried it manually to echo the response and send it through jq with the commands from above $status. But there was the response: "null". I don't know why.

Here is how the JSON Response looks like from VULTR:

{"2342738":{"SUBID":"2342738","os":"Debian 9 x64 (stretch)","ram":"1024 MB","disk":"Virtual 25 GB","main_ip":"","vcpu_count":"1","location":"Frankfurt","DCID":"9","default_password":"=*{#?HHH*!-(","date_created":"2019-04-22 17:49:28","pending_charges":"0.01","status":"active","cost_per_month":"5.00","current_bandwidth_gb":0,"allowed_bandwidth_gb":"1000","netmask_v4":"","gateway_v4":"","power_status":"running","server_state":"installingbooting","VPSPLANID":"201","v6_main_ip":"","v6_network_size":"","v6_network":"","v6_networks":[],"label":"","internal_ip":"","kvm_url":"https:\/\/my.vultr.com\/subs\/vps\/novnc\/api.php?data=jhkjhjhkjhkj","auto_backups":"no","tag":"","OSID":"244","APPID":"0","FIREWALLGROUPID":"0"}}

First of all, use -r with jq to get the raw data back. Don't pass the output through sed:


serverid=$( curl -H "$key" "$url/create" \
                --data 'DCID=9' \
                --data 'VPSPLANID=201' \
                --data 'OSID=244' |
            jq -r '.SUBID' )

Then, the second call to jq won't work as you use single quotes around the expression, which stops the shell variable from expanding. However, that is not the way to pass a shell variable into jq.


printf 'VULRT IS WORKING ID: %s\n' "$serverid"

status=$( curl -s -H "$key" "$url/list" 100 |
          jq -r --arg id "$serverid" '.[$id].status' )

Using --arg id "$serverid" will create a jq variable whose value you can access through $id. To use this as a key, use [$id].

I've also taken the liberty to change a few other things in your code in accordance with my own personal preferences.

  • The --arg id worked for me. Thank you. And the -r is for filtering also the ". That i doesnt knowed. But maybe someone other need that also. Thank you too for answering – daniprog Apr 23 at 5:21

The issue is that '."$idofserver"' is single-quoted, so $idofserver is never expanded to its value - you're looking for a key literally called "$idofserver".

You also never need to pipe jq | jq. You can just join filters together in the jq program:


You can fix the quoting to get that result, but more reliably, pass the id in as a jq variable to be set and avoid internal quoting issues entirely:

jq --arg id "$idofserver" '.[$a].status'

I would suggest avoiding echo "$response" | jq as well if you can: either pipe directly, or use printf '%s' "$response" | jq or (best) jq <<<"$response" instead.

  • Thanks. But i cant pipe directly, because i need more than only 1 variable, and that would take my internet traffic down and my api requests from vultr also. But I dont show for security, it only should work. The Script i write is for my raspberry, that will handle to setup an server automatically, when the main server that stands at my friends house, goes down. I hope there isnt that much security needed :D. But for the next programmed scripts i will try the <<< command in my script. – daniprog Apr 23 at 5:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.