Skip to main content
POST
/
realms
/
fleximage
/
protocol
/
openid-connect
/
token
Autenticação OAuth 2.0
curl --request POST \
  --url https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --header 'x-api-key: <api-key>' \
  --data 'grant_type=<string>' \
  --data 'client_id=<string>' \
  --data 'client_secret=<string>'
import requests

url = "https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token"

payload = {
    "grant_type": "<string>",
    "client_id": "<string>",
    "client_secret": "<string>"
}
headers = {
    "x-api-key": "<api-key>",
    "Content-Type": "application/x-www-form-urlencoded"
}

response = requests.post(url, data=payload, headers=headers)

print(response.text)
const options = {
  method: 'POST',
  headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/x-www-form-urlencoded'},
  body: new URLSearchParams({grant_type: '<string>', client_id: '<string>', client_secret: '<string>'})
};

fetch('https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token', options)
  .then(res => res.json())
  .then(res => console.log(res))
  .catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "grant_type=%3Cstring%3E&client_id=%3Cstring%3E&client_secret=%3Cstring%3E",
  CURLOPT_HTTPHEADER => [
    "Content-Type: application/x-www-form-urlencoded",
    "x-api-key: <api-key>"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token"

	payload := strings.NewReader("grant_type=%3Cstring%3E&client_id=%3Cstring%3E&client_secret=%3Cstring%3E")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-api-key", "<api-key>")
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token")
  .header("x-api-key", "<api-key>")
  .header("Content-Type", "application/x-www-form-urlencoded")
  .body("grant_type=%3Cstring%3E&client_id=%3Cstring%3E&client_secret=%3Cstring%3E")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/x-www-form-urlencoded'
request.body = "grant_type=%3Cstring%3E&client_id=%3Cstring%3E&client_secret=%3Cstring%3E"

response = http.request(request)
puts response.read_body
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJxNzJMVEMyVXQ4VjhfYTBYMjRMU2g3MThsUndVdWFQRDVWNXVhX0pIaW5VIn0.eyJleHAiOjE3NDU0MjE2MzMsImlhdCI6MTc0NTQxODAzMywianRpIjoiZjc4YzA5ZjAtMTBkZS00NzQwLWI4ODEtOGY0YWQwZjBmZmZkIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLWRlcy5mbGV4ZG9jLWFwaXMuY29tLmJyL3JlYWxtcy9mbGV4aW1hZ2UiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNGU3YzY4YWItNzQxZi00ZDhjLWJiNGUtMWY3MzI5ZDkwNzAzIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGUtYXBpIn0...",
  "expires_in": 3600,
  "refresh_expires_in": 0,
  "token_type": "Bearer",
  "not-before-policy": 0,
  "scope": "profile email"
}
{
  "error": "invalid_client",
  "error_description": "Invalid client credentials"
}
{
  "error": "invalid_request",
  "error_description": "Missing form parameter: grant_type"
}

Visão Geral

Todas as requisições para as APIs do Flexdoc exigem autenticação via OAuth 2.0 usando o fluxo Client Credentials. Esta página permite que você gere seu token de acesso diretamente no playground.
1

1. Use suas credenciais

Informe o Client ID e Client Secret fornecidos pela equipe Flexdoc
2

2. Gere o token

Execute a requisição no playground ao lado
3

3. Copie o access_token

Armazene o token retornado para usar nas próximas requisições
4

4. Use nas APIs

Adicione no header: Authorization: Bearer {access_token}

Credenciais de Desenvolvimento

Para testes no ambiente de desenvolvimento, use as credenciais abaixo:
CLIENT_ID=teste-api
CLIENT_SECRET=pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg
As credenciais acima são exclusivas para ambiente de desenvolvimento (DES).Para produção, solicite suas credenciais através do email integracao@flexdoc.com.br

Request Parameters

Teste Agora! Use o playground interativo “Try It” na lateral direita desta página →Preencha os campos abaixo e clique em “Send” para gerar seu token instantaneamente.

Body Parameters (application/x-www-form-urlencoded)

grant_type
string
default:"client_credentials"
required
Tipo de concessão OAuth 2.0. Deve ser sempre client_credentials
client_id
string
default:"teste-api"
required
Identificador único do cliente fornecido pela FlexdocExemplo DEV: teste-api
client_secret
string
default:"pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg"
required
Chave secreta do cliente fornecida pela FlexdocExemplo DEV: pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg
Nunca compartilhe ou exponha seu client_secret em repositórios públicos ou código frontend

Response

access_token
string
required
Token JWT para autenticação nas APIs. Use no header Authorization: Bearer {token}Formato: JWT (JSON Web Token)Exemplo: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
token_type
string
Tipo do token. Sempre retorna Bearer
expires_in
integer
Tempo de validade do token em segundosPadrão: 3600 (1 hora)
refresh_expires_in
integer
Tempo de validade do refresh token em segundos (se aplicável)
scope
string
Escopos de acesso concedidos ao tokenExemplo: profile email
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJxNzJMVEMyVXQ4VjhfYTBYMjRMU2g3MThsUndVdWFQRDVWNXVhX0pIaW5VIn0.eyJleHAiOjE3NDU0MjE2MzMsImlhdCI6MTc0NTQxODAzMywianRpIjoiZjc4YzA5ZjAtMTBkZS00NzQwLWI4ODEtOGY0YWQwZjBmZmZkIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLWRlcy5mbGV4ZG9jLWFwaXMuY29tLmJyL3JlYWxtcy9mbGV4aW1hZ2UiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNGU3YzY4YWItNzQxZi00ZDhjLWJiNGUtMWY3MzI5ZDkwNzAzIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGUtYXBpIn0...",
  "expires_in": 3600,
  "refresh_expires_in": 0,
  "token_type": "Bearer",
  "not-before-policy": 0,
  "scope": "profile email"
}
{
  "error": "invalid_client",
  "error_description": "Invalid client credentials"
}
{
  "error": "invalid_request",
  "error_description": "Missing form parameter: grant_type"
}

Exemplos de Código

curl -X POST "https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=teste-api" \
  -d "client_secret=pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg"
const axios = require('axios');
const qs = require('qs');

async function getAccessToken() {
  try {
    const response = await axios.post(
      'https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token',
      qs.stringify({
        grant_type: 'client_credentials',
        client_id: 'teste-api',
        client_secret: 'pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg'
      }),
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }
    );

    const { access_token, expires_in } = response.data;
    console.log('Token obtido com sucesso!');
    console.log('Expira em:', expires_in, 'segundos');

    return access_token;
  } catch (error) {
    console.error('Erro ao obter token:', error.response?.data || error.message);
    throw error;
  }
}

// Uso
getAccessToken().then(token => {
  console.log('Token:', token);
});
import requests
from datetime import datetime, timedelta

def get_access_token():
    """
    Obtém token de acesso OAuth 2.0
    Retorna: (access_token, expiration_time)
    """
    url = "https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token"

    data = {
        'grant_type': 'client_credentials',
        'client_id': 'teste-api',
        'client_secret': 'pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg'
    }

    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }

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

        token_data = response.json()
        access_token = token_data['access_token']
        expires_in = token_data['expires_in']

        # Calcula horário de expiração
        expiration_time = datetime.now() + timedelta(seconds=expires_in)

        print(f"✓ Token obtido com sucesso!")
        print(f"Expira em: {expiration_time.strftime('%Y-%m-%d %H:%M:%S')}")

        return access_token, expiration_time

    except requests.exceptions.RequestException as e:
        print(f"✗ Erro ao obter token: {e}")
        raise

# Uso
if __name__ == "__main__":
    token, expires_at = get_access_token()
    print(f"\nToken: {token[:50]}...")
import java.net.http.*;
import java.net.*;
import java.time.*;
import com.google.gson.*;

public class FlexdocAuthClient {

    private static final String TOKEN_URL =
        "https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token";
    private static final String CLIENT_ID = "teste-api";
    private static final String CLIENT_SECRET = "pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg";

    public static class TokenResponse {
        public String access_token;
        public String token_type;
        public int expires_in;
        public String scope;
    }

    public static TokenResponse getAccessToken() throws Exception {
        HttpClient client = HttpClient.newHttpClient();

        String body = "grant_type=client_credentials" +
                      "&client_id=" + URLEncoder.encode(CLIENT_ID, "UTF-8") +
                      "&client_secret=" + URLEncoder.encode(CLIENT_SECRET, "UTF-8");

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(TOKEN_URL))
            .header("Content-Type", "application/x-www-form-urlencoded")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();

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

        if (response.statusCode() == 200) {
            Gson gson = new Gson();
            TokenResponse tokenResponse = gson.fromJson(
                response.body(),
                TokenResponse.class
            );

            Instant expiresAt = Instant.now().plusSeconds(tokenResponse.expires_in);
            System.out.println("✓ Token obtido com sucesso!");
            System.out.println("Expira em: " + expiresAt);

            return tokenResponse;
        } else {
            throw new RuntimeException("Erro ao obter token: " + response.body());
        }
    }

    public static void main(String[] args) {
        try {
            TokenResponse token = getAccessToken();
            System.out.println("\nToken: " +
                token.access_token.substring(0, 50) + "...");
        } catch (Exception e) {
            System.err.println("Erro: " + e.getMessage());
        }
    }
}
<?php

function getAccessToken() {
    $url = 'https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token';

    $data = [
        'grant_type' => 'client_credentials',
        'client_id' => 'teste-api',
        'client_secret' => 'pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg'
    ];

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/x-www-form-urlencoded'
    ]);

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

    if ($httpCode === 200) {
        $tokenData = json_decode($response, true);
        $expiresAt = date('Y-m-d H:i:s', time() + $tokenData['expires_in']);

        echo "✓ Token obtido com sucesso!\n";
        echo "Expira em: {$expiresAt}\n";

        return $tokenData['access_token'];
    } else {
        throw new Exception("Erro ao obter token: {$response}");
    }
}

// Uso
try {
    $token = getAccessToken();
    echo "\nToken: " . substr($token, 0, 50) . "...\n";
} catch (Exception $e) {
    echo "Erro: " . $e->getMessage() . "\n";
}
?>
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "net/url"
    "strings"
    "time"
)

type TokenResponse struct {
    AccessToken      string `json:"access_token"`
    TokenType        string `json:"token_type"`
    ExpiresIn        int    `json:"expires_in"`
    RefreshExpiresIn int    `json:"refresh_expires_in"`
    Scope            string `json:"scope"`
}

func getAccessToken() (*TokenResponse, error) {
    tokenURL := "https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token"

    data := url.Values{}
    data.Set("grant_type", "client_credentials")
    data.Set("client_id", "teste-api")
    data.Set("client_secret", "pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg")

    req, err := http.NewRequest("POST", tokenURL, strings.NewReader(data.Encode()))
    if err != nil {
        return nil, err
    }

    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

    client := &http.Client{Timeout: 10 * time.Second}
    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
    }

    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("erro ao obter token: %s", string(body))
    }

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

    expiresAt := time.Now().Add(time.Duration(tokenResp.ExpiresIn) * time.Second)
    fmt.Printf("✓ Token obtido com sucesso!\n")
    fmt.Printf("Expira em: %s\n", expiresAt.Format("2006-01-02 15:04:05"))

    return &tokenResp, nil
}

func main() {
    tokenResp, err := getAccessToken()
    if err != nil {
        fmt.Printf("Erro: %v\n", err)
        return
    }

    fmt.Printf("\nToken: %s...\n", tokenResp.AccessToken[:50])
}

Gerenciamento de Token

O token expira em 1 hora (3600 segundos) após sua geração.Recomendações:
  • Armazene o horário de expiração ao obter o token
  • Renove o token 5 minutos antes de expirar (margem de segurança)
  • Implemente renovação automática em caso de erro 401
Exemplo de validação:
class TokenManager {
  constructor() {
    this.token = null;
    this.expiresAt = null;
  }

  async getToken() {
    // Se token ainda é válido (com margem de 5min)
    if (this.token && this.expiresAt > Date.now() + 300000) {
      return this.token;
    }

    // Renova o token
    const response = await this.fetchNewToken();
    this.token = response.access_token;
    this.expiresAt = Date.now() + (response.expires_in * 1000);

    return this.token;
  }
}
Para otimizar performance e reduzir requisições desnecessárias:Faça:
  • Cache o token em memória durante sua validade
  • Use variáveis de ambiente para credenciais
  • Implemente singleton/padrão de instância única
Não faça:
  • Armazenar token em localStorage (frontend)
  • Compartilhar tokens entre ambientes diferentes
  • Fazer uma requisição de auth para cada chamada à API
Erro 401 - Invalid Client
{
  "error": "invalid_client",
  "error_description": "Invalid client credentials"
}
Causa: Client ID ou Client Secret incorretosSolução: Verifique suas credenciais
Erro 400 - Invalid Request
{
  "error": "invalid_request",
  "error_description": "Missing form parameter: grant_type"
}
Causa: Parâmetros obrigatórios ausentesSolução: Certifique-se de enviar grant_type, client_id e client_secret
Erro 500 - Server ErrorCausa: Erro interno no servidor de autenticaçãoSolução: Implemente retry com backoff exponencial (aguarde 1s, 2s, 4s entre tentativas)
🔒 Boas Práticas de Segurança:
  1. Nunca exponha credenciais:
    • Não commite client_secret em repositórios Git
    • Use variáveis de ambiente (.env)
    • Adicione .env ao .gitignore
  2. Proteja o token:
    • Nunca envie tokens em URLs (query params)
    • Use apenas HTTPS em produção
    • Não armazene em cookies sem httpOnly/secure flags
  3. Rotação de credenciais:
    • Rotacione secrets a cada 90 dias
    • Mantenha credenciais antigas ativas por 7 dias durante transição
  4. Monitoramento:
    • Registre tentativas de autenticação falhas
    • Configure alertas para uso anômalo
    • Audite uso de tokens periodicamente

Ambientes

Endpoint

POST https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token

Credenciais de Teste

ParâmetroValor
Client IDteste-api
Client SecretpwR8GPipQvifGhSIH7cH07OOCXd2C8Hg
Realmfleximage
Use estas credenciais para testes e homologação. Não há limite de requisições no ambiente DEV.

Próximos Passos

Após obter seu token de acesso, você está pronto para usar as APIs do Flexdoc!

Importação de Documentos

Envie documentos para análise e validação automática