> ## Documentation Index
> Fetch the complete documentation index at: https://phaseo.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Inicio rápido

> Crea una clave de API y envía tu primera solicitud a Phaseo con un modelo de texto actual.

Usa este tutorial para realizar una solicitud correcta a Phaseo, de texto generado o una decisión estructurada, y confirmar dónde aparece la respuesta.

<Note>
  **¿Usas un agente de programación?** Copia y pega este prompt antes de empezar:

  ```text theme={null}
  You are integrating this project with Phaseo Gateway. Read the Phaseo agent guidance at https://phaseo.app/docs/skill.md and the relevant API reference before editing anything. Inspect the existing provider configuration and identify the smallest safe change needed. Use https://api.phaseo.app with a server-side PHASEO_API_KEY, preserve the current provider/model behavior unless I explicitly ask for a migration, and never print or commit credentials. Explain the files you would change and the verification commands first. Do not deploy, rotate keys, send external messages, or make unrelated edits without my approval.
  ```
</Note>

En este tutorial podrás:

* crear una clave de API
* enviar una solicitud de texto o decisión estructurada
* leer el texto generado o las respuestas tipadas
* saber qué comprobar primero si falla la solicitud

***

## 1. Crea una clave de API

1. Abre el [panel de Phaseo](https://phaseo.app/gateway/keys).
2. Crea una clave en **Gateway -> Claves**.
3. Cópiala una sola vez y guárdala en un lugar seguro.

Usa este formato:

```http theme={null}
Authorization: Bearer phaseo_v1_sk_<kid>_<secret>
```

<Danger>
  Trata tu clave de API como una contraseña. No la expongas en código del lado del cliente.
</Danger>

***

## 2. Envía una solicitud de texto

Usa `POST /v1/responses` para la primera solicitud. Es el endpoint recomendado para generar texto en nuevas integraciones.

### Solicitud

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.phaseo.app/v1/responses \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-6-astra",
      "input": "Reply with: quickstart works"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.phaseo.app/v1/responses", {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "openai/gpt-6-astra",
      input: "Reply with: quickstart works",
    }),
  });

  const data = await response.json();
  const assistantText = data.output
    ?.find((item) => item.type === "message")
    ?.content?.find((part) => part.type === "output_text")
    ?.text;

  console.log(assistantText);
  ```

  ```typescript TypeScript SDK theme={null}
  import Phaseo from "@phaseo/sdk";

  const client = new Phaseo({ apiKey: process.env.PHASEO_API_KEY! });

  const response = await client.generateResponse({
    model: "openai/gpt-6-astra",
    input: "Reply with: quickstart works",
  });

  const assistantText = response.output
    ?.find((item: any) => item.type === "message")
    ?.content?.find((part: any) => part.type === "output_text")
    ?.text;

  console.log(assistantText);
  ```

  ```python Python SDK theme={null}
  from phaseo import Phaseo

  client = Phaseo(api_key="YOUR_API_KEY")

  response = client.generate_response(
      {
          "model": "openai/gpt-6-astra",
          "input": "Reply with: quickstart works",
      }
  )

  assistant_text = next(
      (
          part.get("text")
          for item in response.get("output", [])
          if item.get("type") == "message"
          for part in item.get("content", [])
          if part.get("type") == "output_text"
      ),
      None,
  )

  print(assistant_text)
  ```

  ```go Go SDK theme={null}
  package main

  import (
    "context"
    "fmt"

    phaseo "github.com/phaseoteam/Phaseo/packages/sdk/sdk-go/v3"
  )

  func main() {
    client := phaseo.New("YOUR_API_KEY", "https://api.phaseo.app/v1")
    input := map[string]interface{}{
      "role": "user",
      "content": []map[string]interface{}{
        {
          "type": "input_text",
          "text": "Reply with: quickstart works",
        },
      },
    }

    response, err := client.GenerateResponse(context.Background(), phaseo.ResponsesRequest{
      Model: "openai/gpt-6-astra",
      Input: &input,
    })
    if err != nil {
      panic(err)
    }

    fmt.Println(response)
  }
  ```

  ```csharp C# SDK theme={null}
  using PhaseoSdk;
  using System.Collections.Generic;

  var client = new Phaseo("YOUR_API_KEY");

  var response = await client.GenerateResponse(new Dictionary<string, object>
  {
      ["model"] = "openai/gpt-6-astra",
      ["input"] = "Reply with: quickstart works",
  });

  Console.WriteLine(response);
  ```

  ```php PHP SDK theme={null}
  <?php
  require 'vendor/autoload.php';

  use Phaseo\Sdk\Phaseo;

  $client = new Phaseo(getenv('PHASEO_API_KEY') ?: 'YOUR_API_KEY');

  $response = $client->generateResponse([
      'model' => 'openai/gpt-6-astra',
      'input' => 'Reply with: quickstart works',
  ]);

  print_r($response);
  ```

  ```ruby Ruby SDK theme={null}
  require 'phaseo_sdk'

  client = PhaseoSdk::Phaseo.new(api_key: ENV.fetch('PHASEO_API_KEY', 'YOUR_API_KEY'))

  response = client.generate_response(
    model: 'openai/gpt-6-astra',
    input: 'Reply with: quickstart works',
  )

  puts response
  ```

  ```rust Rust SDK theme={null}
  use phaseo::Phaseo;
  use serde_json::{json, Value};

  fn main() -> Result<(), Box<dyn std::error::Error>> {
      let client = Phaseo::from_env()?;
      let response = client.responses(&json!({
          "model": "openai/gpt-6-astra",
          "input": "Reply with: quickstart works"
      }))?;

      let assistant_text = response.body
          .get("output")
          .and_then(Value::as_array)
          .into_iter()
          .flatten()
          .filter(|item| item.get("type").and_then(Value::as_str) == Some("message"))
          .flat_map(|item| {
              item.get("content")
                  .and_then(Value::as_array)
                  .into_iter()
                  .flatten()
          })
          .find_map(|part| {
              (part.get("type").and_then(Value::as_str) == Some("output_text"))
                  .then(|| part.get("text").and_then(Value::as_str))
                  .flatten()
          })
          .unwrap_or("");

      println!("{assistant_text}");
      Ok(())
  }
  ```

  ```typescript Vercel AI SDK theme={null}
  import { phaseo } from "@phaseo/ai-sdk-provider";
  import { generateText } from "ai";

  const result = await generateText({
    model: phaseo("openai/gpt-6-astra"),
    prompt: "Reply with: quickstart works",
  });

  console.log(result.text);
  ```
</CodeGroup>

### Respuesta

```json theme={null}
{
  "id": "resp_...",
  "object": "response",
  "created_at": 1730000000,
  "status": "completed",
  "completed_at": 1730000001,
  "model": "openai/gpt-6-astra",
  "output": [
    {
      "type": "message",
      "id": "msg_...",
      "status": "completed",
      "role": "assistant",
      "content": [{ "type": "output_text", "text": "quickstart works", "annotations": [] }]
    }
  ],
  "usage": {
    "input_tokens": 9,
    "output_tokens": 3,
    "total_tokens": 12
  },
  "error": null,
  "incomplete_details": null
}
```

En las llamadas directas a la Responses API, lee la respuesta del asistente en `output[].content[]`, donde `type` es `output_text`.

Si usas Vercel AI SDK, lee la respuesta en `result.text`.

***

## 3. Toma una decisión estructurada

Usa `POST /v1/decisions` cuando tu aplicación necesite respuestas tipadas en lugar de texto generado. Phaseo ofrece Jev 1.13 de TypeSafe con el ID de modelo `typesafe/jev-1.13.0`. Envía un valor `state` y una o más preguntas con nombre; cada respuesta se devuelve con el mismo nombre.

<Note>
  Decisions es una función beta y puede requerir habilitación del espacio de trabajo. Jev 1.13 se factura a \$0.042 por 1 millón de tokens de entrada; los tokens de salida son gratuitos.
</Note>

Ejecuta estos ejemplos en tu servidor con `PHASEO_API_KEY` definido. Nunca expongas una clave de API del Gateway en código del navegador.

Los tres tipos de pregunta son:

* `choice` selecciona una opción de un mapa de criterios y devuelve probabilidades y confianza.
* `noul` devuelve una probabilidad de sí/no entre 0 y 1.
* `score` evalúa una matriz ordenada de criterios y devuelve una puntuación ponderada por probabilidad.

Puedes combinar tipos de pregunta en la misma solicitud.

### Solicitud

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.phaseo.app/v1/decisions \
    -H "Authorization: Bearer $PHASEO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "typesafe/jev-1.13.0",
      "state": {
        "customer_message": "I was charged twice and need help with a refund.",
        "account_tier": "pro",
        "days_waiting": 3
      },
      "questions": {
        "department": {
          "type": "choice",
          "instructions": "Which team should handle this request?",
          "criteria": {
            "billing": "Payments, invoices, refunds, and duplicate charges.",
            "support": "Product usage questions and troubleshooting.",
            "sales": "Upgrades and new accounts."
          }
        },
        "is_urgent": {
          "type": "noul",
          "instructions": "Does this request require urgent handling?",
          "criteria": {
            "true": "The customer is blocked or the issue is time-sensitive.",
            "false": "The request can follow the normal support queue."
          }
        },
        "customer_impact": {
          "type": "score",
          "instructions": "How severe is the customer impact?",
          "criteria": [
            "No impact",
            "Minor inconvenience",
            "Significant impact",
            "Service blocked"
          ]
        }
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.phaseo.app/v1/decisions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.PHASEO_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "typesafe/jev-1.13.0",
      state: {
        customer_message: "I was charged twice and need help with a refund.",
        account_tier: "pro",
        days_waiting: 3,
      },
      questions: {
        department: {
          type: "choice",
          instructions: "Which team should handle this request?",
          criteria: {
            billing: "Payments, invoices, refunds, and duplicate charges.",
            support: "Product usage questions and troubleshooting.",
            sales: "Upgrades and new accounts.",
          },
        },
        is_urgent: {
          type: "noul",
          instructions: "Does this request require urgent handling?",
          criteria: {
            true: "The customer is blocked or the issue is time-sensitive.",
            false: "The request can follow the normal support queue.",
          },
        },
        customer_impact: {
          type: "score",
          instructions: "How severe is the customer impact?",
          criteria: [
            "No impact",
            "Minor inconvenience",
            "Significant impact",
            "Service blocked",
          ],
        },
      },
    }),
  });

  if (!response.ok) throw new Error(await response.text());
  const data = await response.json();
  console.log(data.answers);
  ```

  ```typescript TypeScript SDK theme={null}
  import Phaseo from "@phaseo/sdk";

  const client = new Phaseo({ apiKey: process.env.PHASEO_API_KEY! });

  const decision = await client.decisions.make({
    model: "typesafe/jev-1.13.0",
    state: {
      customer_message: "I was charged twice and need help with a refund.",
      account_tier: "pro",
      days_waiting: 3,
    },
    questions: {
      department: {
        type: "choice",
        instructions: "Which team should handle this request?",
        criteria: {
          billing: "Payments, invoices, refunds, and duplicate charges.",
          support: "Product usage questions and troubleshooting.",
          sales: "Upgrades and new accounts.",
        },
      },
      is_urgent: {
        type: "noul",
        instructions: "Does this request require urgent handling?",
        criteria: {
          true: "The customer is blocked or the issue is time-sensitive.",
          false: "The request can follow the normal support queue.",
        },
      },
      customer_impact: {
        type: "score",
        instructions: "How severe is the customer impact?",
        criteria: [
          "No impact",
          "Minor inconvenience",
          "Significant impact",
          "Service blocked",
        ],
      },
    },
  });

  console.log(decision.answers);
  ```

  ```python Python SDK theme={null}
  from phaseo import Phaseo

  client = Phaseo()  # Uses PHASEO_API_KEY from the environment

  decision = client.decisions.make(
      {
          "model": "typesafe/jev-1.13.0",
          "state": {
              "customer_message": "I was charged twice and need help with a refund.",
              "account_tier": "pro",
              "days_waiting": 3,
          },
          "questions": {
              "department": {
                  "type": "choice",
                  "instructions": "Which team should handle this request?",
                  "criteria": {
                      "billing": "Payments, invoices, refunds, and duplicate charges.",
                      "support": "Product usage questions and troubleshooting.",
                      "sales": "Upgrades and new accounts.",
                  },
              },
              "is_urgent": {
                  "type": "noul",
                  "instructions": "Does this request require urgent handling?",
                  "criteria": {
                      "true": "The customer is blocked or the issue is time-sensitive.",
                      "false": "The request can follow the normal support queue.",
                  },
              },
              "customer_impact": {
                  "type": "score",
                  "instructions": "How severe is the customer impact?",
                  "criteria": [
                      "No impact",
                      "Minor inconvenience",
                      "Significant impact",
                      "Service blocked",
                  ],
              },
          },
      }
  )

  print(decision["answers"])
  ```
</CodeGroup>

### Respuesta

```json theme={null}
{
  "model": "typesafe/jev-1.13.0",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "billing",
      "probabilities": { "billing": 0.91, "support": 0.06, "sales": 0.03 },
      "confidence": 0.89
    },
    "is_urgent": {
      "type": "noul",
      "noul": 0.84
    },
    "customer_impact": {
      "type": "score",
      "score": 2.4,
      "legend": {
        "0": "No impact",
        "1": "Minor inconvenience",
        "2": "Significant impact",
        "3": "Service blocked"
      },
      "probabilities": { "0": 0.02, "1": 0.12, "2": 0.61, "3": 0.25 },
      "confidence": 0.76
    }
  },
  "usage": {
    "input_tokens": 42,
    "output_tokens": 18,
    "total_tokens": 60
  }
}
```

Lee el valor tipado de la respuesta que coincida con el ID de tu pregunta, por ejemplo `answers.department.choice`, `answers.is_urgent.noul` o `answers.customer_impact.score`. Usa `confidence` y `probabilities` si necesitas establecer un umbral en la aplicación en lugar de decidir solo a partir del valor.

Consulta la [referencia de la API Decisions](./api-reference/endpoint/decisions) para el contrato completo de solicitudes y respuestas, y la [referencia del modelo Jev](https://docs.typesafe.ai/models) de TypeSafe para el comportamiento del modelo y los límites del proveedor.

***

## 4. Soluciona los problemas de la primera solicitud

* `401`: comprueba la clave de API y el encabezado `Authorization`.
* `400`: comprueba el cuerpo de la solicitud y el ID del modelo.
* `402`: cambia a un modelo `:free` o añade saldo antes de usar un modelo de pago.
* `429` o `5xx`: vuelve a intentarlo con retroceso exponencial.

Consulta la [referencia de gestión de errores](./api-reference/errors.mdx) para encontrar el problema rápidamente.

***

## 5. Si estás creando una función de vídeo

La generación de vídeo es asíncrona. Primero crea una tarea y después consulta su estado o suscríbete para recibir el resultado.

1. Crea una tarea con `POST /v1/videos`.
2. Consulta el estado con `GET /v1/videos/{video_id}` hasta que termine.
3. Descarga el contenido con `GET /v1/videos/{video_id}/content`.

```bash theme={null}
# Create
curl https://api.phaseo.app/v1/videos \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<video-model-id>",
    "prompt": "A cinematic sunrise over a mountain lake"
  }'

# Poll status
curl https://api.phaseo.app/v1/videos/VIDEO_ID \
  -H "Authorization: Bearer YOUR_API_KEY"
```

***

## 6. Sigue construyendo

<Columns cols={2}>
  <Card title="Integrar el Gateway" icon="plug" href="./developers/integrating-with-the-gateway.mdx">
    Patrones de integración para producción y cómo elegir un endpoint.
  </Card>

  <Card title="Referencia de la API" icon="book" href="./api-reference/introduction.mdx">
    Documentación completa de solicitudes y respuestas para cada endpoint.
  </Card>

  <Card title="Ejemplos" icon="code" href="./guides/examples.mdx">
    Más ejemplos completos de solicitudes para flujos habituales.
  </Card>

  <Card title="Soporte" icon="message-circle" href="https://phaseo.app/help">
    Obtén ayuda con la depuración, el enrutamiento y el comportamiento de los modelos.
  </Card>
</Columns>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.