A successful first call to the String AI API comes down to three values: the base URL, an API key, and a model ID. Everything else is detail. This five-step quickstart walks through an OpenAI-compatible setup from a blank terminal to a working chat completions request, and it ends with the three mistakes that cause most first-call failures plus a short triage table for the error codes you are most likely to see.
If you prefer a browser before a terminal, the platform's own five-minute guide covers the WebChat entry point, and the desktop launcher lives on the download page. This article is for the API path: your code, one endpoint, one key.
Step 1: Get your String AI API key
Sign in to the platform with your account, open the API keys section of the dashboard, and create a key. Keys belong to your account, so the same login you use for the web chat manages them. The platform documentation walks through account setup and key creation step by step; follow it if the dashboard has moved things around since this was written.
Once you have the key, store it somewhere your shell can read it instead of pasting it into source files:
export STRING_AI_API_KEY="YOUR_API_KEY"Two habits from here on. Never commit a real key to a repository, and never paste one into a screenshot, an issue, or a chat message. If a script needs the key, have it read the environment variable above. Every example in this article uses the placeholder YOUR_API_KEY so that nothing can be copied into production by accident.
Step 2: Point your client at the base URL
The OpenAI-compatible entry point is:
https://www.string.ink/v1The /v1 matters. OpenAI-style clients take this base URL and append their own path segments, so a chat request ends up at /v1/chat/completions and a models lookup at /v1/models. If you set the base URL to the bare site root, those segments land on the wrong path and you get a 404 that looks like a missing endpoint. The platform fixed its base URL at https://www.string.ink/v1 and authenticates compatible clients with an OpenAI Bearer token, so this is the value to use in curl, SDKs, and tool settings that ask for an OpenAI-compatible address.
In the OpenAI SDK, the base URL is a constructor argument. In shell-based tools, it is often an environment variable. Both are just ways of getting the same string into the same place.
Step 3: List models before you call one
Different accounts can have different model permissions, so start with the models list endpoint rather than a chat request. Ask the API what your key can actually reach:
curl https://www.string.ink/v1/models \
-H "Authorization: Bearer $STRING_AI_API_KEY"A healthy response contains object "list" and a data array naming the models this key can use. That single call proves three things at once: the key is valid, the base URL is right, and the network path is open. It is also where you should copy model IDs from instead of typing them from memory. Model IDs are exact strings; a guess costs you a model-not-found error and a few confused minutes.
The documentation lists examples such as gpt-6-astra, gpt-5.6-luna, and claude-opus-4-8, and it suggests validating the connection with the lighter gpt-5.6-luna before switching to whichever model your workload needs. Treat the live models list as the source of truth and this paragraph as orientation.
Step 4: Send your first chat completions request
With the key and base URL confirmed, the first real request is a single-turn conversation. In curl:
curl https://www.string.ink/v1/chat/completions \
-H "Authorization: Bearer $STRING_AI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-luna",
"messages": [
{"role": "user", "content": "Say hello in one sentence."}
]
}'The request body has three moving parts: model names the ID you copied in step 3, messages carries the conversation (a single user message is the minimal valid form), and the endpoint speaks the OpenAI Chat Completions format, which means existing clients and older code can usually migrate by changing the base URL and the key.
If you prefer the OpenAI Python SDK, two constructor values point it at the platform, and the call itself stays exactly as you know it:
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://www.string.ink/v1",
)
resp = client.chat.completions.create(
model="gpt-5.6-luna",
messages=[{"role": "user", "content": "Say hello in one sentence."}],
)
print(resp.choices[0].message.content)For chat interfaces or command-line tools that should print output as it arrives, add "stream": true to the request. The endpoint then returns Server-Sent Events: each chunk carries object "chat.completion.chunk", the incremental text arrives under choices[].delta.content, and a final stats chunk usually carries usage before the stream ends with a [DONE] marker.
Step 5: Read the response and check usage
A non-streaming response follows the familiar OpenAI shape: a choices array where choices[0].message.content holds the assistant's text, and a usage object reporting token counts for the request. Print the content first and keep the usage around; it is the quickest way to confirm that a call really reached the model.
Consumption for your requests shows up in the platform dashboard as usage records tied to your account, so after the first successful call, look for it there. There is nothing to configure for basic usage tracking; if you later rotate keys or run several services, the record is how you tell which key is doing what.
One habit while everything is still small: keep the minimal curl command from step 4 in a scratch file. When something breaks in a larger application later, running the minimal version first separates a configuration problem from a code problem in about fifteen seconds.
Three mistakes that break a first call
1. The /v1 convention is not universal. OpenAI-compatible calls need the base URL to end at /v1. Some other tools use a different rule for the same platform: Claude Code's gateway variable (ANTHROPIC_BASE_URL) takes the site root with no /v1 suffix, because that client speaks a different protocol and appends different paths. If you work across both kinds of tools, keep the two conventions straight and set each one from that tool's own documentation page.
2. The credential has to arrive in the right header. In curl and the SDK, the key travels as a Bearer token in the Authorization header. Two classic slips: exporting the variable in one terminal and running curl in another, and wrapping the header value in single quotes, which stops the shell from expanding $STRING_AI_API_KEY so the literal text "Bearer $STRING_AI_API_KEY" gets sent. Some tools describe their credential as an "auth token" and expect it in a specific environment variable of their own; that naming is a tool convention, not a second credential system. When a 401 arrives, check what the client actually sent before doubting the key.
3. Model IDs must match exactly, and capabilities differ. A typo, a stale name, or an ID borrowed from another provider returns model-not-found, which is a string problem rather than an outage. And do not assume every model accepts the same parameters or the same input types. Text and vision inputs, image generation, and image editing are served as distinct endpoints; sending an image prompt to a chat endpoint is not the way to generate images. When a model rejects a parameter, check the models list and the endpoint documentation rather than guessing.
Quick triage for the first three error codes
| What you see | Check first | Typical fix |
|---|---|---|
| 401 or 403 | The API key | Re-copy the key into the environment variable; confirm it is exported in the same shell you are calling from; remove stray quotes or whitespace; restart the client so it rereads its settings |
| 404 | The base URL | Make sure it is exactly https://www.string.ink/v1, with /v1 present once and no trailing path; check the request path for typos |
| model-not-found or parameter errors | The model ID and the endpoint | Copy the ID from the models list; confirm the model supports the input type you are sending and that you are calling the matching endpoint |
The shared principle behind all three rows: make one minimal request before wiring anything into an application. A thirty-second curl tells you whether the problem is the key, the address, or the model, and every layer you add on top first multiplies the ways the failure can look.
Where to go next
- Connect your coding tools. The guide to running Codex CLI, Claude Code, and Cursor on a single key picks up where this article leaves off.
- Plan for model retirements. The migration playbook covers inventory, alias layers, and preflight checks so that a retirement notice never becomes an outage.
- Split work across models. The multi-model workflow shows how to assign research, writing, and review to different models without adding coordination work.
- Install the desktop launcher. The download page has the platform's launcher for a no-terminal setup path.
Scope and maintenance notes
This article describes the path and the failure modes; the exact field lists live in the platform documentation and can change as the platform evolves. Nothing here is a performance or availability commitment, and no numbers are quoted for pricing or usage because those belong to your account and the current documentation. Your API key is the one secret in the whole flow: keep it in an environment variable or a secrets manager, and rotate it when in doubt.
One call, one key, one address. Get the minimal request working first, and everything after that is integration work.