Skip to content

CyonCode/NewAPIKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NewAPIKit

Swift SDK for self-hosted new-api instances. Provides chat completions, streaming, and model listing over an OpenAI-compatible REST API with HMAC-SHA256 request signing, certificate pinning, and device-bound authentication.

Requirements

  • Swift 5.9+
  • iOS 15+ / macOS 12+ / tvOS 15+ / watchOS 8+
  • No external dependencies (Foundation + CryptoKit only)

Installation

Swift Package Manager

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/conversun/NewAPIKit.git", from: "1.0.0")
]

Or in Xcode: File → Add Package Dependencies → paste the repository URL.

Usage

Setup

import NewAPIKit

let client = NewAPIClient(configuration: NewAPIConfiguration(
    apiKey: "sk-your-token",
    baseURL: URL(string: "https://api.example.com")!,
    defaultModel: "gemini-3-flash",
    pinnedCertificateHashes: ["base64-sha256-hash-from-admin-panel"]
))

Chat Completion

let response = try await client.chatCompletion(
    messages: [
        .system("You are a helpful assistant."),
        .user("Hello!")
    ],
    model: "gemini-3-flash",
    temperature: 0.7,
    maxTokens: 1024
)
print(response.content ?? "")

Streaming

let stream = try await client.chatCompletionStream(
    messages: [.user("Tell me a story")]
)
for try await chunk in stream {
    if let text = chunk.content {
        print(text, terminator: "")
    }
}

List Models

let models = try await client.listModels()
for model in models {
    print(model.id)
}

Security

Request Signing

Every request is automatically signed with HMAC-SHA256. The signing key is derived from the API key, bundle ID, and device ID (identifierForVendor), ensuring requests cannot be forged from outside the app on a different device.

Header Description
Authorization Bearer sk-...
X-Bundle-Id App's bundle identifier
X-Device-Id UIDevice.current.identifierForVendor
X-Timestamp Unix timestamp
X-Nonce UUID for replay protection
X-Signature HMAC-SHA256(timestamp + nonce + bodyHash)

Signing algorithm:

signingKey = SHA256(apiKey + bundleId + deviceId)
bodyHash   = SHA256(requestBody).hex
message    = "{timestamp}\n{nonce}\n{bodyHash}"
signature  = Base64(HMAC-SHA256(message, signingKey))

Certificate Pinning

The SDK supports TLS certificate pinning to prevent MITM attacks. It checks the entire certificate chain — pin the intermediate CA for stability across leaf certificate renewals.

Get the hash from the admin panel: Token Editor → iOS Authentication → Get Certificate Hash.

let config = NewAPIConfiguration(
    apiKey: "sk-your-token",
    baseURL: URL(string: "https://api.example.com")!,
    defaultModel: "gemini-3-flash",
    pinnedCertificateHashes: ["your-intermediate-ca-hash"]
)

When pinnedCertificateHashes is empty (default), pinning is disabled.

Token-Level Enforcement

When iOS authentication is enabled on a token in the admin panel, that token cannot be used without valid signatures. Even if someone extracts the sk-xxx key, requests without proper HMAC signing from a real device are rejected.

Error Handling

All errors are typed via NewAPIError:

do {
    let response = try await client.chatCompletion(messages: [.user("Hi")])
} catch let error as NewAPIError {
    switch error {
    case .invalidAPIKey:
        // Invalid or missing API key
    case .invalidSignature:
        // HMAC signature verification failed
    case .missingDeviceId:
        // Device ID unavailable (e.g. simulator without identifierForVendor)
    case .invalidBundleId, .missingBundleId:
        // Bundle ID not authorized or missing
    case .rateLimitExceeded(let retryAfter):
        // Rate limited
    case .quotaExceeded, .insufficientCredits:
        // Billing issue
    case .timeout:
        // Request timed out
    default:
        print(error.localizedDescription)
    }
}

License

See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages