Your first request
Change the base URL. Nothing else in your code moves.
1curl https://api.aile.sh/v1/chat/completions \2-H "Authorization: Bearer $AILE_KEY" \3-H "Content-Type: application/json" \4-d '{5 "model": "cc/claude-sonnet-5",6 "messages": [{ "role": "user", "content": "Say hello." }]7}'
Base URL differs by SDK family
OpenAI clients want the /v1 suffix, because they append paths like
/chat/completions to it; given the bare origin they get a 404. The Anthropic
SDK and Claude Code append /v1/messages themselves, so they take the bare origin,
though a base URL ending in /v1 is served too.
What comes back
The body is exactly what your SDK expects: no envelope, no extra fields. The headers are the interesting part, and they tell you what happened:
1x-aile-sharer: 9c2e8b7d06315a4e2x-aile-node: a3f19c2e3x-aile-provider: claude4x-aile-capacity: subscription5x-aile-blind: true6x-aile-model: claude/claude-sonnet-57x-aile-price: 0.01828x-aile-attempts: 1
x-aile-capacity:subscription,nodeless,nodeless-oauthorlocal.x-aile-blind: whether the node could read the request.trueon a relayed subscription;falsewhen Aile terminated TLS itself.x-aile-node: omitted entirely on a nodeless serve, because no machine was in the path to name.x-aile-attempts: how many sharers were tried before one answered.x-aile-sharer: the serving sharer's internal id. To pin a sharer, send their handle from the marketplace (L+ 16 hex) instead; this value is not one.x-aile-status: on a503, the real status when it was a502or504, which the edge in front of Aile would otherwise swallow.x-aile-edge-hold: a stream with no answer after 25 seconds is committed to200and kept alive; it carries this header and only those of the ones above that could no longer change (not the sharer or price, except on self-hosted capacity), and a later failure arrives as your SDK's stream error event.
Full list: Headers.
Listing what you can ask for
1curl https://api.aile.sh/v1/models
Public: no key needed. It returns only what a sharer can serve right now and
has tested, so it is a live availability check rather than a catalogue of
everything that exists. Each row also carries the model's list price as a ceiling
(pricing), its context window and, where known, its reasoning-effort levels. See
Model names.
Picking a model name
1{ "model": "cc/claude-sonnet-5" }
The prefix names the provider, and every request must name one. cc/ is a
caller-facing alias for claude; a self-hosted model is local/<model>. A bare
name works only with an x-aile-provider header or on a provider-pinned key;
otherwise it is a 400. Claude Code and the Codex CLI are the exceptions: their bare
ids go to claude and codex.
There is no cross-provider fallback: naming a provider means that provider serves you or the request fails. Model names explains why.
Next
- Streaming:
"stream": true - Choosing a sharer: cap the price, require attestation
- Errors: what each status means and which are retryable