Use Chat Completions

Send a message array through the OpenAI-compatible Chat Completions API.

Set BASE_URL to your HTTPS API origin without a trailing slash or /v1, and pass API_KEY from your credential store. OpenAI-compatible SDKs use ${BASE_URL}/v1; Anthropic-compatible SDKs use BASE_URL.

Choose Chat Completions when an existing client expects a messages array and choices. For a new integration, Responses is the primary path. You need a key, an available model, and credits.

Send one message

bash
printf 'Authorization: Bearer %s\n' "$API_KEY" \
  | curl -q -H @- -i "$BASE_URL/v1/chat/completions" \
    -H "Content-Type: application/json" \
    -d '{
  "model": "gpt-5.6-sol",
  "messages": [
    {
      "role": "user",
      "content": "Say hello in one sentence."
    }
  ],
  "max_tokens": 64,
  "stream": false
}'

HTTP 200 returns a chat completion with a choices array and usage. Read the assistant message from choices[0].message; generated text is not deterministic. Keep the HTTP request-id header for support; check recent endpoint, time and outcome in API Activity. Its run ID differs from the header. If your client needs incremental choices, set stream: true and follow streaming. Unknown fields and unsupported required capabilities are rejected before generation. Optional parameters may be omitted when unavailable for the selected model at execution time; the change appears in API Activity.

Read choices

This illustrates a successful response shape; your ID, text, and token counts will differ:

json
{
  "id": "chatcmpl-018f3f407b447cc4b8ba3f62656c299c",
  "object": "chat.completion",
  "created": 1790244000,
  "model": "gpt-5.6-sol",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Done." },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 5,
    "total_tokens": 17,
    "prompt_tokens_details": { "cached_tokens": 0 },
    "completion_tokens_details": { "reasoning_tokens": 0 }
  }
}

Check choices[0].finish_reason: stop means a normal completion, length means the length limit was reached, and tool_calls means your application must execute a function. With a tool call, message.content may be null; message.tool_calls contains the function name, JSON arguments, and call ID. The current API Activity shows the outcome, tokens, and the finalized credit debit; do not treat total_tokens as a money price.

When to stream

Use -N to see each SSE event as it arrives. If you may need a safe retry after a disconnect, generate one idempotency key and keep it with the unchanged request body:

bash
export UNLIMGPT_REQUEST_KEY="$(openssl rand -hex 16)"

From the same shell, request the final usage chunk when your client needs token counts:

bash
test -n "${UNLIMGPT_REQUEST_KEY:-}" \
  && printf 'Authorization: Bearer %s\n' "$API_KEY" \
  | curl -q -H @- -i -N "$BASE_URL/v1/chat/completions" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $UNLIMGPT_REQUEST_KEY" \
    -d '{
  "model": "gpt-5.6-sol",
  "messages": [
    {
      "role": "user",
      "content": "Count to three."
    }
  ],
  "max_tokens": 64,
  "stream": true,
  "stream_options": {
    "include_usage": true
  }
}'

HTTP 200 starts the stream. Assemble choices[].delta in order. A final choice chunk carries finish_reason; with include_usage: true, a subsequent chunk has empty choices and the completed usage, followed by data: [DONE]. A TCP disconnect before that marker does not prove completion. For a retry, run only the second block with the same key and body; rerunning OpenSSL creates a new request. See streaming and idempotency for event handling and safe retries. For a new integration that needs structured output and stored results, start with Responses.

Next: handle errors and limits.