# HubNotas API API Laravel para receber notas fiscais/comprovantes de sistemas externos. ## Fluxo 1. O usuario cria uma conta pelo painel ou em `POST /api/v1/auth/register`. 2. O usuario escolhe `gemini` ou `openai` e cadastra a propria chave. 3. O usuario gera um token Bearer. 4. O usuario cadastra um sistema cliente e guarda o `id`. 5. O sistema externo envia imagem, foto, PDF ou XML da nota em `POST /api/v1/invoices`. 6. O HubNotas usa a chave do provedor escolhido pelo usuario e devolve o JSON extraido. 7. Cada usuario enxerga apenas seus sistemas, tokens e notas. Base de producao: ```text https://hubnotas.brunoalves.dev.br ``` ## Autenticacao Envie o token em todas as rotas protegidas: ```http Authorization: Bearer SEU_TOKEN Accept: application/json ``` No painel web, o usuario tambem pode gerar e remover tokens Bearer. O valor completo do token aparece apenas no momento da criacao. ## Cadastro ```bash curl -X POST http://localhost:8000/api/v1/auth/register \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "name": "Empresa Cliente", "email": "financeiro@empresa.test", "password": "password123", "device_name": "sistema-financeiro", "ai_provider": "gemini", "gemini_api_key": "sua-chave-gemini", "openai_api_key": null }' ``` ## Configurar Provedor de IA Cada usuario da API pode escolher entre `gemini` e `openai`. A chave do usuario fica salva criptografada no banco. Exemplo com Gemini: ```bash curl -X PUT http://localhost:8000/api/v1/me/gemini \ -H "Accept: application/json" \ -H "Authorization: Bearer SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "ai_provider": "gemini", "gemini_api_key": "sua-chave-gemini" }' ``` Exemplo com OpenAI: ```bash curl -X PUT http://localhost:8000/api/v1/me/gemini \ -H "Accept: application/json" \ -H "Authorization: Bearer SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "ai_provider": "openai", "openai_api_key": "sua-chave-openai" }' ``` ## Criar Sistema Cliente Tambem e possivel criar sistemas clientes pelo painel web em `/painel`. Depois de criar, use o `id` retornado como `system_id` no envio de notas. ```bash curl -X POST http://localhost:8000/api/v1/systems \ -H "Accept: application/json" \ -H "Authorization: Bearer SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Sistema Financeiro", "slug": "sistema-financeiro", "callback_url": "https://empresa.test/webhooks/notas" }' ``` ## Remover Sistema Cliente ```bash curl -X DELETE http://localhost:8000/api/v1/systems/1 \ -H "Accept: application/json" \ -H "Authorization: Bearer SEU_TOKEN" ``` A remocao apaga o sistema cliente, suas notas vinculadas e os arquivos armazenados dessas notas. ## Teste no Postman Configure a chamada assim: ```text Metodo: POST URL: https://hubnotas.brunoalves.dev.br/api/v1/invoices Authorization: Bearer SEU_TOKEN Accept: application/json Body: form-data ``` Campos do `form-data`: ```text system_id Text ID do sistema cliente external_id Text ID unico da nota no sistema externo file File Imagem, foto, PDF ou XML da nota ``` Use um `external_id` novo em cada teste. Se repetir o mesmo `external_id` dentro do mesmo `system_id`, a API retorna a nota ja existente e nao chama a IA novamente. ## Enviar Nota com Dados Estruturados ```bash curl -X POST http://localhost:8000/api/v1/invoices \ -H "Accept: application/json" \ -H "Authorization: Bearer SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "system_id": 1, "external_id": "NF-001", "issuer_name": "Fornecedor Teste LTDA", "document_number": "12345", "issued_at": "2026-08-24", "total_amount": 199.90, "currency": "BRL", "category": "servicos", "payment_method": "pix", "raw_payload": { "origem": "sistema-financeiro" } }' ``` ## Enviar Arquivo da Nota ```bash curl -X POST http://localhost:8000/api/v1/invoices \ -H "Accept: application/json" \ -H "Authorization: Bearer SEU_TOKEN" \ -F "system_id=1" \ -F "external_id=NF-002" \ -F "file=@/caminho/nota.pdf" ``` Arquivos aceitos: `jpg`, `jpeg`, `png`, `pdf`, `xml`, ate 10MB. O `system_id` deve pertencer ao usuario autenticado pelo token Bearer. O `external_id` e opcional, mas recomendado para evitar notas duplicadas. Resposta esperada quando a IA estiver configurada: ```json { "data": { "id": 10, "system_id": 1, "external_id": "NF-002", "issuer_name": "Mercado Central", "document_number": "CUPOM-789", "issued_at": "2026-08-24T00:00:00.000000Z", "total_amount": "58.35", "currency": "BRL", "category": "alimentacao", "payment_method": "cartao", "status": "extracted", "extracted_data": { "issuer_name": "Mercado Central", "document_number": "CUPOM-789", "issued_at": "2026-08-24", "total_amount": 58.35, "currency": "BRL", "category": "alimentacao", "payment_method": "cartao", "status": "extracted", "extraction_error": null, "extraction_provider": "gemini", "extraction_model": "gemini-3.6-flash", "extraction_key_source": "user" } } } ``` Configure apenas os modelos fixos no `.env` do HubNotas: ```env GEMINI_MODEL=gemini-3.6-flash OPENAI_INVOICE_MODEL=gpt-4.1-nano ``` Os modelos sao fixos por ambiente. Usuarios da API escolhem o provedor e configuram a propria chave. Sem chave do provedor no usuario, o arquivo sera salvo e a nota ficara com status `extraction_unavailable`. Se a extracao falhar por instabilidade do provedor, a nota fica salva com status `extraction_failed` e o campo `extraction_error` traz a mensagem retornada. ## Remover Nota ```bash curl -X DELETE http://localhost:8000/api/v1/invoices/10 \ -H "Accept: application/json" \ -H "Authorization: Bearer SEU_TOKEN" ``` A remocao apaga o registro da nota e o arquivo armazenado, quando existir. ## Proximos Passos Tecnicos - Criar webhook para avisar o `callback_url` quando a extracao terminar. - Adicionar fila para processar notas pesadas de forma assincrona. - Adicionar campos fiscais especificos, como CNPJ, chave NFe, impostos e itens.