/openai/v1. Roadie holds your OpenAI key (BYOK), meters usage per
device, and enforces free-vs-pro limits. RoadieKit requires iOS 18+.
RoadieKit is images-only today (generation and editing). For chat and embeddings on iOS, point a
third-party OpenAI-compatible Swift client at the same surface — see
chat and embeddings on iOS below and Using OpenAI SDKs.
Install
Add RoadieKit with Swift Package Manager. In Xcode, choose File → Add Package Dependencies… and enterhttps://github.com/paroaria/roadiekit.git and pick the Up to Next Major rule from
0.1.0, or add it to Package.swift:
Configure the client
ARoadie client needs a RoadieConfig (where the gateway lives, and which image model to request)
and a token provider (how each request is authenticated). Swap the provider between local
development and production without changing any call site:
StaticTokenProvider— a fixed bearer read from the run scheme’sROADIE_STATIC_TOKENenvironment variable (anrd_sk_…key or a pre-minted client token). The working simulator / dev path.AppAttestTokenProvider— silently mints a per-device client token via Apple App Attest, using the publishable key. The production path; it needs a real device (App Attest is unavailable in the simulator).
RoadieConfig
Method surface
TheRoadie client is an actor; client.images is its image surface. Both methods return the
generated image’s raw bytes (PNG unless the server’s output_format is changed) — the caller turns
them into a UIImage.
size is an ImageSize (.auto, .square, .landscape, .portrait), background is an
ImageBackground (.transparent, .opaque, .auto), and quality is an ImageQuality (.low,
.medium, .high, .auto). n defaults to 1. On edit, mask is optional; when present, only
the masked region is regenerated. edit defaults background to .transparent; generate defaults
it to .opaque.
Edit an image
Generate from a prompt
Authentication providers
RoadieKit resolves theAuthorization: Bearer … value through a TokenProvider:
StaticTokenProvider(token:)returns a fixed token;invalidateToken()is a no-op, so the built-in single remint-retry cannot loop.AppAttestTokenProvider(config:)mints short-lived client tokens by attesting the device with Apple App Attest and exchanging the proof at the gateway’s/v1/device/*endpoints (authorized with the publishable key). Only the App Attest key id is persisted (Keychain); the token lives in memory and is reminted before expiry (or after a 401). It requires apublishableKeyin the config and a real device.
On a DeviceCheck-capable device,
AppAttestTokenProvider also attaches an optional per-device
DeviceCheck token to the mint so the gateway’s free-tier guard can resist reinstall farming. This is
wired internally — there is no separate public DeviceCheck provider to construct — and it fails
open (an unsupported device or a token-generation error simply omits it). See
Mobile device auth.Error handling
Every HTTP or decoding failure is thrown as aRoadieError; task cancellation is Swift’s own
CancellationError (never a RoadieError). Branch on error.kind:
RoadieError also exposes statusCode, apiType, apiCode, message, and isRetryable, and
conforms to LocalizedError (errorDescription).
RoadieKit handles two cases for you: it re-mints once on a 401 (an expired client token) and
retries transient network and 5xx failures. A client .timedOut is deliberately not retried —
image generation runs for tens of seconds, so a timeout usually means the server is still working, and
a retry would double-execute an expensive call. An .insufficientQuota error drops the cached token
and is re-thrown unchanged (no retry) — your cue to show the paywall; see
Free → Pro with StoreKit.
Chat and embeddings on iOS
RoadieKit does not cover chat. Point any OpenAI-compatible Swift client at the same surface — the base URL and bearer token are the only changes:Not included
- Chat and embeddings — RoadieKit is images-only; use an OpenAI-compatible Swift client as above.
- A separate DeviceCheck provider — DeviceCheck is an internal detail of
AppAttestTokenProvider, not a public API you construct.
Next steps
iOS quickstart
Add RoadieKit to an app end to end.
Mobile device auth
How App Attest mints per-device client tokens with no account.
Free → Pro with StoreKit
Convert the free tier to a paid subscription and flip the device’s plan.
Image enhance tutorial
A complete image-editing feature end to end.