Every time someone asks me how to make their first LLM API call, I watch them hit the same wall. It is never the code.
The wall is setup. One tutorial says put the key in an environment variable, another says edit a config file, a third uses a command that doesn't exist on your machine. Three tabs, three incompatible mechanisms, and eventually a 401 that doesn't tell you which of the three lost. Nobody can debug that, because the error points at the credential while the actual problem is that three documents disagreed and the reader had no way to arbitrate.
So instead of pointing people at tutorials, I wrote down the route I use myself — then re-ran the whole thing end to end this week on my own machine, to be sure I wasn't handing out stale steps. Eleven minutes from minting a key to reading the token bill of a real call. Four steps, one CLI, no SDK.
Step 1: mint a key, and pick the region on purpose
Keys come from the console API key page. The part almost every write-up skips: the region matters.
Free quota on Alibaba Cloud Model Studio exists only in the China (Beijing) region, and keys are bound to a region. A key minted somewhere else doesn't throw an error, doesn't warn you, doesn't behave oddly — it authenticates fine and quietly bills you instead of drawing down free quota. I found this out the expensive way during my first week, which is why it's now step one of the route rather than a footnote.
Copy the key when it appears. It's shown in full exactly once.
Step 2: one install command
npm install -g bailian-cli
bl --version
Mine reports bl 1.27.0 today. Version numbers drift; the command signatures below have been stable across the releases I've used.
Step 3: the first call is a sentence, not a program
bl text chat --message "Introduce yourself in one sentence"
The first run asks for your API key. If you'd rather not paste it every time, store it once:
bl auth login --api-key sk-your-key
Then the model answers. My actual output this week:
I'm Qwen, a large language model developed by Alibaba Group, here to help you think, write, and solve problems.
That's the whole call. No client object, no request signing, no response parsing, no dependency pinned to a version that conflicts with the rest of your project. One sentence in, one sentence out. For a first contact with a model, that's the right amount of machinery: enough to prove the credential, the endpoint and the account all work, and nothing else in the way.
Step 4: the tier swap that doubles as an honesty test
The default model is the most capable tier in the catalog, and most everyday questions don't need it. One flag moves you down a tier:
bl text chat --model qwen3.8-flash --message "Is today a good day to go outside in Berlin? Two sentences."
What I like about the answer isn't the advice, it's the disclaimer:
I can't access real-time weather or air quality for Berlin today, so I can't judge reliably. If it's mild and clear, go out; if there's wind, rain or smog, keep it short or protect yourself.
No live data, and it says so, then gives you the conditional version. That's a useful first signal about whether a model fabricates. A hallucination-prone one would have cheerfully told me "sunny, 22°C, perfect day" and I'd have spent a week trusting it before noticing.
My working rule since then: drafts, summaries, classification and quick questions go to the flash tier; hard reasoning and code go back to the default tier. Same key, same command, one flag — which means the switch is a policy decision you can write down, not a refactor.
Step 5: read what one call costs
Cost intuition is the thing beginners lack most, and they lack it because the bill is invisible by default. One flag fixes that:
bl text chat --message "Answer in one sentence: what is 1+1?" --output json
The response carries a usage block:
{
"prompt_tokens": 71,
"completion_tokens": 49,
"total_tokens": 120
}
prompt_tokens is what my question cost, completion_tokens what the answer cost. A one-sentence round trip is a little over a hundred tokens. Multiply by the published unit price on the model's page and you can price any call yourself — that 1+1 question landed four decimal places below one cent.
Doing this on the first call, rather than the fiftieth, changes how the rest of the project gets scoped. You stop reasoning about "AI costs" in the abstract and start reasoning about tokens per request times requests per day.
The free-quota rules, stated completely
"Free credits" undersells how specific the rules are. As published:
- Valid for 90 days, counted from whichever is later: account activation or model release
- Per model, typically 1M tokens each; quotas do not pool across models
- Beijing region only — which is why step 1 insists on the region
- Unused quota still expires and is not reissued
- Once quota runs out: verified accounts switch to pay-as-you-go automatically; unverified accounts simply stop
- There's a "stop when free quota is exhausted" switch in the console. With it on, an exhausted quota returns HTTP 403 instead of a bill
That switch is the one I'd enable before letting anyone experiment on an account I'm paying for. A 403 is a clear signal at the moment it matters; a line item on next month's invoice is not.
For your own remaining balance and expiry date, the console quota page is the source of truth. The CLI's quota self-check commands need a console login session, so they won't help you on a fresh machine.
What this route is not
An honest caveat, because I don't want anyone shipping a service this way: a CLI call is a probe, not a production architecture. A service needs typed errors it can match on, a retry and backoff policy it owns, connection reuse, and request shaping that lives in the same runtime as the rest of the code. That's what the SDK or the HTTP API is for, and moving to it should be a deliberate step rather than something you discover during an incident.
The first call has a different job. It has to succeed quickly, cost nothing unexpected, and leave you able to explain what happened — and one command with a --output json flag does all three better than a directory of boilerplate ever did for me.
Install docs and the full command list: Bailian CLI (bl). Image, speech and video live in the same CLI under other command groups, with the same rhythm: read --help, run one command, read the output.



Top comments (0)