Last reviewed: 2026-07-21

Direct answer

A Swift URLSession chat client for CometAPI should keep configuration, request construction, decoding, and smoke-test logging separate. The CometAPI docs show an OpenAI-compatible base URL, the POST /v1/chat/completions chat path, a JSON request body with model and messages, bearer-token authorization, and response examples with choices, message, and error objects. That is enough to design a small Swift client, but not enough to make claims about every model, price, limit, latency, or provider-specific parameter.

Start with a narrow client that sends one non-streaming chat request and records whether the request matched the documented shape. Keep the API key outside the source file. In examples, show <API_KEY_PLACEHOLDER> and <MODEL_ID> instead of a real credential or a model value that could go stale. Verify the base URL and endpoint family before publishing code; Verify CometAPI Base URLs Before Publishing Tutorial Examples is the adjacent check for that step.

Setup assumptions:

  • The Swift target can use Foundation, URLSession, JSONEncoder, and JSONDecoder.
  • The caller provides the CometAPI key at runtime from a secret source, not from a committed Swift file.
  • The current base URL, chat path, request fields, response fields, and endpoint choice are checked in the linked CometAPI docs on the review date.
  • Model selection is handled as configuration. The smoke test proves request construction and response parsing, not catalog freshness.

Happy-path request plan:

  1. Read the API key from a runtime secret and reject an empty value before building the request.
  2. Build the URL from the documented CometAPI base URL and the documented chat completions path.
  3. Set the documented HTTP method, JSON content type, and authorization header with the runtime secret.
  4. Encode a minimal request body with model: "<MODEL_ID>" and a short messages array.
  5. Send the request with URLSession and capture the HTTP status, response data length, and JSON decode result.
  6. Decode only the fields the tutorial needs to display or log, such as the first choice message when present.
  7. Treat any undecoded or unexpected response as a failed smoke test until the current docs explain the shape.

A compact Swift request builder can stay intentionally plain:

import Foundation

struct ChatMessage: Codable {
    let role: String
    let content: String
}

struct ChatRequest: Codable {
    let model: String
    let messages: [ChatMessage]
}

func makeChatRequest(apiKey: String) throws -> URLRequest {
    guard !apiKey.isEmpty else { throw URLError(.userAuthenticationRequired) }
    let url = URL(string: "https://api.cometapi.com/v1/chat/completions")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
    request.httpBody = try JSONEncoder().encode(ChatRequest(
        model: "<MODEL_ID>",
        messages: [ChatMessage(role: "user", content: "Hello!")]
    ))
    return request
}

Use that snippet as a shape check, not as a full production client. Before a real release, compare it with Review CometAPI Request Headers Before Shipping Example Clients and the current chat reference.

Error-path check:

  • Run one request with a missing runtime key and confirm the client stops before sending.
  • Run one non-production request with an invalid placeholder-style token and confirm the client reports an authentication error state instead of displaying an empty assistant reply.
  • Run one malformed request in a controlled environment, such as omitting the required message body, and confirm the error is captured as sanitized metadata.

Minimum assertions:

  • The request URL uses the documented CometAPI base and chat completions path.
  • The request uses the documented HTTP method, content type, and authorization pattern.
  • The request body contains a model placeholder and a messages array.
  • A successful response is JSON and contains the documented response area your Swift decoder intentionally reads.
  • An error response is logged as a failed smoke test with HTTP status and a sanitized category.

Do not assert model availability, exact prices, account balance, rate limits, uptime, latency, billing behavior, provider routing behavior, or support coverage from this one test. Those areas need their own current documentation checks.

Sanitized pass/fail log template:

smoke_test_id: swift-urlsession-chat-<run_id>
reviewed_docs_date: 2026-07-21
request_family: chat_completions
client_runtime: swift-urlsession
credential_source: runtime_secret
http_status: <status_code>
json_decoded: <true_or_false>
assistant_message_present: <true_or_false>
error_category: <none_or_sanitized_category>
contract_notes: <short_note_without_credentials_or_full_response>
pass_fail: <pass_or_fail>

Who this is for

This guide is for Swift developers who want a small CometAPI chat client using Foundation URLSession instead of a generated SDK. It is also for tutorial authors who need to show a source-checked Swift example without over-claiming current model behavior. If you are building a full production app, use this as the first request/response check, then add timeout handling, retries, streaming, model selection, and observability after each area is verified in the current docs.

Key takeaways

  • Treat the CometAPI docs as the source for the base URL, endpoint path, HTTP method, headers, request body, response shape, and endpoint choice.
  • Keep the first URLSession client narrow: one request builder, one JSON encoder, one decoder boundary, and one sanitized log record.
  • Use <API_KEY_PLACEHOLDER> and <MODEL_ID> in public examples until account setup and model choice are verified.
  • Test one successful request shape and one expected failure path before adding UI, streaming, retries, or provider-specific parameters.
  • Keep citation links clean, and keep the reader-facing CometAPI account step separate from source citations.

Sources checked

Contract details to verify

AreaWhat to verifySource URLAccessedSafe candidate wording
Base URLConfirm the current API base before hard-coding a Swift URL value.https://apidoc.cometapi.com/2026-07-21“Configure URLSession with the current CometAPI base URL from the docs.”
Chat endpointConfirm the documented chat completions path and HTTP method.https://apidoc.cometapi.com/api/text/chat2026-07-21“Send the smoke-test request to the documented chat completions endpoint.”
AuthenticationConfirm the current bearer-token pattern and keep real keys outside examples.https://apidoc.cometapi.com/api/text/chat2026-07-21“Attach the documented authorization header using a runtime secret.”
Request bodyConfirm required fields before encoding Swift structs.https://apidoc.cometapi.com/api/text/chat2026-07-21“Encode only the documented fields needed for a minimal chat request.”
Response handlingConfirm the response fields your decoder reads.https://apidoc.cometapi.com/api/text/chat2026-07-21“Decode the documented fields your app uses and ignore fields you do not need.”
Endpoint choiceConfirm when the Responses endpoint is a better fit than chat completions.https://apidoc.cometapi.com/api/text/responses2026-07-21“Check endpoint fit before expanding the Swift client beyond chat completions.”

Failure modes

  • Credential leakage: a developer pastes a real key into a Swift file, issue comment, screenshot, or log. Replace it with <API_KEY_PLACEHOLDER>, rotate the exposed key through the account console, and keep future examples placeholder-only.
  • Endpoint drift: a sample keeps using an old base URL or path after the docs change. Re-check the documentation homepage and chat reference before treating the Swift client as current.
  • Over-broad decoder: the Swift types require fields that are not needed by the app, so a harmless provider-specific variation breaks the smoke test. Decode the fields you use and preserve raw response inspection only in a sanitized local debug flow.
  • Model assumption: a tutorial hard-codes a model value and later readers treat that value as guaranteed. Keep the model as <MODEL_ID> unless the model catalog and account eligibility are checked at the same time.
  • Error masking: the UI displays an empty assistant message for authentication, validation, or server errors. The client should separate successful chat output from failed request metadata.
  • Unsafe evidence: a pass note records the full prompt, full response, account balance, or credential source. Keep the log small and sanitized so it can be shared without exposing private details.

Reader next step

Before adding this client to an app screen, run a local smoke test with the current CometAPI docs open beside the code. Confirm the base URL, chat path, headers, minimal body, and response fields against the linked pages, then save only the sanitized pass/fail line. If the first test passes, add client-side timeout handling next; Add Client Timeouts Around CometAPI Text Requests covers that follow-up. When you are ready to create a key and test against your own account, use Start with CometAPI .

FAQ

Can I paste a real API key into the Swift example?

No. Keep real credentials out of source files, screenshots, and logs. Use <API_KEY_PLACEHOLDER> in examples and load the real value from a runtime secret source.

Should the first URLSession client include streaming?

Start with a non-streaming smoke test unless the linked docs and your product requirement both call for streaming. A narrow first test makes request construction, decoding, and error handling easier to verify.

Can I hard-code a model ID in the tutorial?

Use <MODEL_ID> until the current model documentation and account setup are verified. A chat client smoke test should prove request handling, not model catalog freshness.

What should the client log after a test request?

Log the reviewed docs date, request family, HTTP status, JSON decode result, sanitized error category, and pass/fail outcome. Do not log credentials, full prompts, full responses, prices, quotas, or private account details.