Emitir e-CF
Emite con POST /companies/{companyId}/documents. Gravitas asigna el e-NCF, arma el XML oficial, lo
valida contra el XSD de la DGII, lo firma con el certificado de la empresa y lo envía.
# Emitir un e-CF 31 en test para la empresa 101000001 (respuesta 202 con documentId de Gravitas).curl -s -X POST "https://tuempresa.gravitastec.com/api/v1/companies/0192f1a0-0000-7000-8000-000000000001/documents" \ -H "Authorization: Bearer $TOKEN" \ -H "Idempotency-Key: pedido-0001" \ -H "Content-Type: application/json" \ -d '{ "ecfType": 31, "issueDate": "2026-11-02", "incomeType": "01", "paymentType": 1, "buyer": { "rnc": "101672919", "name": "CLIENTE DE PRUEBA SRL" }, "lines": [ { "itemName": "Servicio de transporte", "isService": true, "billingIndicator": 1, "quantity": 1, "unitPrice": 1000 } ]}'// Emitir un e-CF 31 en test para la empresa 101000001.using System.Net.Http.Headers;using System.Net.Http.Json;using System.Text.Json;
var api = new HttpClient { BaseAddress = new Uri("https://tuempresa.gravitastec.com/api/v1/") };var form = new FormUrlEncodedContent(new Dictionary<string, string>{ ["grant_type"] = "client_credentials", ["client_id"] = "YOUR_CLIENT_ID", ["client_secret"] = Environment.GetEnvironmentVariable("GRAVITAS_CLIENT_SECRET") ?? "YOUR_CLIENT_SECRET",});var tokenResponse = await api.PostAsync("oauth/token", form);tokenResponse.EnsureSuccessStatusCode();var token = JsonDocument.Parse(await tokenResponse.Content.ReadAsStringAsync()).RootElement.GetProperty("access_token").GetString();api.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "companies/0192f1a0-0000-7000-8000-000000000001/documents"){ Content = new StringContent(""" { "ecfType": 31, "issueDate": "2026-11-02", "incomeType": "01", "paymentType": 1, "buyer": { "rnc": "101672919", "name": "CLIENTE DE PRUEBA SRL" }, "lines": [ { "itemName": "Servicio de transporte", "isService": true, "billingIndicator": 1, "quantity": 1, "unitPrice": 1000 } ] } """, System.Text.Encoding.UTF8, "application/json"),};request.Headers.Add("Idempotency-Key", "pedido-0001");var response = await api.SendAsync(request);Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");// Emitir un e-CF 31 en test para la empresa 101000001. Node 20+.const baseUrl = 'https://tuempresa.gravitastec.com/api/v1';const tokenResponse = await fetch(`${baseUrl}/oauth/token`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'client_credentials', client_id: 'YOUR_CLIENT_ID', client_secret: process.env.GRAVITAS_CLIENT_SECRET ?? 'YOUR_CLIENT_SECRET', }),});const { access_token: token } = await tokenResponse.json();const auth = { Authorization: `Bearer ${token}` };
const response = await fetch(`${baseUrl}/companies/0192f1a0-0000-7000-8000-000000000001/documents`, { method: 'POST', headers: { ...auth, 'Content-Type': 'application/json', 'Idempotency-Key': 'pedido-0001' }, body: JSON.stringify({ "ecfType": 31, "issueDate": "2026-11-02", "incomeType": "01", "paymentType": 1, "buyer": { "rnc": "101672919", "name": "CLIENTE DE PRUEBA SRL" }, "lines": [ { "itemName": "Servicio de transporte", "isService": true, "billingIndicator": 1, "quantity": 1, "unitPrice": 1000 } ] }),});console.log(response.status, await response.json());Idempotencia
Sección titulada «Idempotencia»El encabezado Idempotency-Key es obligatorio. Si tu ERP reintenta con la misma clave y el mismo
contenido, recibe el mismo documento; nunca se emite dos veces. Si reutilizas la clave con otro contenido,
la respuesta es 409 idempotency_conflict.
Tipos de e-CF
Sección titulada «Tipos de e-CF»Se admiten los tipos 31, 32, 33, 34, 41, 43, 44, 45, 46 y 47. Las reglas de cada tipo
(campos obligatorios, ITBIS, retenciones, otra moneda) siguen el formato oficial de la DGII; los errores
indican la ruta exacta del campo.
- Tipo 32 menor de RD$250,000: Gravitas envía a la DGII el resumen (RFCE) y conserva el e-CF completo para entregarlo al comprador.
- Notas de crédito y débito (33 y 34): indica el comprobante modificado y el código de modificación.
Campos desconocidos
Sección titulada «Campos desconocidos»Un campo que no existe en el modelo devuelve 422: así detectas errores de integración temprano.
Después de emitir
Sección titulada «Después de emitir»202 Acceptedcon eldocumentId.- El estado avanza:
validated → signed → sent → accepted | accepted_conditional | rejected. - Si el comprador es electrónico, Gravitas le entrega el XML; si no, envía la representación impresa por correo cuando la empresa lo tiene configurado.