Skip to content

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.

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.

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"}}
]
}

HTTP apps that serve the OpenAI API, such as vLLM or SGLang, answer at /openai/{app}/v1.

import os
from 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"}],
)

/http/{app}/{path} forwards a request to that path on an HTTP app’s server, with the method, query string, and JSON body.

Terminal window
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.

Each app’s Overview tab shows ready-to-copy snippets with the app’s id and your API base URL.