Call an app
Every call goes through the queue. It starts replicas when none are running, waits for an idle worker, and is retried if a worker fails. All calls authenticate with Authorization: Bearer $SURFRA_API_KEY.
Wait for the result
Section titled “Wait for the result”import surfra
app = surfra.App("my-model")output = app.run({"prompt": "Say hi"}, timeout=600)run returns the handler’s output. It raises RuntimeError with the error message if the request failed, and TimeoutError if timeout seconds pass first. The request keeps running after a timeout.
curl -X POST https://api.surfra.io/v1/apps/my-model/run \ -H "Authorization: Bearer $SURFRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"input": {"prompt": "Say hi"}}'This returns the transaction right away. Poll GET /v1/transactions/{id} until status is succeeded or failed.
Queue now, collect later
Section titled “Queue now, collect later”enqueue returns a Call as soon as the request is queued. Use it to fan out many requests and collect them as they finish.
calls = [app.enqueue({"prompt": p}) for p in prompts]results = [call.result(timeout=900) for call in calls]Call member |
Meaning |
|---|---|
id |
The transaction id, tx_... |
get() |
Fetch the latest status and stage outputs |
poll(interval=0.5, timeout=None) |
Wait until the request finishes, then return the transaction |
result(timeout=None) |
Wait, then return the output or raise |
A transaction looks like this:
{ "id": "tx_8c1f...", "status": "succeeded", "stages": [ {"name": "call", "status": "succeeded", "progress": 1.0, "output": {"text": "hi"}} ]}OpenAI-compatible calls
Section titled “OpenAI-compatible calls”HTTP apps that serve the OpenAI API, such as vLLM or SGLang, answer at /openai/{app}/v1.
import osfrom openai import OpenAI
client = OpenAI( base_url="https://api.surfra.io/openai/my-llm/v1", api_key=os.environ["SURFRA_API_KEY"],)reply = client.chat.completions.create( model="Qwen/Qwen3-0.6B", messages=[{"role": "user", "content": "Say hi"}],)curl https://api.surfra.io/openai/my-llm/v1/chat/completions \ -H "Authorization: Bearer $SURFRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "Qwen/Qwen3-0.6B", "messages": [{"role": "user", "content": "Say hi"}]}'Any HTTP path
Section titled “Any HTTP path”/http/{app}/{path} forwards a request to that path on an HTTP app’s server, with the method, query string, and JSON body.
curl https://api.surfra.io/http/my-llm/v1/models \ -H "Authorization: Bearer $SURFRA_API_KEY"Gateway calls wait up to the app’s execution_timeout_sec and return 504 after that. The body must be JSON and at most 8 MB. Streaming responses are not supported yet.
Where to find the app URL
Section titled “Where to find the app URL”Each app’s Overview tab shows ready-to-copy snippets with the app’s id and your API base URL.
