Documentación › Primeros pasos
Empieza aquí
De la clave de prueba a la primera NFS-e autorizada, paso a paso, con curl, C# y Delphi.
Tu primera nota fiscal
Todo empieza en el entorno de pruebas: la nota fiscal va de verdad al entorno de pruebas del Sistema Nacional, sin valor fiscal, sin cobro y sin aparecer en el panel. Después, para producción, solo cambia la clave.
¿Cuál es tu camino?
- A. La empresa ya está configurada en el panel (certificado A1 y datos fiscales): sigue los pasos 1, 3, 4, 5, 6 y 7. Toma minutos.
- B. Primera configuración: empieza por el paso 2. El tiempo depende de tener el certificado A1 a mano y de conocer el régimen tributario y el código de servicio de la empresa.
1. Clave de prueba. En el panel, en Integrações › Chaves de API
(Integraciones › Claves de API), crea una clave con entorno Teste (Prueba).
Empieza con sdr_test_. En los ejemplos de abajo está en la variable
SUDREL_API_KEY.
2. Empresa (solo en el camino B). Registra la empresa y envía el
certificado A1 por el panel, o por la API con una clave sdr_live_
(POST /v1/companies y POST /v1/companies/{id}/certificate). La clave de
prueba lee las empresas y emite en su nombre, pero no crea ni modifica
empresas. Los datos fiscales (régimen tributario, código de servicio
predeterminado) están en el panel, en Emissão › Empresa (Emisión ›
Empresa). El empresa_id de cada empresa sale de GET /v1/companies.
3. Preparación. Objetivo: saber si la empresa puede emitir ahora, antes de intentarlo.
curl https://api.sudrel.com.br/api/v1/companies/$EMPRESA/prontidao \
-H "Authorization: Bearer $SUDREL_API_KEY"
La respuesta trae situacao (ok, aviso o bloqueio) y un ítem por
requisito, cada uno con mensagem y correcao. Siguiente paso: con ok o
aviso, continúa. Con bloqueio, resuelve el ítem indicado: la emisión sería
rechazada con 412. Detalles en Preparación.
4. Valida antes de emitir. POST /v1/nfse/validacoes recibe el mismo
JSON de la emisión y devuelve los errores y los ajustes, sin crear nada.
curl https://api.sudrel.com.br/api/v1/nfse/validacoes \
-H "Authorization: Bearer $SUDREL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"empresa_id":"'$EMPRESA'","referencia":"PED-1001","tomador":{"documento":"11222333000181"},"valor":"1500.00","servico":{"descricao":"Consultoria em sistemas"}}'
La respuesta es siempre 200, con valida (true o false), erros (cada
uno con campo, mensagem y correcao) y ajustes (lo que Sudrel completó
u omitió según el municipio). Siguiente paso: con valida: true, emite.
5. Emite. Envía siempre referencia e Idempotency-Key: es lo que hace
seguro repetir la llamada. Consulta Idempotencia.
curl https://api.sudrel.com.br/api/v1/nfse \
-H "Authorization: Bearer $SUDREL_API_KEY" \
-H "Idempotency-Key: 7f1c0d9a-4a51-4e0e-9b1f-2b6f0d3c5a10" \
-H "Prefer: wait=10" \
-H "Content-Type: application/json" \
-d '{"empresa_id":"'$EMPRESA'","referencia":"PED-1001","tomador":{"documento":"11222333000181"},"valor":"1500.00","servico":{"descricao":"Consultoria em sistemas"}}'
Lo que puede volver:
| Status | Qué pasó | Siguiente paso |
|---|---|---|
| 201 | Autorizada. numero y chave_acesso completos. |
Listo. Descarga el PDF en GET /v1/nfse/{id}/pdf. |
| 202 | Todavía transmitindo. Sudrel sigue a cargo. |
Espera el webhook o consulta (paso 6). No emitas de nuevo. |
422 validacao |
El JSON tiene un error. No se creó nada. | Corrige los ítems de erros y envía de nuevo. |
422 nfse_rejeitada |
El Sistema Nacional la rechazó. La nota fiscal existe como rejeitada. |
Lee rejeicao, corrige y emite una nota fiscal nueva, con otra referencia. |
412 empresa_nao_pronta |
La empresa no puede emitir. No se creó nada. | Resuelve los ítems en bloqueio (paso 3). |
Sin SDK, la misma llamada en HTTP puro:
C# (.NET 6 o más reciente):
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Threading.Tasks;
public static class PrimeiraNota
{
// A Idempotency-Key é sua: gere uma por nota, guarde junto do pedido e
// reaproveite a MESMA se precisar repetir a chamada. Assim nunca sai nota dobrada.
public static async Task<string> EmitirAsync(string empresaId, string idempotencyKey)
{
using var http = new HttpClient { BaseAddress = new Uri("https://api.sudrel.com.br/api/") };
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("SUDREL_API_KEY"));
var pedido = new HttpRequestMessage(HttpMethod.Post, "v1/nfse")
{
Content = JsonContent.Create(new
{
empresa_id = empresaId,
referencia = "PED-1001",
tomador = new { documento = "11222333000181" },
valor = "1500.00",
servico = new { descricao = "Consultoria em sistemas" },
}),
};
pedido.Headers.Add("Idempotency-Key", idempotencyKey);
pedido.Headers.Add("Prefer", "wait=10");
var resposta = await http.SendAsync(pedido);
var corpo = await resposta.Content.ReadAsStringAsync();
// 201: autorizada. 202: ainda transmitindo (acompanhe por webhook ou GET /v1/nfse/PED-1001).
// 422: veja "codigo" e "erros" (ou a nota rejeitada em "nfse"). Todo erro traz "requisicao_id".
return $"{(int)resposta.StatusCode} {corpo}";
}
}
Delphi (10.3 o más reciente, System.Net.HttpClient):
uses
System.SysUtils, System.Classes, System.Net.HttpClient, System.Net.URLClient;
// A Idempotency-Key é sua: gere uma por nota, guarde junto do pedido e
// reaproveite a MESMA se precisar repetir a chamada. Assim nunca sai nota dobrada.
function EmitirNota(const EmpresaId, IdempotencyKey: string): string;
var
Cliente: THTTPClient;
Corpo: TStringStream;
Resposta: IHTTPResponse;
begin
Cliente := THTTPClient.Create;
Corpo := TStringStream.Create(
'{"empresa_id":"' + EmpresaId + '","referencia":"PED-1001",' +
'"tomador":{"documento":"11222333000181"},"valor":"1500.00",' +
'"servico":{"descricao":"Consultoria em sistemas"}}', TEncoding.UTF8);
try
Cliente.ContentType := 'application/json';
Cliente.CustomHeaders['Authorization'] := 'Bearer ' + GetEnvironmentVariable('SUDREL_API_KEY');
Cliente.CustomHeaders['Idempotency-Key'] := IdempotencyKey;
Cliente.CustomHeaders['Prefer'] := 'wait=10';
Resposta := Cliente.Post('https://api.sudrel.com.br/api/v1/nfse', Corpo);
// 201: autorizada. 202: ainda transmitindo (acompanhe por webhook ou GET /v1/nfse/PED-1001).
// 422: veja "codigo" e "erros" (ou a nota rejeitada em "nfse"). Todo erro traz "requisicao_id".
Result := IntToStr(Resposta.StatusCode) + ' ' + Resposta.ContentAsString(TEncoding.UTF8);
finally
Corpo.Free;
Cliente.Free;
end;
end;
También hay SDKs de TypeScript y PHP: consulta SDKs.
6. Haz el seguimiento. Objetivo: conocer el resultado de una nota fiscal que volvió con 202. Consulta por tu referencia:
curl https://api.sudrel.com.br/api/v1/nfse/PED-1001 \
-H "Authorization: Bearer $SUDREL_API_KEY"
Siguiente paso: status indica dónde está la nota fiscal (consulta
Estados de la NFS-e). Consulta sin prisa (cada 30
segundos, por ejemplo); en producción, prefiere el webhook.
7. Webhook. Objetivo: recibir el aviso sin consultar. Registra una dirección tuya con la clave de prueba (recibe solo eventos de prueba):
curl https://api.sudrel.com.br/api/v1/webhooks \
-H "Authorization: Bearer $SUDREL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://erp.exemplo.com.br/webhooks/sudrel","eventos":["NFSE_AUTORIZADA","NFSE_REJEITADA","NFSE_FALHA_TRANSMISSAO"]}'
Guarda el segredo de la respuesta: solo aparece aquí. Prueba con
POST /v1/webhooks/{id}/teste. Cómo verificar la firma de cada entrega
está en Webhooks.
8. Provoca los fallos. Con el encabezado X-Sudrel-Simular (sección
Simulador de fallos) ves timeout, Sefin caída,
bloqueo de período de competencia y falha_transmissao sin tocar la Sefin.
¿Hubo un error? Toda respuesta trae el encabezado X-Request-Id, y los
errores de emisión, lote, webhooks y eventos repiten el valor en
requisicao_id. Búscalo en el panel, en Integrações › Log da API
(Integraciones › Registro de la API): ahí está lo que tu sistema envió y lo que
Sudrel respondió, durante 30 días. Consulta también
Problemas comunes.