Configuración
import Phaseo from "@phaseo/sdk";
const client = new Phaseo({ apiKey: process.env.PHASEO_API_KEY! });
from phaseo import Phaseo
client = Phaseo(api_key="your-api-key")
import (
"context"
phaseo "github.com/phaseoteam/Phaseo/packages/sdk/sdk-go/v3"
)
client, err := phaseo.NewFromEnv() // reads PHASEO_API_KEY
if err != nil {
panic(err)
}
ctx := context.Background()
using PhaseoSdk;
var client = new Phaseo(); // reads PHASEO_API_KEY
<?php
require 'vendor/autoload.php';
use Phaseo\Sdk\Phaseo;
$client = new Phaseo(); // reads PHASEO_API_KEY
require 'phaseo_sdk'
client = PhaseoSdk::Phaseo.new # reads PHASEO_API_KEY
import app.phaseo.sdk.Phaseo;
Phaseo client = new Phaseo(System.getenv("PHASEO_API_KEY"));
use phaseo::Phaseo;
use serde_json::json;
let client = Phaseo::from_env()?; // or Phaseo::new("phaseo_v1_sk_...")?
Chat completions
const completion = await client.generateText({
model: "openai/gpt-6-astra",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "What is Phaseo?" },
],
});
for await (const chunk of client.streamChat({
model: "openai/gpt-6-astra",
messages: [{ role: "user", content: "Tell me a story" }],
})) {
if (chunk.text) process.stdout.write(chunk.text);
}
completion = client.generate_text(
{
"model": "openai/gpt-6-astra",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is Phaseo?"},
],
}
)
for chunk in client.stream_chat(
{
"model": "openai/gpt-6-astra",
"messages": [{"role": "user", "content": "Tell me a story"}],
}
):
if chunk.get("text"):
print(chunk["text"], end="", flush=True)
chat, err := client.GenerateText(ctx, phaseo.ChatCompletionsRequest{
Model: "openai/gpt-6-astra",
Messages: []map[string]interface{}{{"role": "user", "content": "Hello"}},
})
var chat = await client.GenerateText(new Dictionary<string, object>
{
["model"] = "openai/gpt-6-astra",
["messages"] = new[]
{
new Dictionary<string, object> { ["role"] = "user", ["content"] = "Hello" },
},
});
$chat = $client->generateText([
'model' => 'openai/gpt-6-astra',
'messages' => [
['role' => 'user', 'content' => 'Hello'],
],
]);
chat = client.generate_text(
model: 'openai/gpt-6-astra',
messages: [{ role: 'user', content: 'Hello' }]
)
var chat = client.createChatCompletion(Map.of(
"model", "openai/gpt-6-astra",
"messages", List.of(Map.of("role", "user", "content", "Hello"))
));
let response = client.chat_completions(&json!({
"model": "openai/gpt-6-astra",
"messages": [{
"role": "user",
"content": "Reply with exactly: chat works"
}]
}))?;
println!("{}", response.body);
Responses
const response = await client.generateResponse({
model: "openai/gpt-6-astra",
input: [{ role: "user", content: [{ type: "input_text", text: "Summarise this" }] }],
});
for await (const chunk of client.streamResponses({
model: "openai/gpt-6-astra",
input: [{ role: "user", content: [{ type: "input_text", text: "Stream this" }] }],
})) {
if (chunk.text) process.stdout.write(chunk.text);
}
resp = client.generate_response(
{
"model": "openai/gpt-6-astra",
"input": [{"role": "user", "content": [{"type": "input_text", "text": "Summarise this"}]}],
}
)
for chunk in client.stream_responses(
{
"model": "openai/gpt-6-astra",
"input": [{"role": "user", "content": [{"type": "input_text", "text": "Stream this"}]}],
}
):
if chunk.get("text"):
print(chunk["text"], end="", flush=True)
resp, err := client.GenerateResponse(ctx, phaseo.ResponsesRequest{
Model: "openai/gpt-6-astra",
Input: "Reply with: go sdk works",
})
var resp = await client.GenerateResponse(new Dictionary<string, object>
{
["model"] = "openai/gpt-6-astra",
["input"] = "Reply with: csharp sdk works",
});
$response = $client->generateResponse([
'model' => 'openai/gpt-6-astra',
'input' => 'Reply with: php sdk works',
]);
response = client.generate_response(
model: 'openai/gpt-6-astra',
input: 'Reply with: ruby sdk works'
)
var response = client.createResponse(Map.of(
"model", "openai/gpt-6-astra",
"input", "Reply with: Java SDK works"
));
try (var lines = client.streamResponse(Map.of(
"model", "openai/gpt-6-astra", "input", "Hello"
))) {
lines.forEach(System.out::println);
}
let response = client.responses(&json!({
"model": "openai/gpt-6-astra",
"input": "Summarise why provider fallbacks improve reliability."
}))?;
println!("{}", response.body);
Messages (compatible con Anthropic)
const message = await client.generateMessage({
model: "anthropic/claude-haiku-4.5",
messages: [{ role: "user", content: "Hello from the Messages API" }],
max_tokens: 128,
});
for await (const chunk of client.streamMessages({
model: "anthropic/claude-haiku-4.5",
messages: [{ role: "user", content: "Stream a short hello" }],
max_tokens: 128,
})) {
if (chunk.text) process.stdout.write(chunk.text);
}
message = client.generate_message(
{
"model": "anthropic/claude-haiku-4.5",
"messages": [{"role": "user", "content": "Hello from the Messages API"}],
"max_tokens": 128,
}
)
for chunk in client.stream_message(
{
"model": "anthropic/claude-haiku-4.5",
"messages": [{"role": "user", "content": "Stream a short hello"}],
"max_tokens": 128,
}
):
if chunk.get("text"):
print(chunk["text"], end="", flush=True)
stream_message produce fragmentos ya analizados; stream_messages produce las líneas SSE sin procesar. Go, C#, PHP, Ruby y Java tienen createAnthropicMessage con su propio estilo de nombres.
Imágenes
await client.generateImage({
model: "openai/gpt-image-1",
prompt: "A lighthouse at golden hour",
});
await client.generateImageEdit({
model: "openai/gpt-image-1",
prompt: "Make it sunset",
image: "data:image/png;base64,...",
});
image = client.generate_image(
{"model": "openai/gpt-image-1", "prompt": "A lighthouse at golden hour"}
)
edited = client.generate_image_edit(
{
"model": "openai/gpt-image-1",
"prompt": "Make it sunset",
"image": "data:image/png;base64,...",
}
)
image, err := client.CreateImage(ctx, map[string]interface{}{
"model": "openai/gpt-image-1",
"prompt": "A lighthouse at golden hour",
})
var image = await client.GenerateImage(new Dictionary<string, object>
{
["model"] = "openai/gpt-image-1",
["prompt"] = "A lighthouse at golden hour",
});
$image = $client->generateImage([
'model' => 'openai/gpt-image-1',
'prompt' => 'A lighthouse at golden hour',
]);
$edit = $client->generateImageEdit([
'model' => 'openai/gpt-image-1',
'prompt' => 'Make it sunset',
'image' => 'data:image/png;base64,...',
]);
image = client.generate_image(
model: 'openai/gpt-image-1',
prompt: 'A lighthouse at golden hour'
)
edit = client.generate_image_edit(
model: 'openai/gpt-image-1',
prompt: 'Make it sunset',
image: 'data:image/png;base64,...'
)
var image = client.createImage(Map.of(
"model", "openai/gpt-image-1",
"prompt", "A lighthouse at golden hour"
));
Audio
Las transcripciones y las traducciones reciben una subida multipart. TypeScript envía un cuerpoFormData como multipart. Los métodos de Python, Go, C#, PHP y Ruby envían JSON, así que la transcripción solo funciona con una URL pasada a un modelo que acepte file_url, y la traducción necesita una subida multipart. Para subir un archivo de audio desde esos SDK, consulta STT (voz a texto) y Traducciones.
import { readFile } from "node:fs/promises";
const speech = await client.generateSpeech({
model: "openai/gpt-4o-mini-tts",
input: "Hello world",
});
// Las transcripciones y las traducciones reciben una subida multipart.
const form = new FormData();
form.append("model", "openai/gpt-4o-transcribe");
form.append("file", new Blob([await readFile("call.mp3")], { type: "audio/mpeg" }), "call.mp3");
const transcript = await client.generateTranscription(form as unknown as Record<string, unknown>);
speech = client.generate_speech(
{"model": "openai/gpt-4o-mini-tts", "input": "Hello world"}
)
# generate_transcription envía JSON, así que pasa una URL a un modelo que acepte file_url.
transcription = client.generate_transcription(
{"model": "mistral/voxtral-mini-transcribe-2", "file_url": "https://example.com/call.mp3"}
)
speech, err := client.CreateSpeech(ctx, map[string]interface{}{
"model": "openai/gpt-4o-mini-tts",
"input": "Hello from Go",
})
var speech = await client.CreateSpeech(new Dictionary<string, object>
{
["model"] = "openai/gpt-4o-mini-tts",
["input"] = "Hello from .NET",
});
$speech = $client->createSpeech([
'model' => 'openai/gpt-4o-mini-tts',
'input' => 'Hello from PHP',
]);
$transcript = $client->generateTranscription([
'model' => 'mistral/voxtral-mini-transcribe-2',
'file_url' => 'https://example.com/meeting.mp3',
]);
speech = client.generate_speech(
model: 'openai/gpt-4o-mini-tts',
input: 'Hello world'
)
transcription = client.generate_transcription(
model: 'mistral/voxtral-mini-transcribe-2',
file_url: 'https://example.com/meeting.mp3'
)
generateTranslation(). Java: createSpeech espera JSON y no puede decodificar audio binario, así que usa rawClient().requestBytes para la voz; envía las subidas de transcripción y traducción con el cliente HTTP estándar de Java, como muestran las páginas de STT y Traducciones.
Vídeo
const video = await client.videos.generateAndWait({
model: "openai/sora-2",
prompt: "A serene mountain lake at sunrise",
});
video = client.videos.generate_and_wait(
{"model": "openai/sora-2", "prompt": "A serene mountain lake at sunrise"}
)
Embeddings, rerank y moderación
const embedding = await client.generateEmbedding({
model: "openai/text-embedding-3-large",
input: "Sample text",
});
const ranked = await client.rerank.create({
model: "voyage/rerank-2",
query: "How do I list models?",
documents: ["Call GET /v1/models.", "Create an image with POST /v1/images/generations."],
});
await client.generateModeration({
model: "openai/omni-moderation",
input: "Some text to check",
});
embedding = client.generate_embedding(
{"model": "openai/text-embedding-3-large", "input": "Sample text"}
)
ranked = client.rerank.create(
{
"model": "voyage/rerank-2",
"query": "How do I list models?",
"documents": ["Call GET /v1/models.", "Create an image with POST /v1/images/generations."],
}
)
moderation = client.generate_moderation(
{"model": "openai/omni-moderation", "input": "Text to check"}
)
embedding, err := client.GenerateEmbedding(ctx, map[string]interface{}{
"model": "openai/text-embedding-3-large",
"input": "Sample text",
})
moderation, err := client.GenerateModeration(ctx, map[string]interface{}{
"model": "openai/omni-moderation",
"input": "Some text to check",
})
var embedding = await client.CreateEmbedding(new Dictionary<string, object>
{
["model"] = "openai/text-embedding-3-large",
["input"] = "Sample text",
});
var moderation = await client.GenerateModeration(new Dictionary<string, object>
{
["model"] = "openai/omni-moderation",
["input"] = "Some text to check",
});
$embedding = $client->generateEmbedding([
'model' => 'openai/text-embedding-3-large',
'input' => 'Sample text',
]);
$moderation = $client->generateModeration([
'model' => 'openai/omni-moderation',
'input' => 'Some text to check',
]);
embedding = client.generate_embedding(
model: 'openai/text-embedding-3-large',
input: 'Sample text'
)
moderation = client.generate_moderation(
model: 'openai/omni-moderation',
input: 'Some text to check'
)
var embedding = client.createEmbedding(Map.of(
"model", "openai/text-embedding-3-large",
"input", "Sample text"
));
// post(...) envía JSON a un endpoint sin helper de alto nivel.
// La ruta puede incluir u omitir la barra inicial.
let response = client.post("/embeddings", &json!({
"model": "openai/text-embedding-3-small",
"input": "Phaseo routes across AI providers"
}))?;
Lotes y archivos
const file = await client.uploadFile({
purpose: "batch",
file: new Blob(["{}"], { type: "application/json" }),
filename: "batch.jsonl",
});
const batch = await client.createBatch({
input_file_id: file.id,
endpoint: "/v1/responses",
completion_window: "24h",
});
const batchStatus = await client.getBatch(batch.id);
uploaded = client.upload_file(
purpose="batch",
file=b'{"test": true}',
filename="batch.jsonl",
content_type="application/json",
)
batch = client.create_batch(
{
"endpoint": "/v1/responses",
"input_file_id": uploaded["id"],
"completion_window": "24h",
"session_id": "agent-run-42",
}
)
status = client.get_batch(batch["id"])
createBatch y retrieveBatch con su propio estilo de nombres; Archivos explica las subidas en cada SDK.
URL de WebSocket de trabajos asíncronos
const batchSocketUrl = client.batches.websocketUrl(batch.id, {
intervalMs: 1500,
closeOnTerminal: false,
});
const videoSocketUrl = client.videos.websocketUrl(video.id);
batch_socket_url = client.batches.websocket_url(
batch["id"], interval_ms=1500, close_on_terminal=False
)
video_socket_url = client.videos.websocket_url(video["id"])
String batchSocketUrl = client.getBatchWebSocketUrl(batchId, 1500, false);
String videoSocketUrl = client.getVideoWebSocketUrl(videoId);
Modelos, estado y cuenta
Los créditos y la actividad necesitan una clave de API de administración.const models = await client.getModels();
const health = await client.getHealth();
const providers = await client.listProviders();
// Los créditos y la actividad necesitan una clave de API de administración.
const credits = await client.getCredits();
const activity = await client.getActivity({ days: 30 });
models = client.get_models()
health = client.get_health()
providers = client.list_providers()
generation = client.get_generation("G-01ABC...")
# Los créditos y la actividad necesitan una clave de API de administración.
credits = client.get_credits()
activity = client.get_activity({"days": 30})
models, err := client.GetModels(ctx, map[string]string{"limit": "10"})
health, err := client.Health(ctx)
var models = await client.ListModels(new Dictionary<string, string> { ["limit"] = "10" });
var health = await client.Health();
$models = $client->listModels(['limit' => 10]);
$health = $client->health();
models = client.list_models(limit: 10)
health = client.health
var models = client.listModels(Map.of("limit", "10"));
Gestiona los errores
import { PhaseoHttpError } from "@phaseo/sdk";
try {
await client.generateText({ model: "invalid", messages: [{ role: "user", content: "Hi" }] });
} catch (error) {
if (error instanceof PhaseoHttpError) {
console.error(error.status, error.code, error.requestId, error.traceUrl);
} else {
throw error;
}
}
from phaseo import PhaseoHTTPError
try:
client.generate_text({"model": "invalid", "messages": [{"role": "user", "content": "Hi"}]})
except PhaseoHTTPError as error:
print(error.status, error.code, error.request_id, error.trace_url)
import app.phaseo.gen.Client;
import app.phaseo.sdk.Phaseo;
import java.time.Duration;
import java.util.Map;
Phaseo client = new Phaseo(System.getenv("PHASEO_API_KEY"))
.setTimeout(Duration.ofSeconds(30))
.setMaxRetries(2);
try {
var result = client.requestWithResponse("GET", "/models",
Map.of("limit", "5"), null, null, null);
System.out.println(result.requestId());
System.out.println(result.data);
} catch (Client.ApiException error) {
System.err.println(error.getStatusCode());
System.err.println(error.getRequestId());
System.err.println(error.getResponseBody());
}
let request = serde_json::json!({
"model": "openai/gpt-6-astra",
"input": "Handle this request"
});
match client.responses(&request) {
Ok(response) => println!("{}", response.body),
Err(error) => {
eprintln!("message: {}", error.message);
eprintln!("status: {:?}", error.status);
eprintln!("body: {:?}", error.body);
}
}
PhaseoError (Rust) tiene un estado HTTP y un cuerpo JSON analizado cuando el Gateway devolvió un error; los fallos de transporte y de configuración no tienen estado. La descripción general enumera los campos de error de cada SDK.
Añade un encabezado a las solicitudes
Rust:with_header añade un encabezado a todas las solicitudes posteriores.
Rust
let client = Phaseo::from_env()?
.with_header("x-phaseo-workspace-id", "workspace_123");