Swift client archive
The former Swift SDK is archived. Existing source and package versions may
remain available for historical use, but they receive no compatibility, update,
publication, or support guarantees. Use the supported
REST/OpenAPI contract for new integrations. See the
authoritative client support matrix for lifecycle definitions.
The remaining examples are retained as historical reference. They do not imply
that an archived package matches the current API.
Quick Start
import ModelRelay
let client = try ModelRelayClient.fromAPIKey(ProcessInfo.processInfo.environment["MODELRELAY_API_KEY"]!)
let answer = try await client.responses.text(
model: "claude-sonnet-5",
system: "You are a helpful assistant.",
user: "What is the capital of France?"
)
print(answer)
// "The capital of France is Paris."
Convenience API
Ask — Get a Quick Answer
import ModelRelay
let client = try ModelRelayClient.fromAPIKey(ProcessInfo.processInfo.environment["MODELRELAY_API_KEY"]!)
let answer = try await client.ask(model: "claude-sonnet-5", prompt: "What is 2 + 2?")
print(answer) // "4"
Configuration
From API Key
import ModelRelay
// From API key string
let client = try ModelRelayClient.fromAPIKey("mr_sk_...")
// With custom base URL
let client = try ModelRelayClient.fromAPIKey(
"mr_sk_...",
baseURL: URL(string: "https://api.modelrelay.ai/api/v1")!
)
Making Requests
ResponseBuilder
The ResponseBuilder provides a fluent API for constructing requests:
let response = try await client.responses.create(
client.responses
.builder()
.model("claude-sonnet-5")
.system("You are a helpful assistant.")
.user("What is 2 + 2?")
.maxOutputTokens(256)
.temperature(0.7)
)
print(response.text())
Multi-Turn Conversations
Build conversations with multiple messages:
let response = try await client.responses.create(
client.responses
.builder()
.model("claude-sonnet-5")
.system("You are a helpful assistant.")
.user("My name is Alice.")
.assistant("Hello Alice! How can I help you today?")
.user("What's my name?")
)
Customer-Attributed Requests
For metered billing, attribute requests to customers:
let response = try await client.responses.create(
client.responses
.builder()
.model("claude-sonnet-5")
.customerId("customer-123")
.system("You are helpful.")
.user("Hello!")
)
Streaming
Stream Events
For real-time response streaming:
let stream = try await client.responses.stream(
client.responses
.builder()
.model("claude-sonnet-5")
.user("Write a haiku about programming.")
)
for try await event in stream {
if event.type == .messageDelta, let delta = event.textDelta {
print(delta, terminator: "")
}
}
print()
Structured Output
Parse to Typed Struct
Use Codable structs to parse responses:
import ModelRelay
struct Review: Decodable {
let risk: String
}
let schema: JSONValue = .object([
"type": .string("object"),
"properties": .object([
"risk": .object(["type": .string("string")])
]),
"required": .array([.string("risk")])
])
let review: Review = try await client.responses.object(
model: "claude-sonnet-5",
schema: schema,
prompt: "Classify the risk as low/medium/high"
)
print(review.risk)
SQL Tool Loop
The SDK includes helpers for SQL query generation with validation:
let handlers = SQLToolLoopHandlers(
listTables: { [SQLTableInfo(name: "users")] },
describeTable: { _ in SQLTableDescription(table: "users", columns: []) },
sampleRows: { args in
SQLExecuteResult(columns: ["id"], rows: [["id": .number(1)]])
},
executeSQL: { args in
SQLExecuteResult(columns: ["id"], rows: [["id": .number(1)]])
}
)
let result = try await client.sqlToolLoop(
model: "claude-sonnet-5",
prompt: "Count users",
handlers: handlers,
profileId: "profile_1",
maxAttempts: 3,
resultLimit: 100
)
print(result.summary)
SQL Tool Loop (Streaming)
let stream = client.sqlToolLoopStream(
model: "claude-sonnet-5",
prompt: "List recent users",
handlers: handlers,
profileId: "profile_1"
)
for try await event in stream {
switch event {
case .summaryDelta(let delta):
print(delta, terminator: "")
case .executeSQL(let exec):
print("Rows:", exec.result.rows.count)
case .result(let result):
print("Final SQL:", result.sql)
default:
break
}
}
Customer-Scoped Requests
Create a customer-scoped client for attributed requests:
let customer = try client.forCustomer("customer-123")
let text = try await customer.responses.text(
model: "claude-sonnet-5",
user: "Say hi"
)
print(text)
Customer Token Provider
For frontend use with minted tokens:
let provider = try CustomerTokenProvider(CustomerTokenProviderConfig(
secretKey: "mr_sk_...",
request: CustomerTokenRequest(customerExternalId: "customer-123")
))
let tokenClient = try ModelRelayClient.fromTokenProvider(provider)
let text = try await tokenClient.responses.text(
model: "claude-sonnet-5",
user: "Hi"
)
Workflows + Runs
let spec: JSONValue = .object([
"version": .string("v1"),
"nodes": .array([])
])
let compile = try await client.workflows.compile(spec: spec)
if case .success(_, let planHash) = compile {
let run = try await client.runs.createFromPlan(planHash: planHash)
print(run.runId)
}
Platform Support
| Platform | Minimum Version |
|---|---|
| macOS | 13.0 |
| iOS | 16.0 |
| tvOS | 16.0 |
| watchOS | 9.0 |
Next Steps
- First Request - Make your first API call
- Streaming - Real-time response streaming
- Tool Use - Let models call functions
- Structured Output - Get typed JSON responses