Antbase/Documentation

iOS / Mobile Integration

Integrate ANT into your iOS or mobile app using simple REST calls. No SDK required — just standard HTTP requests.

Architecture

ANT exposes a standard OpenAI-compatible REST API, so any iOS or mobile app can integrate directly over HTTP without installing a dedicated SDK.

1. Your app sends an HTTP request to ANT's API.

2. ANT classifies the request, selects the best model, and routes it.

3. The response is returned in standard OpenAI format.

  • Works with any HTTP client — URLSession, Alamofire, Moya, etc.
  • Supports text and vision (image) inputs via the same endpoint.
  • Streaming supported through Server-Sent Events (SSE).

Swift Example — Text Request

A minimal client using URLSession and Swift concurrency:

import Foundation

struct ANTClient {
    let baseURL = "https://antbase.ai/v1"
    let apiKey: String

    func chat(prompt: String, model: String = "ant:auto") async throws -> String {
        let url = URL(string: "\(baseURL)/chat/completions")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let body: [String: Any] = [
            "model": model,
            "messages": [["role": "user", "content": prompt]],
            "max_tokens": 1024
        ]
        request.httpBody = try JSONSerialization.data(withJSONObject: body)

        let (data, _) = try await URLSession.shared.data(for: request)
        let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
        let choices = json["choices"] as! [[String: Any]]
        let message = choices[0]["message"] as! [String: Any]
        return message["content"] as! String
    }
}

Swift Example — Vision / Image Analysis

Send a base64-encoded image for analysis using the standard image_url content type:

extension ANTClient {
    /// Analyze an image. Defaults to "ant:best" but also accepts nest references like "nest:product-vision".
    func analyzeImage(base64Image: String, prompt: String = "What is in this image?", model: String = "ant:best") async throws -> String {
        let url = URL(string: "\(baseURL)/chat/completions")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let body: [String: Any] = [
            "model": model,
            "messages": [[
                "role": "user",
                "content": [
                    ["type": "text", "text": prompt],
                    ["type": "image_url", "image_url": [
                        "url": "data:image/jpeg;base64,\(base64Image)"
                    ]]
                ]
            ]],
            "max_tokens": 1024
        ]
        request.httpBody = try JSONSerialization.data(withJSONObject: body)

        let (data, _) = try await URLSession.shared.data(for: request)
        let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
        let choices = json["choices"] as! [[String: Any]]
        let message = choices[0]["message"] as! [String: Any]
        return message["content"] as! String
    }
}

Example: Photo Scanner App

A practical workflow showing how to capture a photo, identify a product, and generate suggestions:

// 1. Capture photo from camera
let image = capturedImage
let imageData = image.jpegData(compressionQuality: 0.8)!
let base64 = imageData.base64EncodedString()

// 2. Identify the product
let client = ANTClient(apiKey: "your-ant-api-key")
let identification = try await client.analyzeImage(
    base64Image: base64,
    prompt: "Identify this product. Return the product name, brand, and category as JSON."
)

// 3. Get suggestions based on user's inventory
let suggestions = try await client.chat(
    prompt: "Based on this product: \(identification)\nAnd the user's current inventory: \(userInventory)\nSuggest complementary items.",
    model: "ant:best"
)

Recommended Models for Mobile

ModelBest For
ant:autoGeneral-purpose, good default for most requests
ant:bestImage analysis, complex reasoning, highest quality
ant:fastQuick responses for chat-like UX, low latency
ant:freeZero-cost for testing and non-critical features
nest:your-nest-nameRoute to a specific nest — curated model set with guardrails

Using Nests from iOS

A nest is a curated model configuration — it defines which models are allowed, cost limits, and guardrails. To route a request through a nest, set the model field to nest:your-nest-name.

// Using a nest for a mobile shopping assistant
let client = ANTClient(apiKey: "your-ant-api-key")

let response = try await client.chat(
    prompt: "Compare these two products and recommend the better value.",
    model: "nest:shopping-assistant"
)

Nests also work with vision requests — just pass the nest model reference the same way:

// Vision request routed through a nest
let description = try await client.analyzeImage(
    base64Image: base64,
    prompt: "Describe this product photo.",
    model: "nest:product-vision"
)

Security best practice: nest-locked keys

For production mobile apps, create API keys that are locked to a specific nest. A nest-locked key can only access the models and configurations defined in that nest — even if the key is extracted from the app binary, it cannot be used to call arbitrary models or exceed the nest's cost limits. This is the recommended approach for any key shipped inside a mobile app.

Error Handling

Handle common HTTP status codes from the API, especially when using nests:

extension ANTClient {
    func chatSafe(prompt: String, model: String = "ant:auto") async throws -> String {
        let url = URL(string: "\(baseURL)/chat/completions")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let body: [String: Any] = [
            "model": model,
            "messages": [["role": "user", "content": prompt]],
            "max_tokens": 1024
        ]
        request.httpBody = try JSONSerialization.data(withJSONObject: body)

        let (data, response) = try await URLSession.shared.data(for: request)
        let httpResponse = response as! HTTPURLResponse

        switch httpResponse.statusCode {
        case 200:
            let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
            let choices = json["choices"] as! [[String: Any]]
            let message = choices[0]["message"] as! [String: Any]
            return message["content"] as! String
        case 401:
            throw ANTError.unauthorized  // API key not authorized (or not allowed for this nest)
        case 404:
            throw ANTError.nestNotFound  // Nest name not found — check spelling, ensure it exists in the project
        case 429:
            throw ANTError.rateLimited   // Too many requests — back off and retry
        default:
            throw ANTError.serverError(statusCode: httpResponse.statusCode)
        }
    }
}

enum ANTError: Error {
    case unauthorized
    case nestNotFound
    case rateLimited
    case serverError(statusCode: Int)
}
  • 401 — API key is invalid or not authorized for the requested nest.
  • 404 — Nest not found. Double-check the nest name spelling and confirm the nest exists in your project.
  • 429 — Rate limited. Implement exponential backoff before retrying.

Tips

  • Use ant:best for vision/image analysis — it routes to models with vision support.
  • Compress images before sending. JPEG at 0.7-0.8 quality works well and keeps payload sizes reasonable.
  • For streaming responses, set "stream": true in the request body and parse the SSE event stream.
  • Store API keys in the iOS Keychain — never in UserDefaults, plist files, or hardcoded in source. UserDefaults is unencrypted and trivially readable on jailbroken devices. Use SecItemAdd / SecItemCopyMatching or a wrapper like KeychainAccess.
  • Markdown fence stripping: Some models return markdown-fenced responses (e.g. ```json ... ```). Strip these before JSON parsing: content.replacingOccurrences(of: "```json\\n", with: "").replacingOccurrences(of: "```", with: "")

Do I Need an SDK?

For most apps, direct REST calls with URLSession are sufficient. ANT's API is standard OpenAI-compatible, so any OpenAI Swift client library will also work out of the box.

Consider wrapping calls in a thin helper class (like the ANTClient above) for convenience, error handling, and retry logic.