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"}}

2 Answers 2


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, 2019 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, 2019 at 5:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .