AppAIGatewayDocs
Integrate your app

Calling custom endpoints

Send a request body to a slug and let the gateway choose the provider, model and parameters.

A custom endpoint is a URL whose provider and model are configured on the gateway:

POST https://api.appaigateway.com/v1/apps/{app}/endpoints/{slug}

Authentication is identical to the proxy: a gateway token with X-App-Version, or an API key. Limits, usage and error codes are the same. Only POST is accepted.

Request bodies

Send the body of the endpoint's request format, as the provider documents it. You may omit model; if you send one, the gateway replaces it with the endpoint's model, and for the Gemini formats it puts the model in the URL instead. The endpoint's parameters are deep-merged over your body, with the endpoint winning on conflicts, and a text endpoint's output cap is applied like the proxy's.

Request formatBody
OpenAI Responses{"input": "…"}
OpenAI Chat Completions{"messages": [{"role": "user", "content": "…"}]}
Anthropic Messages{"max_tokens": 1024, "messages": [{"role": "user", "content": "…"}]}
Gemini generateContent{"contents": [{"parts": [{"text": "…"}]}]}
OpenAI image generation{"prompt": "…"}
OpenAI embeddings{"input": "…"}
Gemini embedContent{"content": {"parts": [{"text": "…"}]}}
OpenAI audio transcriptionA multipart/form-data upload with a file field
curl https://api.appaigateway.com/v1/apps/example-app-a1b2c3/endpoints/chat \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'X-App-Version: 1.4.2' \
  -H 'Content-Type: application/json' \
  -d '{"input":"Suggest a 500 kcal lunch."}'

The response is in the serving provider's format. If a Responses endpoint falls back from OpenAI to xAI, you get xAI's Responses-style body. Both follow the same shape, but read the usage and any provider-specific fields defensively.

An Anthropic Messages endpoint sends anthropic-version: 2023-06-01 when your request has no anthropic-version header, and yours when it does.

A Gemini speech model answers with audio only when the request asks for it with "generationConfig": {"responseModalities": ["AUDIO"]}. Send it from your clients or set it in the endpoint's parameters.

Streaming

Streaming works as on the proxy: set "stream": true and read the event stream. On a Gemini generateContent endpoint, add ?alt=sse to the endpoint URL instead, as Gemini's own API does; the gateway calls the streaming method for you. A fallback happens only if nothing has been streamed yet.

From Swift, pass the query to the request helper rather than adding it to the URL afterwards: an App Attest proof is signed over the URL, query included. This needs the Swift package 1.6.0 or later.

let (bytes, response) = try await gateway.withAuthorizedRequest(
    endpointSlug: "gemini-chat",
    query: [URLQueryItem(name: "alt", value: "sse")],
    body: body,
    contentType: "application/json"
) { try await URLSession.shared.bytes(for: $0) }

Transcription endpoints

Send an OpenAI audio-transcription multipart body. model may be omitted. Leave response_format at its default or choose another JSON format: a plain-text answer (text, srt or vtt) reports nothing to bill, so it is refused with 400 invalid_request.

curl https://api.appaigateway.com/v1/apps/example-app-a1b2c3/endpoints/transcribe \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'X-App-Version: 1.4.2' \
  -F file=@note.m4a

With the Swift package

let (data, response) = try await gateway.withAuthorizedRequest(
    endpointSlug: "chat",
    body: Data(#"{"input":"Suggest a 500 kcal lunch."}"#.utf8),
    contentType: "application/json"
) { try await URLSession.shared.data(for: $0) }

Pass the body to withAuthorizedRequest: when the app verifies App Attest on every request, the request is signed over it, as described in Per-request proof.

Errors

An unknown slug answers 404 endpoint_not_found. A method other than POST answers 404 invalid_request. When every target in the chain fails, the last provider's error is returned, or 502 provider_error if none could be reached.

On this page