Inovacc Desenvolvedores

Guias

Autenticação

Toda chamada a uma API da Inovacc é autenticada por um único cabeçalho, Authorization: Bearer <credential>. A credencial identifica a sua organização e, no caso da credencial de uma aplicação, a aplicação também, então você nunca as nomeia na requisição. As chamadas que alteram algo na API de IA também levam um X-Operation-Id, que as torna seguras para repetir. Este guia explica as credenciais, os cabeçalhos que cada API lê, como funciona a idempotência e como manter as chaves seguras durante toda a sua vida.

Os cabeçalhos

CabeçalhoOndeValor
Authorizationtoda chamada, toda APIBearer <credential>
X-Operation-IdAPI de IA (ai.inovacc.dev): todo POST, PUT e DELETE; opcional em GETum id único que você escolhe: de 8 a 128 letras, dígitos, _ ou -

Dados (data.inovacc.dev) e Eventos (events.inovacc.dev) não leem nenhum cabeçalho de organização ou de operação: o tenant vem apenas da credencial, e qualquer cabeçalho que tente nomear outro é ignorado. Dados usa versões HTTP (If-Match, If-None-Match) e Eventos usa uma idempotency_key no corpo para repetições seguras; veja as páginas dos produtos.

Uma requisição sem credencial, com uma credencial malformada ou com uma que não é reconhecida é recusada antes de qualquer coisa ser executada: 401 com missing_credentials ou invalid_credentials. Em todas as APIs essa resposta é a mesma, quer o caminho chamado exista ou não, de modo que nada sobre a API pode ser descoberto sem uma credencial.

Obter uma chave

As chaves secretas são criadas no console da Inovacc por uma pessoa da sua organização e mostradas uma única vez: a Inovacc guarda apenas um hash, então uma chave perdida não pode ser exibida de novo, só substituída. O acesso é por convite atualmente: peça ao seu contato na Inovacc que convide você e depois crie uma chave na sua organização.

Credenciais

CredencialAparênciaParaAceita por
Chave de API secretaaik_ seguido de 64 caracteres hexadecimaisos seus servidoresIA, Dados, Eventos
Token de acesso de cliente OAuthum token assinado emitido para um cliente de uma aplicaçãoos seus servidoresIA, Dados, Eventos
Chave publicávelapb_...páginas web, a partir das origens que a sua aplicação listaDados (registros e arquivos, onde as regras permitem), Eventos (apenas transmissões)
Token de acesso de usuário finalemitido quando uma pessoa se autentica na sua aplicaçãoo navegador ou aplicativo dessa pessoaDados (registros e arquivos, conforme as regras da coleção)

Uma chave pode ser vinculada a uma aplicação. Essa chave alcança apenas o que a aplicação habilitou: na API de IA cada rota exige uma capacidade (ai.chat, ai.embeddings, knowledge, decision), recusada com 403 capability_not_enabled caso contrário; em Dados ela enxerga apenas os bancos de dados que a sua aplicação criou e a pasta de arquivos da sua aplicação; em Eventos ela só pode nomear o seu próprio espaço de trabalho.

As chaves publicáveis não são segredos. Elas foram feitas para ir dentro de uma página web. O que protege os seus dados é a lista de origens permitidas e, acima de tudo, as regras de cada coleção: uma chave publicável não pode fazer nada que uma regra não admita.

Idempotência

Na API de IA, X-Operation-Id é uma chave de idempotência. A primeira resposta bem-sucedida a um id de operação é armazenada por 24 horas. Envie o mesmo id de novo e você recebe essa mesma resposta, marcada com x-idempotent-replay: true, sem que o trabalho seja executado duas vezes e sem uma segunda cobrança. É isso que torna segura uma nova tentativa após um tempo esgotado ou uma conexão interrompida.

  • Um erro nunca é armazenado: repetir uma chamada que falhou com o mesmo id a executa de novo.
  • Enquanto a primeira chamada ainda está em execução, uma segunda chamada com o mesmo id retorna 409 operation_in_progress; aguarde e tente novamente.
  • Em chat, embeddings e run, um id reutilizado devolve a resposta armazenada, qualquer que seja o novo corpo. Em itens de coleção, o mesmo id com um arquivo diferente retorna 409 operation_id_reused.
  • Gere um id novo para cada operação nova e reutilize um id apenas para repetir a chamada para a qual ele foi criado.

Toda resposta de IA repete o id sob o qual foi executada em x-operation-id; em um GET sem um id, o serviço cria um. Uma resposta de chat transmitida nunca é armazenada, então não pode ser repetida.

Exemplo

Linguagem

⋮
    Linha de comandoExemplo

    Shell

    export INOVACC_API_KEY="<your API key>"

    Linguagem

    ⋮
    Requisição em cURLExemplo

    cURL

    curl "https://ai.inovacc.dev/v1/models" \
      -H "Authorization: Bearer $INOVACC_API_KEY"

    TypeScript

    const url = "https://ai.inovacc.dev/v1/models";
    
    const response = await fetch(url, {
      method: "GET",
      headers: {
        Authorization: `Bearer ${process.env.INOVACC_API_KEY}`,
      },
    });
    
    console.log(response.status, await response.text());

    Python

    import os
    import urllib.request
    
    request = urllib.request.Request(
        "https://ai.inovacc.dev/v1/models",
        method="GET",
        headers={
            "User-Agent": "inovacc-python-sample",
            "Authorization": "Bearer " + os.environ["INOVACC_API_KEY"],
        },
    )
    
    with urllib.request.urlopen(request) as response:
        print(response.status, response.read().decode())

    Go

    package main
    
    import (
    	"fmt"
    	"io"
    	"net/http"
    	"os"
    )
    
    const url = "https://ai.inovacc.dev/v1/models"
    
    func main() {
    	req, err := http.NewRequest("GET", url, nil)
    	if err != nil {
    		panic(err)
    	}
    	req.Header.Set("Authorization", "Bearer "+os.Getenv("INOVACC_API_KEY"))
    
    	res, err := http.DefaultClient.Do(req)
    	if err != nil {
    		panic(err)
    	}
    	defer res.Body.Close()
    
    	out, err := io.ReadAll(res.Body)
    	if err != nil {
    		panic(err)
    	}
    	fmt.Println(res.Status, string(out))
    }

    Rust

    // Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
    
    fn main() -> Result<(), Box<dyn std::error::Error>> {
        let api_key = std::env::var("INOVACC_API_KEY")?;
        let response = reqwest::blocking::Client::new()
            .get("https://ai.inovacc.dev/v1/models")
            .bearer_auth(api_key)
            .send()?;
        println!("{} {}", response.status(), response.text()?);
        Ok(())
    }

    JavaScript

    const url = "https://ai.inovacc.dev/v1/models";
    
    const response = await fetch(url, {
      method: "GET",
      headers: {
        Authorization: `Bearer ${process.env.INOVACC_API_KEY}`,
      },
    });
    
    console.log(response.status, await response.text());

    PHP

    <?php
    
    $curl = curl_init('https://ai.inovacc.dev/v1/models');
    curl_setopt_array($curl, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . getenv('INOVACC_API_KEY'),
        ],
    ]);
    
    $response = curl_exec($curl);
    echo curl_getinfo($curl, CURLINFO_HTTP_CODE), ' ', $response, "\n";
    curl_close($curl);

    Ruby

    require "net/http"
    require "uri"
    
    uri = URI('https://ai.inovacc.dev/v1/models')
    
    request = Net::HTTP::Get.new(uri)
    request["Authorization"] = "Bearer #{ENV.fetch('INOVACC_API_KEY')}"
    
    response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
      http.request(request)
    end
    
    puts "#{response.code} #{response.body}"

    Java

    import java.net.URI;
    import java.net.http.HttpClient;
    import java.net.http.HttpRequest;
    import java.net.http.HttpResponse;
    
    public class Main {
        public static void main(String[] args) throws Exception {
            String apiKey = System.getenv("INOVACC_API_KEY");
    
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create("https://ai.inovacc.dev/v1/models"))
                    .header("Authorization", "Bearer " + apiKey)
                    .GET()
                    .build();
    
            HttpResponse<String> response = HttpClient.newHttpClient()
                    .send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.statusCode() + " " + response.body());
        }
    }

    C#

    var url = "https://ai.inovacc.dev/v1/models";
    var apiKey = Environment.GetEnvironmentVariable("INOVACC_API_KEY");
    
    using var client = new HttpClient();
    using var request = new HttpRequestMessage(HttpMethod.Get, url);
    request.Headers.Add("Authorization", $"Bearer {apiKey}");
    
    using var response = await client.SendAsync(request);
    Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");

    Kotlin

    import java.net.URI
    import java.net.http.HttpClient
    import java.net.http.HttpRequest
    import java.net.http.HttpResponse
    
    fun main() {
        val apiKey = System.getenv("INOVACC_API_KEY")
    
        val request = HttpRequest.newBuilder()
            .uri(URI.create("https://ai.inovacc.dev/v1/models"))
            .header("Authorization", "Bearer " + apiKey)
            .GET()
            .build()
    
        val response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString())
        println("${response.statusCode()} ${response.body()}")
    }

    Swift

    import Foundation
    #if canImport(FoundationNetworking)
    import FoundationNetworking
    #endif
    
    let apiKey = ProcessInfo.processInfo.environment["INOVACC_API_KEY"] ?? ""
    
    let url = URL(string: "https://ai.inovacc.dev/v1/models")!
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
    
    let (data, response) = try await URLSession.shared.data(for: request)
    let status = (response as? HTTPURLResponse)?.statusCode ?? 0
    print(status, String(decoding: data, as: UTF8.self))

    A resposta lista as rotas configuradas para a sua organização. As rotas são nomeadas por organização, então a lista que você vê é a sua. Uma chamada que altera algo acrescenta o seu id de operação:

    Linguagem

    ⋮
      Linha de comandoExemplo

      Shell

      curl -X POST "https://ai.inovacc.dev/v1/chat/completions" \
        -H "Authorization: Bearer $INOVACC_API_KEY" \
        -H "Content-Type: application/json" \
        -H "X-Operation-Id: $(uuidgen)" \
        -d '{"model":"auto","messages":[{"role":"user","content":"Hello"}]}'

      Ciclo de vida da chave

      Uma chave passa por quatro etapas, e cada uma tem os seus próprios cuidados.

      1. Criação. Crie uma chave por aplicação e por ambiente (produção, homologação, o notebook de um desenvolvedor), nunca uma chave compartilhada por tudo. Copie a chave direto do console para o seu repositório de segredos.
      2. Uso. Carregue a chave a partir do ambiente ou de um gerenciador de segredos na inicialização. Envie-a apenas no cabeçalho Authorization, apenas por HTTPS e apenas a partir de um servidor: uma chave secreta que chega à API de Dados ou de Eventos a partir de um navegador (com um cabeçalho Origin) é recusada com 403 secret_key_in_browser.
      3. Rotação. Crie uma segunda chave, implante-a em todos os lugares onde a primeira é usada, confirme no Registro de atividade que o id da chave antiga não aparece mais como actor_id e então desative a chave antiga. Uma chave desativada responde 403 key_disabled; revogar a credencial de uma aplicação tem efeito em até um minuto.
      4. Aposentadoria. Remova a chave de todo repositório de segredos e pipeline quando uma aplicação ou ambiente deixar de existir.

      Um comportamento para planejar: no Banco de Dados Vetorial, o escopo local pertence à chave que o escreveu. Uma chave nova enxerga um escopo local novo e vazio; use o escopo shared para o conhecimento que precisa sobreviver a uma rotação.

      Os tokens de acesso OAuth expiram. Quando uma chamada responde 401 invalid_credentials com um token que antes funcionava, obtenha um novo token e tente novamente uma vez; não repita um 401 em um laço.

      Higiene das chaves

      • Nunca faça commit de uma chave, nem mesmo em um repositório privado ou em um arquivo de teste. Mantenha os arquivos .env fora do controle de versão.
      • Nunca registre em log o cabeçalho Authorization e oculte-o dos relatórios de erro e dos traces.
      • Dê a cada integração a sua própria chave, para que o tráfego dela seja visível no Registro de atividade e ela possa ser rotacionada isoladamente.
      • Prefira uma chave vinculada a uma aplicação com apenas as capacidades de que precisa a uma chave de toda a organização.
      • Rotacione em um calendário e imediatamente quando alguém que tinha acesso sair ou uma chave puder ter vazado.
      • Em um navegador, use uma chave publicável ou o token de uma pessoa autenticada e feche toda coleção com regras.

      Veja também

      • Erros: o envelope de erro e os códigos que você pode tratar.
      • Limites: tamanhos de requisição, tempos limite e taxas.
      • Webhooks: verificação de entregas com um segredo de assinatura.
      • Referência da API: cada produto e seus endpoints.
      Atualizado em 2026-10-10.