One very likely possibility is that the webroot for api.example.com is different from the webroot for example.com. In that case, you can specify a different webroot for each domain name by preceding the -d with a corresponding -w (where -w is simply the short form for --webroot-path).
@schoen My webroot for api.example.com is public as you can see from the nginx config. I tried the test.txt solution. I see the file from example.com but not from api.example.com. If I go to api.example.com, I get the Can’t establish secure connection error.
Sure, I didn’t quite understand what you meant by “public”. Is that the name of a directory?
For each -d, you can add a -w before giving a path where files for that particular domain name can be placed. It is supposed to be the top level (“web root”) for content on that domain.
@MaeseppTarvo, it should be impossible to get TLS-SNI-01 errors when using --webroot. The webroot authenticator should never trigger the certificate authority to attempt to use this method of validating your control of a domain name. So that’s the first time I’ve ever seen that error in this context. (edit: note that you got a very different error before, related to HTTP-01, as I would expect)
Is it possible that you have some kind of shell alias for certbot or have created an /etc/letsencrypt/cli.ini file?
If not, could you please post the log files from /var/log/letsencrypt? You can change your domain to example.com there if you want (although notice that you’ve left an instance of it in the error message above).
This log is somehow showing that you ran certbot --nginx rather than certbot certonly --webroot -w /var/www/example.com/html/ -d www.example.com -d example.com -w /var/www/example.com/api/public -d api.example.com. Do you remember using this form somehow? There’s no record in this log that you used --webroot.