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

# Migrar una integración existente

> Cambia dos constantes. Después revisa los puntos en que el comportamiento difiere.

Esta API implementa el contrato estándar de tareas asíncronas. En los endpoints que admite, los esquemas de
solicitud y respuesta no cambian, así que un cliente que funciona no suele necesitar cambios de código.

## La migración

```diff theme={null}
- const BASE = "https://api.your-current-provider.example"
+ const BASE = "https://api.querying.ai"
```

Apunta tu constante de clave de API a una clave de querying.ai. Tu URL de webhook, claves de idempotencia, tipos
de tarea y parseo de respuestas se quedan como están.

## Qué está implementado

<CardGroup cols={2}>
  <Card title="Admitido" icon="check">
    `POST /v1/async/task`

    `POST /v1/async/task/batch`

    `GET /v1/async/task/{id}`

    Callbacks de webhook
  </Card>

  <Card title="No implementado" icon="x">
    Endpoints síncronos `/v1/monitor/*`

    `/v1/async/status`
  </Card>
</CardGroup>

La familia síncrona `/v1/monitor/*` falta a propósito. Todos los motores funcionan de forma asíncrona; una solicitud
que se bloquea durante lo que puede tardar una consulta no es algo que ofrezca este servicio.

## Dónde difiere el comportamiento

<AccordionGroup>
  <Accordion title="1. Sin limitador de tasa: usa lotes" icon="gauge">
    No hay límite de tasa por clave. Para grandes volúmenes, usa el envío en lote y reduce los viajes de ida y vuelta.

    Consulta [Regiones y buenas prácticas](/es/engines/capacity).
  </Accordion>

  <Accordion title="2. Los créditos son por motor" icon="coins">
    `credits` aparece en cada respuesta como parte del sobre. Las respuestas de envío y sondeo informan
    `{ "creditsToCharge": 0, "creditsCharged": 0 }`; los webhooks informan el coste en créditos del motor (1–3 créditos
    según el motor).

    Las tareas fallidas no se cobran. Los saldos de créditos se ven en el panel.
  </Accordion>

  <Accordion title="3. Algunas combinaciones motor × región se rechazan de entrada" icon="ban">
    Una combinación no se puede servir en absoluto: `CHATGPT`/`PERPLEXITY`/`GEMINI` hacia `CN`, donde no hay suministro
    de salida y la solicitud nunca llega al destino. Falla de inmediato con `422 REGION_UNSUPPORTED` en lugar de
    aceptarse. `422 REGION_UNAVAILABLE` cubre la versión transitoria de lo mismo.

    Un cliente que asume que todo envío bien formado se acepta necesita una rama aquí. Consulta [Regiones](/es/engines/capacity).
  </Accordion>

  <Accordion title="4. Los flags include casi no tienen efecto" icon="toggle-left">
    Los flags `payload.include` se aceptan, pero la mayoría de los motores devuelven una respuesta de forma fija y los
    ignoran. Solo ChatGPT respeta el conjunto completo; `GEMINI` respeta solo `markdown` y `rawResponse`.

    Pedir `html` a Gemini, por ejemplo, se ignora en silencio: sin error y sin campo. Consulta la
    [tabla de flags admitidos](/es/engines/overview).
  </Accordion>

  <Accordion title="5. Un código de estado adicional: 422" icon="hash">
    Por lo demás, el manejo de errores es convencional: los fallos de validación devuelven `400`, `401` informa
    `MISSING_API_KEY`, `404` informa `RESOURCE_NOT_FOUND` y `details` nombra el campo problemático.

    La única novedad es el par `422` (`REGION_UNSUPPORTED`, `REGION_UNAVAILABLE`) descrito arriba. Te avisamos de
    antemano cuando una región no se puede servir, así que un cliente que nunca ha manejado un `422` empezará a verlos.
  </Accordion>

  <Accordion title="6. Una tarea fallida añade una cadena `error` de nivel superior" icon="triangle-alert">
    `GET /v1/async/task/{id}` sobre una tarea `FAILED` devuelve un campo `error` de nivel superior que el esquema de
    estado de tarea no define, y es una **cadena simple**, no el objeto `{code, message, timestamp}` de los errores de solicitud.

    ```json theme={null}
    { "success": true, "task": { "status": "FAILED", "...": "..." }, "error": "ENGINE_TIMEOUT: The engine did not answer before the task deadline." }
    ```

    Un cliente que interprete un `body.error` verdadero como una *solicitud* fallida malinterpretará una *tarea* fallida
    que se recuperó correctamente. Ramifica por `task.status`.
  </Accordion>
</AccordionGroup>

<Note>
  Estos comportamientos se establecieron llamando a esta API, no leyendo un esquema. Si alguna vez una especificación
  publicada y una respuesta real no coinciden, estas páginas documentan la respuesta real.
</Note>

## Elegir el `taskType` correcto

Si tu integración actual usa un endpoint por motor, el nombre del motor se corresponde con un `taskType`:

| Llamabas a | `taskType` |
| - | - |
| ChatGPT | `CHATGPT` |
| Perplexity | `PERPLEXITY` |
| Gemini | `GEMINI` |
| Google AI Mode | `AIMODE` |
| Google AI Overview | `GOOGLE` |
| Naver | `NAVER_AI_BRIEF` / `NAVER_AI_TAB` |

<Note>
  Que `GOOGLE` signifique «AI Overview» es una convención de nombres, no un nombre de producto de Google. La
  respuesta es un sobre SERP con `aioverview` como miembro anulable; consulta [la forma de GOOGLE](/es/engines/overview).
</Note>

## Verificar el cambio

Ejecuta en paralelo tu integración actual y esta durante un tiempo, y compara los campos que realmente consumes,
en la práctica `response.text`, `response.sources[]` y `response.markdown`. Una comparación en sombra detecta
diferencias de forma que un chequeo de esquema no ve, como una lista de fuentes rellenada pero ordenada de otra manera.
