deploy image via API failing

Hey, I’m doing something wrong here.
I’m getting: errors: [services.0.checks.0.port: can’t be blank]
If I change tcp_checks to checks, the error disappears but I get no public IP.
I’ve already debugged via flyctl and compared the two. You’re sending the exact same data but mine is failing. Any pointers?

  "query": "mutation($input: DeployImageInput!) { deployImage(input: $input) { release { id version reason description deploymentStrategy user { id email name } createdAt } } }",
  "variables": {
    "input": {
      "appId": "appID",
      "image": "imageTag",
      "services": null,
      "definition": {
        "kill_signal": "SIGINT",
        "kill_timeout": 5,
        "services": [
            "internal_port": 443,
            "protocol": "tcp",
            "concurrency": {
              "soft_limit": 2000,
              "hard_limit": 2500
            "ports": [
                "port": "443",
                "handlers": [
            "tcp_checks": [
                "grace_period": "1s",
                "interval": "10s",
                "port": 443,
                "restart_limit": 5,
                "timeout": "2s"
      "strategy": null

I’m not sure it’ll help, but the check port is currently overwritten to the internal_port. So you don’t need/want it in the tcp_check definition. However, that shouldn’t trigger this error.

When you say you debugged with flyctl, do you mean you used the following?

LOG_LEVEL=debug flyctl deploy

That will output the exact POST call it made. For example:

DEBUG --> POST {{"query":"mutation($input: DeployImageInput!) {...

flyctl doesn’t have any special privileges. If it works with it, it should work for you too.

One of my main languages is Go, so I can run flyctl with a debugger attached by building it from source.
I figured out a solution using try and error.
It seems to be not allowed to change regions and/or VM size BEFORE the first deployment of the image.
The API lets you do the calls but then the app is somehow “broken”.
If you do the steps in the right order (create->deploy->setRegions->setScale) it works.

I made a few observations throughout the process.
If I add a new region, the app becomes unavailable for a few seconds. This should not happen.