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

# Assíncrono e webhooks

> Execute um Canvas em segundo plano, consulte o resultado ou receba-o na sua URL, e liste execuções anteriores

Uma completion síncrona mantém a conexão HTTP aberta até o Canvas terminar. Para documentos longos, lotes ou qualquer cliente que não deva esperar, execute a completion em segundo plano. Há duas formas, e elas compartilham os mesmos objetos:

* **`async: true`**: a API responde de imediato com a execução, e você consulta `GET /v2/chat/completions/{id}` até ela terminar.
* **`webhook_url`**: a execução se torna assíncrona automaticamente, e o Tela envia o resultado por POST para a sua URL quando ela termina.

De qualquer forma, a execução é registrada como uma **completion run**, que você pode consultar depois ou encontrar com `GET /v1/completion-run`.

> [!NOTE]
>
> A `webhook_url` de uma completion avisa sobre aquela única execução. Não é a mesma coisa que os [Eventos da Workstation](https://docs.tela.com/pt/workstation/events/overview.md), que são assinaturas configuradas em um App e disparam para toda tarefa daquele App.

## O objeto da execução

Chamadas assíncronas respondem com a execução em vez de um `chat.completion`. O mesmo objeto é retornado no polling e enviado para o seu webhook. O seu `status` vai de `created` para `running`, e então para `succeeded` ou `failed`.

| Campo | Significado |
| - | - |
| `id` | O ID da execução. Use-o para consultar com `GET /v2/chat/completions/{id}`. |
| `status` | `created`, `running`, `succeeded` ou `failed`. |
| `input_content` | As entradas normalizadas: `variables`, `messages` e os `files` encontrados nelas. |
| `output_content` | A resposta quando a execução termina com sucesso: `role` e `content`, com os campos do seu Formato de Saída quando houver um. Pode incluir `information` com `duration`, `cost`, `input_tokens` e `output_tokens`. |
| `raw_input` | O corpo que você enviou (`canvas_id` ou `version_id`, `variables`, `messages`, `webhook_url`, `override`). |
| `raw_output` | A saída bruta da execução. |
| `prompt_version_id` | A versão que executou. |
| `prompt_application_id` | O App, quando a execução é uma tarefa; `null` para completions. |
| `compatibility_date`, `workspace_id`, `created_at`, `updated_at` | Metadados da execução. |

```json Recém-criada theme={null}
{
    "id": "b83b1558-de5b-4e45-b517-7bececbdd154",
    "status": "created",
    "input_content": {
        "variables": null,
        "messages": [],
        "files": []
    },
    "output_content": null,
    "raw_input": {
        "canvas_id": "95cec438-6080-44fe-8275-28b16bd40178",
        "variables": {
            "document": { "file_url": "https://example.com/document.pdf" }
        },
        "webhook_url": "https://example.com/webhook"
    },
    "raw_output": null,
    "compatibility_date": "2024-10-14",
    "prompt_version_id": "76065caa-c519-441a-8fe2-cc43e29664ab",
    "prompt_application_id": null,
    "workspace_id": "3f55cfd9-4427-4887-a181-d9ad39967802",
    "created_at": "2024-10-14T19:00:53.664Z",
    "updated_at": "2024-10-14T19:00:53.664Z"
}
```

```json Concluída theme={null}
{
    "id": "b83b1558-de5b-4e45-b517-7bececbdd154",
    "status": "succeeded",
    "input_content": {
        "variables": {
            "document": { "file_url": "https://example.com/document.pdf" }
        },
        "messages": [],
        "files": [
            {
                "name": "document",
                "url": "https://example.com/document.pdf",
                "used_at": "variables",
                "type": "file"
            }
        ]
    },
    "output_content": {
        "role": "assistant",
        "content": {
            "fileSummary": "This document contains quarterly financial reports showing a 15% revenue increase compared to last quarter."
        }
    },
    "raw_input": {
        "canvas_id": "95cec438-6080-44fe-8275-28b16bd40178",
        "variables": {
            "document": { "file_url": "https://example.com/document.pdf" }
        },
        "webhook_url": "https://example.com/webhook"
    },
    "raw_output": {
        "fileSummary": "This document contains quarterly financial reports showing a 15% revenue increase compared to last quarter."
    },
    "compatibility_date": "2024-10-14",
    "prompt_version_id": "76065caa-c519-441a-8fe2-cc43e29664ab",
    "prompt_application_id": null,
    "workspace_id": "3f55cfd9-4427-4887-a181-d9ad39967802",
    "created_at": "2024-10-14T19:00:53.664Z",
    "updated_at": "2024-10-14T19:01:15.892Z"
}
```

> [!NOTE]
>
> O que uma execução com `status: "failed"` traz sobre a falha não está documentado aqui. Trate `failed` como final e verifique a execução no **Usage** do Canvas.

## Usando a flag async

Acrescente `async: true` ao corpo. A resposta é a execução com `status: "created"`.

```sh cURL theme={null}
curl -X POST https://api.tela.com/v2/chat/completions \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $TELA_API_KEY" \
    -d '{
        "canvas_id": "95cec438-6080-44fe-8275-28b16bd40178",
        "variables": {
            "document": { "file_url": "https://example.com/document.pdf" }
        },
        "async": true
    }'
```

```typescript TypeScript (fetch) theme={null}
const response = await fetch('https://api.tela.com/v2/chat/completions', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${process.env.TELA_API_KEY}`,
    },
    body: JSON.stringify({
        canvas_id: process.env.TELA_CANVAS_ID,
        variables: {
            document: { file_url: 'https://example.com/document.pdf' },
        },
        async: true,
    }),
})

const run = await response.json()
console.log(run.id, run.status) // "b83b1558-...", "created"
```

```python Python (requests) theme={null}
import os
import requests

response = requests.post(
    "https://api.tela.com/v2/chat/completions",
    headers={"Authorization": f"Bearer {os.getenv('TELA_API_KEY')}"},
    json={
        "canvas_id": os.getenv("TELA_CANVAS_ID"),
        "variables": {
            "document": {"file_url": "https://example.com/document.pdf"},
        },
        "async": True,
    },
)

run = response.json()
print(run["id"], run["status"])  # "b83b1558-...", "created"
```

### Consultando o resultado

Chame `GET /v2/chat/completions/{id}` com o ID da execução até o `status` ser `succeeded` ou `failed`, e então leia `output_content.content`. Os exemplos abaixo iniciam uma execução e a consultam no mesmo script.

```typescript TypeScript (fetch) theme={null}
const headers = {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.TELA_API_KEY}`,
}

// Inicie a execução em segundo plano
const created = await fetch('https://api.tela.com/v2/chat/completions', {
    method: 'POST',
    headers,
    body: JSON.stringify({
        canvas_id: process.env.TELA_CANVAS_ID,
        variables: {
            document: { file_url: 'https://example.com/document.pdf' },
        },
        async: true,
    }),
})

// Depois consulte até ela terminar
let run = await created.json()

while (!['succeeded', 'failed'].includes(run.status)) {
    await new Promise((resolve) => setTimeout(resolve, 2000))
    const poll = await fetch(`https://api.tela.com/v2/chat/completions/${run.id}`, {
        headers,
    })
    run = await poll.json()
}

if (run.status === 'succeeded') {
    console.log(run.output_content.content)
}
```

```python Python (requests) theme={null}
import os
import time
import requests

headers = {"Authorization": f"Bearer {os.getenv('TELA_API_KEY')}"}

# Inicie a execução em segundo plano
created = requests.post(
    "https://api.tela.com/v2/chat/completions",
    headers=headers,
    json={
        "canvas_id": os.getenv("TELA_CANVAS_ID"),
        "variables": {
            "document": {"file_url": "https://example.com/document.pdf"},
        },
        "async": True,
    },
)

# Depois consulte até ela terminar
run = created.json()

while run["status"] not in ("succeeded", "failed"):
    time.sleep(2)
    poll = requests.get(
        f"https://api.tela.com/v2/chat/completions/{run['id']}",
        headers=headers,
    )
    run = poll.json()

if run["status"] == "succeeded":
    print(run["output_content"]["content"])
```

```sh cURL theme={null}
curl https://api.tela.com/v2/chat/completions/b83b1558-de5b-4e45-b517-7bececbdd154 \
    -H "Authorization: Bearer $TELA_API_KEY"
```

## Usando uma URL de webhook

Passe uma `webhook_url` e a execução se torna assíncrona sem a flag `async`. A resposta imediata é a execução com `status: "created"`; quando a execução termina, o Tela envia uma requisição `POST` para a sua URL.

```typescript TypeScript Tela SDK theme={null}
const run = await tela.completions.create<{ document: TelaFile }, { fileSummary: string }>({
    canvasId: process.env.TELA_CANVAS_ID,
    variables: {
        document: tela.createFile('https://www.wmaccess.com/downloads/sample-invoice.pdf'),
    },
    webhookUrl: 'https://example.com/webhook',
})
```

```javascript JavaScript Tela SDK theme={null}
const run = await tela.completions.create({
    canvasId: process.env.TELA_CANVAS_ID,
    variables: {
        document: tela.createFile('https://www.wmaccess.com/downloads/sample-invoice.pdf'),
    },
    webhookUrl: 'https://example.com/webhook',
})
```

```python Python Tela SDK theme={null}
run = client.completions.create(
    canvas_id=TELA_CANVAS_ID,
    variables={
        "document": client.create_file("https://www.wmaccess.com/downloads/sample-invoice.pdf"),
    },
    webhook_url="https://example.com/webhook",
)
```

```sh cURL theme={null}
curl -X POST https://api.tela.com/v2/chat/completions \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $TELA_API_KEY" \
    -d '{
        "canvas_id": "95cec438-6080-44fe-8275-28b16bd40178",
        "variables": {
            "document": { "file_url": "https://www.wmaccess.com/downloads/sample-invoice.pdf" }
        },
        "webhook_url": "https://example.com/webhook"
    }'
```

### O callback

O seu endpoint recebe um `POST` com:

* **Headers**: `Content-Type: application/json` e `x-completion-run-id`, o ID da execução. Use-o para associar o callback à execução que você criou, já que é o mesmo `id` retornado na resposta de criação.
* **Corpo**: o [objeto da execução](#o-objeto-da-execucao) com o seu `status` final (`succeeded` ou `failed`) e, em caso de sucesso, a resposta em `output_content.content` e `raw_output`.

Mantenha o handler rápido: guarde o payload e responda com um `2xx`, e processe depois. Não está documentado aqui se a entrega é repetida quando o seu endpoint falha; se você precisa de garantia, consulte também `GET /v2/chat/completions/{id}` para as execuções que não deram retorno depois de um tempo.

> [!TIP]
>
> Use HTTPS na `webhook_url` e confirme que a requisição veio do Tela antes de confiar nela, por exemplo conferindo o `x-completion-run-id` contra as execuções que você criou. Quando você cria tarefas com `POST /task`, os headers da requisição com o prefixo `x-tela-forward-` são encaminhados para o seu webhook sem o prefixo, o que permite enviar um segredo seu; veja [Autenticação e headers](https://docs.tela.com/pt/workstation/events/authentication.md).

## Listando execuções anteriores

Toda completion, síncrona ou não, é guardada como uma completion run. `GET /v1/completion-run` retorna as execuções do seu Workspace, da mais recentemente atualizada para a mais antiga, para você auditar o que rodou, conciliar um lote ou encontrar uma execução cujo callback você perdeu.

| Parâmetro de query | Efeito |
| - | - |
| `limit`, `offset` | Tamanho da página (padrão 10, de 1 a 100) e número de execuções a pular. |
| `promptId` | Só execuções deste Canvas. |
| `promptVersionId` | Só execuções desta versão. |
| `promptApplicationId` | Só execuções deste App (tarefas). |
| `tags` | Só execuções que contêm todas estas tags, como array JSON (`["a","b"]`) ou separadas por vírgula (`a,b`). |
| `objectLinks` | Quando `true`, `meta.links.*` vêm como objetos em vez de query strings. |

```sh cURL theme={null}
curl "https://api.tela.com/v1/completion-run?promptId=95cec438-6080-44fe-8275-28b16bd40178&tags=batch-1&limit=50" \
    -H "Authorization: Bearer $TELA_API_KEY"
```

A resposta tem um array `data` e um objeto `meta` com `totalCount`, `limit`, `offset`, `currentPage`, `totalPages` e `links` (`first`, `last`, `next`, `previous`). Cada execução tem as mesmas informações do objeto da execução acima, com duas diferenças: as chaves são camelCase (`inputContent`, `rawInput`, `promptVersionId`) e ela acrescenta `tags`, `creditsUsed`, `promptId` e um `metadata` com um retrato da versão que executou (`modelConfigurations`, `variablesDefinitions` e, quando a requisição usou um ambiente, `requestedEnvironmentName`).

```json Resposta theme={null}
{
    "data": [
        {
            "id": "b83b1558-de5b-4e45-b517-7bececbdd154",
            "status": "succeeded",
            "inputContent": { "variables": { "document": { "files": [ { "file_url": "https://example.com/document.pdf" } ] } }, "messages": [], "files": [] },
            "outputContent": { "role": "assistant", "content": { "fileSummary": "Quarterly financial report with a 15% revenue increase." } },
            "rawInput": { "canvas_id": "95cec438-6080-44fe-8275-28b16bd40178", "variables": { "document": { "file_url": "https://example.com/document.pdf" } } },
            "rawOutput": { "fileSummary": "Quarterly financial report with a 15% revenue increase." },
            "compatibilityDate": "2024-10-14",
            "metadata": {
                "promptVersion": {
                    "modelConfigurations": { "model": "gpt-4o", "type": "chat" },
                    "variablesDefinitions": [ { "name": "document", "type": "file", "required": true } ]
                }
            },
            "tags": ["batch-1"],
            "creditsUsed": 3,
            "promptId": "95cec438-6080-44fe-8275-28b16bd40178",
            "promptVersionId": "76065caa-c519-441a-8fe2-cc43e29664ab",
            "promptApplicationId": null,
            "workspaceId": "3f55cfd9-4427-4887-a181-d9ad39967802",
            "createdAt": "2024-10-14T19:00:53.664Z",
            "updatedAt": "2024-10-14T19:01:15.892Z",
            "deletedAt": null
        }
    ],
    "meta": {
        "totalCount": 1,
        "limit": 50,
        "offset": 0,
        "currentPage": 1,
        "totalPages": 1,
        "links": { "first": "?promptId=95cec438-6080-44fe-8275-28b16bd40178&tags=batch-1&limit=50&offset=0", "last": "?promptId=95cec438-6080-44fe-8275-28b16bd40178&tags=batch-1&limit=50&offset=0", "next": null, "previous": null }
    }
}
```

Listar execuções exige o papel `member` ou superior; chaves de API do Workspace atendem a isso. Quando você filtra por `promptId`, `promptVersionId` ou `promptApplicationId`, o recurso precisa estar acessível para a sua chave, caso contrário a chamada retorna `404`.

> [!TIP]
>
> Envie uma [tag](https://docs.tela.com/pt/tags.md#enviando-tags-via-api) que identifique o seu lote ou o ID do seu próprio registro em cada requisição (por exemplo `order-123`) e filtre por ela aqui. É a forma mais simples de reencontrar uma execução sem guardar todos os IDs.

Para ler uma execução pelo ID a qualquer momento, use `GET /v2/chat/completions/{id}`, como em [Consultando o resultado](#consultando-o-resultado). Os detalhes completos de parâmetros e schemas estão na referência da API: [Run Canvas](https://docs.tela.com/api-reference/completion/create.md), [Retrieve Canvas Run](https://docs.tela.com/api-reference/completion/get.md) e [List completion runs](https://docs.tela.com/api-reference/completion-run/get-v1-completion-run.md).


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