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

# Extração de Dados - FlexExtractor

> Extraia informações estruturadas de documentos através de OCR inteligente

## Visão Geral

A API FlexOCR Extract permite extrair informações de documentos de forma automática utilizando OCR (Reconhecimento Ótico de Caracteres) com inteligência artificial. Envie a imagem do documento em Base64 e receba os dados estruturados em JSON.

<CardGroup cols={2}>
  <Card title="OCR Inteligente" icon="brain">
    Reconhecimento automático com IA
  </Card>

  <Card title="Múltiplos Documentos" icon="id-card">
    Suporte para RG, CNH, CPF e mais
  </Card>

  <Card title="Classificação Automática" icon="robot">
    Identifica o tipo do documento automaticamente
  </Card>

  <Card title="Dados Estruturados" icon="table">
    Retorna campos com coordenadas e confiança
  </Card>
</CardGroup>

***

## Fluxo de Extração

<Steps>
  <Step title="Autenticação">
    Obtenha um access\_token válido via `/api/v2/Security/GetToken`
  </Step>

  <Step title="Preparar Imagem">
    Converta o documento para Base64 (PDF, JPG, PNG)
  </Step>

  <Step title="Enviar Requisição">
    POST com imagem Base64 e tipo de documento (opcional)
  </Step>

  <Step title="Receber Dados Extraídos">
    API retorna campos identificados com nome, valor e confiança
  </Step>
</Steps>

***

## Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token obtido via `/api/v2/Security/GetToken`

  **Formato:** `Bearer {access_token}`

  **Exemplo:** `Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...`
</ParamField>

***

## Request Body

<Note>
  Use o playground **"Try It"** à direita para testar a API diretamente! →
</Note>

<ParamField body="imageBase64" type="string" required>
  Imagem do documento codificada em Base64

  **Formatos aceitos:** PDF, JPG, JPEG, PNG

  **Tamanho máximo recomendado:** 10MB

  **Exemplo:**

  ```json theme={"theme":"catppuccin-latte"}
  "JVBERi0xLjMNCiXi48/TDQoyIDAgb2J....AAAAAAAAAAA"
  ```

  <Tip>
    Para melhor precisão, use imagens com:

    * Resolução mínima de 300 DPI
    * Boa iluminação
    * Documento completo e legível
    * Sem cortes ou reflexos
  </Tip>
</ParamField>

<ParamField body="typealias" type="string">
  Tipo do documento a ser processado. Se não informado, o sistema identifica automaticamente.

  **Valores aceitos:**

  | Tipo         | Descrição                        |
  | ------------ | -------------------------------- |
  | `RG`         | Registro Geral (Identidade)      |
  | `CNH`        | Carteira Nacional de Habilitação |
  | `CPF`        | Cadastro de Pessoa Física        |
  | `CE_CEMIG`   | Conta de Energia CEMIG           |
  | `PASSAPORTE` | Passaporte brasileiro            |
  | `CTPS`       | Carteira de Trabalho             |

  **Exemplo:** `"RG"`

  <Info>
    Informar o tipo correto melhora a precisão e velocidade da extração
  </Info>
</ParamField>

<ParamField body="cpf" type="string">
  CPF relacionado ao documento (opcional). Usado para validação cruzada.

  **Formato:** Apenas números (11 dígitos)

  **Exemplo:** `"12345678901"`

  <Note>
    O CPF informado pode ser usado para validar dados extraídos do documento
  </Note>
</ParamField>

***

## Response

<ResponseField name="ocrResult" type="object" required>
  Objeto contendo os resultados da extração OCR

  <Expandable title="Estrutura completa">
    <ResponseField name="ocrResult.typeRecognized" type="string">
      Tipo de documento reconhecido automaticamente

      **Exemplo:** `"RG"`, `"CNH"`, `"CPF"`
    </ResponseField>

    <ResponseField name="ocrResult.digitalDocument" type="boolean">
      Indica se o documento é digital (true) ou físico (false)
    </ResponseField>

    <ResponseField name="ocrResult.fields" type="array">
      Array de campos extraídos do documento

      **Estrutura de cada campo:**

      * `name` (string): Nome do campo extraído
      * `value` (string): Valor extraído
      * `boundingBox` (array): Coordenadas \[x1, y1, x2, y2] do campo na imagem
      * `confidence` (integer): Nível de confiança (0-100)

      **Exemplo:**

      ```json theme={"theme":"catppuccin-latte"}
      {
        "name": "NOME",
        "value": "JOÃO DA SILVA",
        "boundingBox": [83, 56, 92, 206],
        "confidence": 98
      }
      ```
    </ResponseField>

    <ResponseField name="ocrResult.statistics" type="object">
      Estatísticas de processamento (tempo em milissegundos)

      * `convert`: Tempo de conversão da imagem
      * `ocr1`: Tempo do primeiro processamento OCR
      * `ocr2`: Tempo do segundo processamento OCR (se aplicável)
      * `parse`: Tempo de parsing dos dados
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="isSuccesful" type="boolean" required>
  Indica se a extração foi bem-sucedida

  * `true`: Dados extraídos com sucesso
  * `false`: Erro na extração (verifique campo `error`)
</ResponseField>

<ResponseField name="statusCode" type="integer" required>
  Código HTTP de status da operação

  **Valores comuns:**

  * `200`: Sucesso
  * `400`: Requisição inválida
  * `401`: Token inválido ou expirado
  * `500`: Erro interno no servidor
</ResponseField>

<ResponseField name="timestamp" type="string" required>
  Data e hora da extração (formato ISO 8601)

  **Exemplo:** `"2025-01-09T11:01:39.6009905-03:00"`
</ResponseField>

<ResponseField name="requestUri" type="string">
  URI da requisição (quando disponível)
</ResponseField>

<ResponseField name="error" type="string">
  Mensagem de erro (presente apenas quando `isSuccesful: false`)

  **Exemplos:**

  * `"Invalid image format"`
  * `"Image too large"`
  * `"Unable to recognize document type"`
</ResponseField>

<ResponseExample>
  ```json Sucesso - RG (200 OK) theme={"theme":"catppuccin-latte"}
  {
    "ocrResult": {
      "typeRecognized": "RG",
      "digitalDocument": false,
      "fields": [
        {
          "name": "NOME",
          "value": "JOÃO DA SILVA",
          "boundingBox": [83, 56, 92, 206],
          "confidence": 98
        },
        {
          "name": "RG",
          "value": "12.345.678-9",
          "boundingBox": [95, 58, 102, 155],
          "confidence": 95
        },
        {
          "name": "CPF",
          "value": "123.456.789-01",
          "boundingBox": [133, 79, 140, 149],
          "confidence": 92
        },
        {
          "name": "DATA_NASCIMENTO",
          "value": "15/03/1990",
          "boundingBox": [145, 82, 152, 178],
          "confidence": 100
        },
        {
          "name": "NOME_PAI",
          "value": "JOSÉ DA SILVA",
          "boundingBox": [165, 88, 172, 220],
          "confidence": 89
        },
        {
          "name": "NOME_MAE",
          "value": "MARIA DA SILVA",
          "boundingBox": [185, 91, 192, 225],
          "confidence": 94
        },
        {
          "name": "DATA_EXPEDICAO",
          "value": "20/01/2015",
          "boundingBox": [205, 95, 212, 165],
          "confidence": 97
        },
        {
          "name": "ORGAO_EXPEDIDOR",
          "value": "SSP/SP",
          "boundingBox": [215, 98, 222, 145],
          "confidence": 100
        }
      ],
      "statistics": {
        "convert": 901,
        "ocr1": 2370,
        "ocr2": 0,
        "parse": 1294
      }
    },
    "isSuccesful": true,
    "statusCode": 200,
    "timestamp": "2025-01-09T11:01:39.6009905-03:00"
  }
  ```

  ```json Sucesso - CNH (200 OK) theme={"theme":"catppuccin-latte"}
  {
    "ocrResult": {
      "typeRecognized": "CNH",
      "digitalDocument": true,
      "fields": [
        {
          "name": "NOME",
          "value": "MARIA SANTOS",
          "boundingBox": [75, 45, 85, 198],
          "confidence": 99
        },
        {
          "name": "CPF",
          "value": "987.654.321-00",
          "boundingBox": [95, 52, 102, 156],
          "confidence": 100
        },
        {
          "name": "REGISTRO_CNH",
          "value": "12345678901",
          "boundingBox": [110, 58, 118, 175],
          "confidence": 98
        },
        {
          "name": "DATA_NASCIMENTO",
          "value": "22/08/1985",
          "boundingBox": [125, 62, 132, 168],
          "confidence": 97
        },
        {
          "name": "CATEGORIA",
          "value": "AB",
          "boundingBox": [140, 68, 145, 95],
          "confidence": 100
        },
        {
          "name": "DATA_PRIMEIRA_HABILITACAO",
          "value": "10/05/2005",
          "boundingBox": [155, 72, 162, 172],
          "confidence": 95
        },
        {
          "name": "DATA_VALIDADE",
          "value": "22/08/2030",
          "boundingBox": [170, 78, 177, 168],
          "confidence": 99
        }
      ],
      "statistics": {
        "convert": 654,
        "ocr1": 1875,
        "ocr2": 0,
        "parse": 987
      }
    },
    "isSuccesful": true,
    "statusCode": 200,
    "timestamp": "2025-01-09T14:23:15.4521098-03:00"
  }
  ```

  ```json Erro 401 - Token Inválido theme={"theme":"catppuccin-latte"}
  {
    "isSuccesful": false,
    "statusCode": 401,
    "timestamp": "2025-01-09T11:05:22.1234567-03:00",
    "error": "Unauthorized: Invalid or expired token"
  }
  ```

  ```json Erro 400 - Imagem Inválida theme={"theme":"catppuccin-latte"}
  {
    "isSuccesful": false,
    "statusCode": 400,
    "timestamp": "2025-01-09T11:07:45.9876543-03:00",
    "error": "Invalid image format. Supported formats: PDF, JPG, PNG"
  }
  ```
</ResponseExample>

***

## Campos Extraídos por Tipo de Documento

<AccordionGroup>
  <Accordion title="RG - Registro Geral" icon="id-card">
    ### Campos Comuns Extraídos:

    | Campo             | Descrição               | Exemplo          |
    | ----------------- | ----------------------- | ---------------- |
    | `NOME`            | Nome completo           | "JOÃO DA SILVA"  |
    | `RG`              | Número do RG            | "12.345.678-9"   |
    | `CPF`             | Número do CPF           | "123.456.789-01" |
    | `DATA_NASCIMENTO` | Data de nascimento      | "15/03/1990"     |
    | `NOME_PAI`        | Nome do pai             | "JOSÉ DA SILVA"  |
    | `NOME_MAE`        | Nome da mãe             | "MARIA DA SILVA" |
    | `DATA_EXPEDICAO`  | Data de expedição       | "20/01/2015"     |
    | `ORGAO_EXPEDIDOR` | Órgão expedidor         | "SSP/SP"         |
    | `NATURALIDADE`    | Cidade/UF de nascimento | "SÃO PAULO/SP"   |

    <Note>
      Os campos extraídos podem variar conforme o modelo do RG (antigo ou novo)
    </Note>
  </Accordion>

  <Accordion title="CNH - Carteira Nacional de Habilitação" icon="id-card-clip">
    ### Campos Comuns Extraídos:

    | Campo                       | Descrição              | Exemplo             |
    | --------------------------- | ---------------------- | ------------------- |
    | `NOME`                      | Nome completo          | "MARIA SANTOS"      |
    | `CPF`                       | Número do CPF          | "987.654.321-00"    |
    | `REGISTRO_CNH`              | Número de registro     | "12345678901"       |
    | `DATA_NASCIMENTO`           | Data de nascimento     | "22/08/1985"        |
    | `CATEGORIA`                 | Categoria da CNH       | "AB"                |
    | `DATA_PRIMEIRA_HABILITACAO` | Data da 1ª habilitação | "10/05/2005"        |
    | `DATA_VALIDADE`             | Data de validade       | "22/08/2030"        |
    | `NOME_PAI`                  | Nome do pai            | "JOSÉ SANTOS"       |
    | `NOME_MAE`                  | Nome da mãe            | "ANA SANTOS"        |
    | `LOCAL_NASCIMENTO`          | Local de nascimento    | "RIO DE JANEIRO/RJ" |
    | `RG`                        | Número do RG           | "98.765.432-1"      |

    <Info>
      CNH digital possui campo `digitalDocument: true`
    </Info>
  </Accordion>

  <Accordion title="CPF - Cadastro de Pessoa Física" icon="card">
    ### Campos Comuns Extraídos:

    | Campo                | Descrição          | Exemplo           |
    | -------------------- | ------------------ | ----------------- |
    | `NOME`               | Nome completo      | "CARLOS OLIVEIRA" |
    | `CPF`                | Número do CPF      | "111.222.333-44"  |
    | `DATA_NASCIMENTO`    | Data de nascimento | "05/12/1978"      |
    | `SITUACAO_CADASTRAL` | Situação do CPF    | "REGULAR"         |
  </Accordion>

  <Accordion title="CE_CEMIG - Conta de Energia CEMIG" icon="bolt">
    ### Campos Comuns Extraídos:

    | Campo               | Descrição          | Exemplo            |
    | ------------------- | ------------------ | ------------------ |
    | `NOME_CLIENTE`      | Nome do cliente    | "JOÃO DA SILVA"    |
    | `CPF_CNPJ`          | CPF ou CNPJ        | "123.456.789-01"   |
    | `NUMERO_INSTALACAO` | Nº da instalação   | "123456789"        |
    | `ENDERECO`          | Endereço completo  | "RUA EXEMPLO, 123" |
    | `VENCIMENTO`        | Data de vencimento | "15/02/2025"       |
    | `VALOR_TOTAL`       | Valor da conta     | "R\$ 250,00"       |
    | `MES_REFERENCIA`    | Mês de referência  | "JAN/2025"         |

    <Tip>
      Use `typealias: "CE_CEMIG"` para contas da CEMIG
    </Tip>
  </Accordion>
</AccordionGroup>

***

## Exemplos de Código

<CodeGroup>
  ```bash cURL theme={"theme":"catppuccin-latte"}
  # Primeiro, obtenha o token
  TOKEN=$(curl -X POST "https://hml.flexextractor.com.br/api/v2/Security/GetToken" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "username=seu_username" \
    -d "password=sua_senha" | jq -r '.access_token')

  # Depois, extraia dados do documento
  curl -X POST "https://hml.flexextractor.com.br/api/v2/FlexOCR/Extract/Json" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "typealias": "RG",
      "imageBase64": "JVBERi0xLjMNCiXi48/TDQoyIDAgb2J..."
    }'
  ```

  ```javascript JavaScript (Node.js) theme={"theme":"catppuccin-latte"}
  const axios = require('axios');
  const fs = require('fs');

  // Função auxiliar para converter imagem para Base64
  function imageToBase64(filePath) {
    const imageBuffer = fs.readFileSync(filePath);
    return imageBuffer.toString('base64');
  }

  // Função principal de extração
  async function extractDocumentData(accessToken, imagePath, docType = null) {
    const imageBase64 = imageToBase64(imagePath);

    const requestBody = {
      imageBase64: imageBase64
    };

    // Adiciona tipo de documento se informado
    if (docType) {
      requestBody.typealias = docType;
    }

    try {
      const response = await axios.post(
        'https://hml.flexextractor.com.br/api/v2/FlexOCR/Extract/Json',
        requestBody,
        {
          headers: {
            'Authorization': `Bearer ${accessToken}`,
            'Content-Type': 'application/json'
          }
        }
      );

      const { ocrResult, isSuccesful, statusCode } = response.data;

      if (isSuccesful) {
        console.log('✓ Extração realizada com sucesso!');
        console.log(`Tipo reconhecido: ${ocrResult.typeRecognized}`);
        console.log(`Campos extraídos: ${ocrResult.fields.length}`);
        console.log('\nDados extraídos:');

        ocrResult.fields.forEach(field => {
          console.log(`  ${field.name}: ${field.value} (confiança: ${field.confidence}%)`);
        });

        return ocrResult;
      } else {
        console.error('✗ Erro na extração:', response.data.error);
        return null;
      }
    } catch (error) {
      console.error('✗ Erro na requisição:', error.response?.data || error.message);
      throw error;
    }
  }

  // Uso
  const token = 'seu_access_token_aqui';
  extractDocumentData(token, './documento_rg.jpg', 'RG');
  ```

  ```python Python theme={"theme":"catppuccin-latte"}
  import requests
  import base64
  import json

  def image_to_base64(file_path: str) -> str:
      """Converte imagem para Base64"""
      with open(file_path, 'rb') as image_file:
          return base64.b64encode(image_file.read()).decode('utf-8')

  def extract_document_data(access_token: str, image_path: str, doc_type: str = None):
      """
      Extrai dados de documento usando FlexExtractor

      Args:
          access_token: Token de autenticação
          image_path: Caminho do arquivo de imagem
          doc_type: Tipo do documento (RG, CNH, etc) - opcional

      Returns:
          dict: Dados extraídos do documento
      """
      url = "https://hml.flexextractor.com.br/api/v2/FlexOCR/Extract/Json"

      # Converte imagem para Base64
      image_base64 = image_to_base64(image_path)

      # Monta corpo da requisição
      payload = {
          "imageBase64": image_base64
      }

      if doc_type:
          payload["typealias"] = doc_type

      headers = {
          'Authorization': f'Bearer {access_token}',
          'Content-Type': 'application/json'
      }

      try:
          response = requests.post(url, json=payload, headers=headers)
          response.raise_for_status()

          result = response.json()

          if result['isSuccesful']:
              ocr_result = result['ocrResult']
              print(f"✓ Extração realizada com sucesso!")
              print(f"Tipo reconhecido: {ocr_result['typeRecognized']}")
              print(f"Campos extraídos: {len(ocr_result['fields'])}")
              print("\nDados extraídos:")

              for field in ocr_result['fields']:
                  print(f"  {field['name']}: {field['value']} "
                        f"(confiança: {field['confidence']}%)")

              return ocr_result
          else:
              print(f"✗ Erro na extração: {result.get('error')}")
              return None

      except requests.exceptions.RequestException as e:
          print(f"✗ Erro na requisição: {e}")
          raise

  # Uso
  if __name__ == "__main__":
      token = "seu_access_token_aqui"
      data = extract_document_data(token, "./documento_rg.jpg", "RG")
  ```

  ```java Java theme={"theme":"catppuccin-latte"}
  import java.io.*;
  import java.net.http.*;
  import java.net.*;
  import java.nio.file.*;
  import java.util.*;
  import com.google.gson.*;

  public class FlexExtractorClient {

      private static final String EXTRACT_URL =
          "https://hml.flexextractor.com.br/api/v2/FlexOCR/Extract/Json";

      // Classe para resposta OCR
      public static class OcrField {
          public String name;
          public String value;
          public int[] boundingBox;
          public int confidence;
      }

      public static class OcrResult {
          public String typeRecognized;
          public boolean digitalDocument;
          public List<OcrField> fields;
          public Map<String, Integer> statistics;
      }

      public static class ExtractResponse {
          public OcrResult ocrResult;
          public boolean isSuccesful;
          public int statusCode;
          public String timestamp;
          public String error;
      }

      // Converte imagem para Base64
      private static String imageToBase64(String filePath) throws IOException {
          byte[] fileContent = Files.readAllBytes(Paths.get(filePath));
          return Base64.getEncoder().encodeToString(fileContent);
      }

      // Extrai dados do documento
      public static ExtractResponse extractDocumentData(
              String accessToken,
              String imagePath,
              String docType) throws Exception {

          String imageBase64 = imageToBase64(imagePath);

          // Monta JSON do request
          Map<String, String> requestBody = new HashMap<>();
          requestBody.put("imageBase64", imageBase64);

          if (docType != null && !docType.isEmpty()) {
              requestBody.put("typealias", docType);
          }

          Gson gson = new Gson();
          String jsonBody = gson.toJson(requestBody);

          HttpClient client = HttpClient.newHttpClient();
          HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create(EXTRACT_URL))
              .header("Authorization", "Bearer " + accessToken)
              .header("Content-Type", "application/json")
              .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
              .build();

          HttpResponse<String> response = client.send(request,
              HttpResponse.BodyHandlers.ofString());

          ExtractResponse result = gson.fromJson(
              response.body(),
              ExtractResponse.class
          );

          if (result.isSuccesful) {
              System.out.println("✓ Extração realizada com sucesso!");
              System.out.println("Tipo: " + result.ocrResult.typeRecognized);
              System.out.println("Campos: " + result.ocrResult.fields.size());
              System.out.println("\nDados extraídos:");

              for (OcrField field : result.ocrResult.fields) {
                  System.out.printf("  %s: %s (confiança: %d%%)\n",
                      field.name, field.value, field.confidence);
              }
          } else {
              System.err.println("✗ Erro: " + result.error);
          }

          return result;
      }

      public static void main(String[] args) {
          try {
              String token = "seu_access_token_aqui";
              extractDocumentData(token, "./documento_rg.jpg", "RG");
          } catch (Exception e) {
              System.err.println("Erro: " + e.getMessage());
          }
      }
  }
  ```

  ```php PHP theme={"theme":"catppuccin-latte"}
  <?php

  function imageToBase64($filePath) {
      $imageData = file_get_contents($filePath);
      return base64_encode($imageData);
  }

  function extractDocumentData($accessToken, $imagePath, $docType = null) {
      $url = 'https://hml.flexextractor.com.br/api/v2/FlexOCR/Extract/Json';

      // Converte imagem para Base64
      $imageBase64 = imageToBase64($imagePath);

      // Monta payload
      $payload = [
          'imageBase64' => $imageBase64
      ];

      if ($docType) {
          $payload['typealias'] = $docType;
      }

      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, [
          'Authorization: Bearer ' . $accessToken,
          'Content-Type: application/json'
      ]);

      $response = curl_exec($ch);
      $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      curl_close($ch);

      $result = json_decode($response, true);

      if ($result['isSuccesful']) {
          $ocrResult = $result['ocrResult'];
          echo "✓ Extração realizada com sucesso!\n";
          echo "Tipo: {$ocrResult['typeRecognized']}\n";
          echo "Campos: " . count($ocrResult['fields']) . "\n\n";
          echo "Dados extraídos:\n";

          foreach ($ocrResult['fields'] as $field) {
              echo "  {$field['name']}: {$field['value']} ";
              echo "(confiança: {$field['confidence']}%)\n";
          }

          return $ocrResult;
      } else {
          echo "✗ Erro: {$result['error']}\n";
          return null;
      }
  }

  // Uso
  $token = 'seu_access_token_aqui';
  extractDocumentData($token, './documento_rg.jpg', 'RG');
  ?>
  ```

  ```go Go theme={"theme":"catppuccin-latte"}
  package main

  import (
      "bytes"
      "encoding/base64"
      "encoding/json"
      "fmt"
      "io"
      "net/http"
      "os"
  )

  type OcrField struct {
      Name        string  `json:"name"`
      Value       string  `json:"value"`
      BoundingBox []int   `json:"boundingBox"`
      Confidence  int     `json:"confidence"`
  }

  type OcrResult struct {
      TypeRecognized   string               `json:"typeRecognized"`
      DigitalDocument  bool                 `json:"digitalDocument"`
      Fields           []OcrField           `json:"fields"`
      Statistics       map[string]int       `json:"statistics"`
  }

  type ExtractResponse struct {
      OcrResult   OcrResult `json:"ocrResult"`
      IsSuccesful bool      `json:"isSuccesful"`
      StatusCode  int       `json:"statusCode"`
      Timestamp   string    `json:"timestamp"`
      Error       string    `json:"error,omitempty"`
  }

  func imageToBase64(filePath string) (string, error) {
      data, err := os.ReadFile(filePath)
      if err != nil {
          return "", err
      }
      return base64.StdEncoding.EncodeToString(data), nil
  }

  func extractDocumentData(accessToken, imagePath, docType string) (*ExtractResponse, error) {
      url := "https://hml.flexextractor.com.br/api/v2/FlexOCR/Extract/Json"

      imageBase64, err := imageToBase64(imagePath)
      if err != nil {
          return nil, err
      }

      payload := map[string]string{
          "imageBase64": imageBase64,
      }

      if docType != "" {
          payload["typealias"] = docType
      }

      jsonData, err := json.Marshal(payload)
      if err != nil {
          return nil, err
      }

      req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
      if err != nil {
          return nil, err
      }

      req.Header.Set("Authorization", "Bearer "+accessToken)
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          return nil, err
      }
      defer resp.Body.Close()

      body, err := io.ReadAll(resp.Body)
      if err != nil {
          return nil, err
      }

      var result ExtractResponse
      if err := json.Unmarshal(body, &result); err != nil {
          return nil, err
      }

      if result.IsSuccesful {
          fmt.Println("✓ Extração realizada com sucesso!")
          fmt.Printf("Tipo: %s\n", result.OcrResult.TypeRecognized)
          fmt.Printf("Campos: %d\n\n", len(result.OcrResult.Fields))
          fmt.Println("Dados extraídos:")

          for _, field := range result.OcrResult.Fields {
              fmt.Printf("  %s: %s (confiança: %d%%)\n",
                  field.Name, field.Value, field.Confidence)
          }
      } else {
          fmt.Printf("✗ Erro: %s\n", result.Error)
      }

      return &result, nil
  }

  func main() {
      token := "seu_access_token_aqui"
      _, err := extractDocumentData(token, "./documento_rg.jpg", "RG")
      if err != nil {
          fmt.Printf("Erro: %v\n", err)
      }
  }
  ```
</CodeGroup>

***

## Boas Práticas

<AccordionGroup>
  <Accordion title="Qualidade de Imagem" icon="image">
    **Recomendações:**

    * **Resolução:** Mínimo 300 DPI, ideal 600 DPI
    * **Formato:** PDF para documentos digitalizados, JPG/PNG para fotos
    * **Iluminação:** Uniforme, sem sombras ou reflexos
    * **Foco:** Imagem nítida, sem desfoque
    * **Enquadramento:** Documento completo, sem cortes
    * **Tamanho:** Máximo 10MB por imagem

    **Evite:**

    * Imagens desfocadas ou tremidas
    * Flash direto (causa reflexos)
    * Documentos dobrados ou amassados
    * Baixa resolução (\< 150 DPI)
    * Imagens muito comprimidas (qualidade baixa)
  </Accordion>

  <Accordion title="Performance" icon="gauge-high">
    **Otimização de Requisições:**

    * Reutilize o access\_token enquanto válido
    * Implemente cache de resultados quando aplicável
    * Processe em lote quando possível
    * Use compressão de imagem antes de Base64

    **Monitoramento:**

    * Registre tempos de resposta (campo `statistics`)
    * Monitore taxa de sucesso (`isSuccesful`)
    * Acompanhe níveis de confiança médios
    * Configure alertas para falhas recorrentes

    **Exemplo de estatísticas:**

    ```json theme={"theme":"catppuccin-latte"}
    {
      "statistics": {
        "convert": 901,   // Conversão: ~1s
        "ocr1": 2370,     // OCR principal: ~2.4s
        "ocr2": 0,        // OCR secundário: não usado
        "parse": 1294     // Parsing: ~1.3s
      }
      // Total: ~4.5 segundos
    }
    ```
  </Accordion>

  <Accordion title="Confiança e Validação" icon="check-circle">
    **Interpretando Confidence:**

    | Nível     | %      | Ação Recomendada             |
    | --------- | ------ | ---------------------------- |
    | Excelente | 95-100 | Aceitar automaticamente      |
    | Bom       | 85-94  | Aceitar com revisão opcional |
    | Regular   | 70-84  | Revisar manualmente          |
    | Baixo     | \< 70  | Solicitar nova imagem        |

    **Validação de Dados:**

    ```javascript theme={"theme":"catppuccin-latte"}
    function validateExtractedData(fields) {
      const warnings = [];

      fields.forEach(field => {
        // Verifica confiança baixa
        if (field.confidence < 70) {
          warnings.push(`${field.name}: confiança baixa (${field.confidence}%)`);
        }

        // Validações específicas
        if (field.name === 'CPF') {
          if (!isValidCPF(field.value)) {
            warnings.push(`CPF inválido: ${field.value}`);
          }
        }

        if (field.name === 'DATA_NASCIMENTO') {
          if (!isValidDate(field.value)) {
            warnings.push(`Data inválida: ${field.value}`);
          }
        }
      });

      return warnings;
    }
    ```
  </Accordion>

  <Accordion title="Tratamento de Erros" icon="triangle-exclamation">
    **Erros Comuns:**

    | StatusCode | Erro                | Solução                     |
    | ---------- | ------------------- | --------------------------- |
    | 401        | Token inválido      | Renove o token              |
    | 400        | Imagem inválida     | Verifique formato e tamanho |
    | 413        | Imagem muito grande | Reduza o tamanho (\< 10MB)  |
    | 500        | Erro no servidor    | Tente novamente com backoff |

    **Implementação de Retry:**

    ```python theme={"theme":"catppuccin-latte"}
    import time

    def extract_with_retry(token, image, max_attempts=3):
        for attempt in range(max_attempts):
            try:
                result = extract_document_data(token, image)
                if result['isSuccesful']:
                    return result
            except Exception as e:
                if attempt < max_attempts - 1:
                    wait_time = 2 ** attempt  # Backoff exponencial
                    print(f"Tentativa {attempt + 1} falhou. "
                          f"Aguardando {wait_time}s...")
                    time.sleep(wait_time)
                else:
                    raise

        return None
    ```
  </Accordion>

  <Accordion title="Segurança" icon="shield">
    **Proteção de Dados:**

    1. **Imagens:**
       * Criptografe imagens em trânsito (HTTPS)
       * Não armazene Base64 em logs
       * Delete imagens após processamento
       * Implemente controle de acesso

    2. **Dados Extraídos:**
       * Dados pessoais são sensíveis (LGPD)
       * Criptografe armazenamento
       * Implemente auditoria de acesso
       * Defina política de retenção

    3. **Tokens:**
       * Use HTTPS obrigatoriamente
       * Nunca logue tokens completos
       * Renove periodicamente
       * Implemente timeout de sessão

    **Exemplo de sanitização:**

    ```javascript theme={"theme":"catppuccin-latte"}
    function sanitizeForLog(data) {
      return {
        typeRecognized: data.ocrResult?.typeRecognized,
        fieldsCount: data.ocrResult?.fields?.length,
        timestamp: data.timestamp,
        success: data.isSuccesful
        // Não inclui valores dos campos (dados pessoais)
      };
    }
    ```
  </Accordion>
</AccordionGroup>
