Gateway and inference
The commands on this page cover two surfaces that the rest of the reference does not: putting your resources on the internet, and calling the platform's hosted models from a terminal. Three small groups follow them.
platformctl gateway
Nothing in a project is reachable from outside it until you publish it, and unpublishing takes the address off the internet without deleting anything. The resource keeps running either way.
Endpoint resolution for this group: $CAI_GATEWAY_API, else $CAI_API, else
https://api.codyhill.dev.
gateway publish
One command for the common case. It reserves an endpoint, applies your access rules, and prints the address.
platformctl gateway publish agent/research-buddy --auth apikey
The argument is <type>/<resource>. Types are agent, function, serverless,
container, memorystore, and the two project-wide engines vectordb and
pubsub — those two cover the whole project and take no resource name:
platformctl gateway publish vectordb --auth none
--auth is required, and has no defaultOn a request-level endpoint (agent, function, serverless, container,
vectordb) the server refuses to publish without a choice, answering 400 and
naming auth.mode. That is deliberate: an open endpoint and a protected one are
both consequential, so the platform makes you say which one you meant.
On a raw-connection endpoint (memorystore, pubsub) the only legal value is
none — there are no requests to check a credential on.
| Flag | What it does |
|---|---|
--auth none|apikey|jwt | Who may call it. Required — see above. |
--key-name | Label for the key --auth apikey issues, so you can tell it apart later. |
--jwt-issuer, --jwt-jwks-uri, --jwt-audience | With --auth jwt: the issuer, where it publishes signing keys, and at least one audience. Without an audience, any token from that issuer is accepted. |
--allow-cidr | Only accept callers from this range, e.g. 203.0.113.0/24. Repeatable. |
--rate-limit | Cap the request rate as <requests>/<second|minute|hour|day>, e.g. 100/minute. |
--rate-limit-by | Count that rate per client_ip (default) or per api_key. |
--domain | Publish on an address of your own — claim it first. |
--name | Name for the endpoint, which also becomes the first label of the address. Defaults to the resource's name. |
--type | The resource type, when the argument is a bare name instead of type/name. |
--auth apikey issues a key and prints it once, here. An endpoint that
checks keys and has none cannot serve, so the platform will not let you publish
into that state.
Allow lists and rate limits work with any auth mode, including none.
gateway endpoint
platformctl gateway endpoint list # what of mine is on the internet right now?
| Command | What it does |
|---|---|
list | This project's endpoints. Start here. |
get <name> | One endpoint, its keys, and its address state. |
create | Reserve an endpoint and its address without putting it on the internet. |
publish <name> | Put an existing endpoint back on the internet. |
unpublish <name> | Take it off, keeping its address. |
update <name> | Change who may call it. |
delete <name> | Delete it, releasing its address and its keys. |
unpublish then publish keeps the address; delete then publish does not.
gateway key
platformctl gateway key issue research-buddy --name ci-runner
platformctl gateway key rotate research-buddy <key-id>
platformctl gateway key revoke research-buddy <key-id>
An endpoint key authorizes one endpoint, is checked at the network edge rather than by the platform, and carries no access to your account. Issuing one on an endpoint that does not check keys is allowed and does nothing until you switch that endpoint to key authentication.
rotate overlaps the old and new keys so nothing goes down mid-rollout.
gateway domain
Every project gets a working platform address for free and needs nothing here. This group is only for publishing on a name of your own — one DNS record, then a few minutes of waiting for it to appear.
platformctl gateway domain claim api.example.com
platformctl gateway domain list
platformctl gateway domain delete api.example.com
See Custom domains for the DNS record itself.
platformctl inference
The platform's hosted models, without writing a program. The surface is
OpenAI-compatible: point any OpenAI client at the same base URL with a platform
API key and /v1/embeddings, /v1/rerank and /v1/models just work.
Endpoint resolution for this group: $CAI_INFERENCE_API, else $CAI_API, else
https://api.codyhill.dev. From a Crusoe VM, or any host the data-plane
firewall admits, you can skip the port-forward with
CAI_INFERENCE_API=https://inference.data.codyhill.dev.
platformctl inference models
platformctl inference embed "a sailboat on the water"
| Flag | What it does |
|---|---|
--model | Embedding model id. Defaults to the platform's hosted embedding model. |
platformctl inference rerank "a boat" "a bicycle" "a sailboat" "a sports car"
| Flag | What it does |
|---|---|
--model | Reranking model id. Defaults to the platform's hosted reranker. |
--top-n | Return only the best N documents. Default: score all of them. |
embed takes one or more texts and shows the vectors' shape rather than
thousands of numbers — it answers "is this working, and how wide is the vector?",
which is what you want from a terminal. Use -o json for the vectors themselves.
See Embeddings and Reranking for how to use them in a workload.
platformctl platform
platformctl platform limits
Instance sizes, request timeouts, and the embedding width your vector indexes must use. Read these rather than hardcoding them: the console once carried its own copy of the embedding width, it was wrong, and every index created from that page was unusable.
platformctl search
platformctl search buddy
platformctl search buddy --all-projects
One query covers every kind the control plane knows about — agents, functions, serverless services, MCP servers, service accounts, secrets and projects — so you can find something without knowing which kind it is or which project it is in. Each match comes back with its kind, its project, and the console route that opens it.
By default the search is scoped to your selected project. --all-projects
searches every project you can see; with no project selected at all, that is
already what happens.
You see only what your grants allow. A project you can see but hold no resource role on matches by its own name and nothing inside it. Secrets match by name only — no secret value is searched, and none is ever returned.
platformctl change-password
platformctl change-password
A new account is issued a temporary password, and every management call is refused until it is replaced — so this is usually the first command you run. It prompts; the password is never taken as a flag, so it cannot land in your shell history or the process table.
This is not platformctl users reset-password, which is an administrator
issuing someone else a fresh temporary password.
Next steps
- Publish an endpoint — the same flow with the reasoning.
- Authentication — API keys and JWT in detail.
- IP allow lists and Rate limits.
- Inference overview — the three model surfaces.