---
title: "POST /_agilink/recovery/detection/attempt"
description: "Detecção opcional: attempt"
sidebar:
  hidden: true
---

Operação pública/SDK existente, separada da Platform API administrativa. [Guia funcional](/sdk/contratos-publicos/) · [Índice dos 13 endpoints](/sdk/endpoints-publicos/) · [Schemas navegáveis](/contratos-publicos/) · [JSON Schema](/contracts/public-openapi.json). Não envie Authorization administrativo. Tokens/capacidades transitórias dos exemplos são fictícios.


## POST /_agilink/recovery/detection/attempt

Detecção opcional: attempt. Contrato público existente, separado de administração. Detecção exige opt-in; não chamar sua rota Edge interna diretamente. Capacidades e validade são revalidadas no servidor.

Base de exemplo: `https://go.agilink.invalid`.

| Campo | Tipo | Obrigatório |
| --- | --- | --- |
| `appId` | string | sim |
| `challenge` | string | sim |
| `attemptId` | string | sim |
| `signals` | DetectionSignals | sim |

```json
{
  "appId": "app_loja",
  "challenge": "<challenge-assinado>",
  "attemptId": "80000000-0000-4000-8000-000000000002",
  "signals": {
    "platform": "ios",
    "family": "iphone",
    "osVersion": "18.0",
    "language": "pt-BR",
    "timezone": "America/Sao_Paulo",
    "screen": {
      "width": 390,
      "height": 844,
      "scale": 3
    }
  }
}
```

```sh
curl --request POST 'https://go.agilink.invalid/_agilink/recovery/detection/attempt' \
  --header 'Content-Type: application/json' \
  --data '{"appId":"app_loja","challenge":"<challenge-assinado>","attemptId":"80000000-0000-4000-8000-000000000002","signals":{"platform":"ios","family":"iphone","osVersion":"18.0","language":"pt-BR","timezone":"America/Sao_Paulo","screen":{"width":390,"height":844,"scale":3}}}'
```

Resposta `200`: Sucesso; exemplos fictícios. ACKs de telemetria devem ser lidos por evento.

```json
{
  "version": 1,
  "mode": "detection",
  "status": "no_match",
  "reason": "no_candidate",
  "policyVersion": "agilink-shadow-v4-context"
}
```

Erros documentados: `400`, `403`, `404`, `405`, `409`, `410`, `413`, `415`, `429`, `502`, `503`. Erros do Worker podem ter corpo vazio. Etapas de recuperação podem responder `200 {"accepted":false}`; ACK HTTP não significa conteúdo exibido. Consulte os schemas e o guia para condições, validade, retry e envelopes.

## JavaScript / TypeScript

```js
const response = await fetch("https://go.agilink.invalid/_agilink/recovery/detection/attempt", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({"appId":"app_loja","challenge":"<challenge-assinado>","attemptId":"80000000-0000-4000-8000-000000000002","signals":{"platform":"ios","family":"iphone","osVersion":"18.0","language":"pt-BR","timezone":"America/Sao_Paulo","screen":{"width":390,"height":844,"scale":3}}}) });
if (!response.ok) throw new Error('HTTP ' + response.status);
const result = await response.json();
// Confira accepted e o ACK de cada evento. Não registre tokens transitórios.
```

## Python

```python
import json
import requests
payload = json.loads("{\"appId\":\"app_loja\",\"challenge\":\"<challenge-assinado>\",\"attemptId\":\"80000000-0000-4000-8000-000000000002\",\"signals\":{\"platform\":\"ios\",\"family\":\"iphone\",\"osVersion\":\"18.0\",\"language\":\"pt-BR\",\"timezone\":\"America/Sao_Paulo\",\"screen\":{\"width\":390,\"height\":844,\"scale\":3}}}")
response = requests.request("POST", "https://go.agilink.invalid/_agilink/recovery/detection/attempt", json=payload, timeout=30)
response.raise_for_status()
result = response.json()
# Confira accepted/ACK, sem registrar tokens transitórios.
```

## Campos, limites e semântica

Os schemas abaixo descrevem obrigatoriedade, tipos, defaults, enums e limites; referências apontam para components.schemas do contrato baixável. Omitir opcionais usa o comportamento do contrato; null só é aceito onde declarado. A API pública não usa os envelopes, If-Match ou Idempotency-Key administrativos. Eventos e etapas de recuperação usam seus próprios IDs, deduplicação e capacidade transitória. Não repita um resgate como se fosse leitura: consulte o estado e os limites do [ciclo de recuperação](/sdk/contratos-publicos/). A resolução não gera clique administrativo; telemetria é client_reported. Associação nativa publicada exige verificação em aparelho. Sem paginação administrativa; requests não concedem acesso de gerenciamento.

### Request schema

```json
{
  "type": "object",
  "properties": {
    "appId": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1
    },
    "challenge": {
      "type": "string",
      "maxLength": 2000
    },
    "attemptId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$"
    },
    "signals": {
      "$ref": "#/components/schemas/DetectionSignals"
    }
  },
  "required": [
    "appId",
    "challenge",
    "attemptId",
    "signals"
  ],
  "additionalProperties": true
}
```

### Response schema

```json
{
  "type": "object",
  "properties": {
    "version": {
      "const": 1
    },
    "mode": {
      "const": "detection"
    },
    "status": {
      "enum": [
        "candidate",
        "confirm_candidate",
        "ambiguous",
        "no_match"
      ]
    },
    "policyVersion": {
      "type": "string",
      "maxLength": 200
    },
    "reason": {
      "type": "string",
      "maxLength": 200
    },
    "candidate": {
      "type": "object",
      "properties": {
        "clickId": {
          "type": "string",
          "format": "uuid",
          "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$"
        },
        "linkId": {
          "type": "string",
          "maxLength": 650
        },
        "publicUri": {
          "type": "string",
          "format": "uri"
        },
        "score": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100
        }
      },
      "required": [
        "clickId",
        "linkId",
        "publicUri",
        "score"
      ],
      "additionalProperties": false
    },
    "receipt": {
      "type": "string",
      "maxLength": 1500
    }
  },
  "required": [
    "version",
    "mode",
    "status",
    "policyVersion"
  ],
  "additionalProperties": false
}
```

Headers: Content-Type application/json nas respostas JSON. Erros aplicáveis são os listados acima e podem ter corpo vazio; 429 exige respeitar Retry-After quando fornecido, sem tentativas ilimitadas. Não trate HTTP 200/ACK como confirmação de conteúdo exibido, instalação ou detecção certa.
