curl --request POST \
--url https://api.ipsofactura.com/cfdi/timbrar \
--header 'Content-Type: application/json' \
--header 'x-api: <api-key>' \
--data '
{
"conceptos": [
{
"cantidad": 1,
"clave_prod_serv": "01010101",
"clave_unidad": "H87",
"descripcion": "Servicio",
"importe": 1000,
"impuestos": {
"traslados": [
{
"base": 1000,
"importe": 160,
"impuesto": "002",
"tasa_o_cuota": "0.160000",
"tipo_factor": "Tasa"
}
]
},
"objeto_imp": "02",
"valor_unitario": 1000
}
],
"forma_pago": "03",
"impuestos": {
"total_impuestos_trasladados": 160,
"traslados": [
{
"base": 1000,
"importe": 160,
"impuesto": "002",
"tasa_o_cuota": "0.160000",
"tipo_factor": "Tasa"
}
]
},
"metodo_pago": "PUE",
"moneda": "MXN",
"receptor": {
"domicilio_fiscal": "65000",
"nombre": "UNIVERSIDAD ROBOTICA ESPANOLA",
"regimen_fiscal": "601",
"rfc": "URE180429TM6",
"uso_cfdi": "G03"
},
"rfc_emisor": "EKU9003173C9",
"subtotal": 1000,
"tipo_comprobante": "I",
"total": 1160
}
'import requests
url = "https://api.ipsofactura.com/cfdi/timbrar"
payload = {
"conceptos": [
{
"cantidad": 1,
"clave_prod_serv": "01010101",
"clave_unidad": "H87",
"descripcion": "Servicio",
"importe": 1000,
"impuestos": { "traslados": [
{
"base": 1000,
"importe": 160,
"impuesto": "002",
"tasa_o_cuota": "0.160000",
"tipo_factor": "Tasa"
}
] },
"objeto_imp": "02",
"valor_unitario": 1000
}
],
"forma_pago": "03",
"impuestos": {
"total_impuestos_trasladados": 160,
"traslados": [
{
"base": 1000,
"importe": 160,
"impuesto": "002",
"tasa_o_cuota": "0.160000",
"tipo_factor": "Tasa"
}
]
},
"metodo_pago": "PUE",
"moneda": "MXN",
"receptor": {
"domicilio_fiscal": "65000",
"nombre": "UNIVERSIDAD ROBOTICA ESPANOLA",
"regimen_fiscal": "601",
"rfc": "URE180429TM6",
"uso_cfdi": "G03"
},
"rfc_emisor": "EKU9003173C9",
"subtotal": 1000,
"tipo_comprobante": "I",
"total": 1160
}
headers = {
"x-api": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
conceptos: [
{
cantidad: 1,
clave_prod_serv: '01010101',
clave_unidad: 'H87',
descripcion: 'Servicio',
importe: 1000,
impuestos: {
traslados: [
{
base: 1000,
importe: 160,
impuesto: '002',
tasa_o_cuota: '0.160000',
tipo_factor: 'Tasa'
}
]
},
objeto_imp: '02',
valor_unitario: 1000
}
],
forma_pago: '03',
impuestos: {
total_impuestos_trasladados: 160,
traslados: [
{
base: 1000,
importe: 160,
impuesto: '002',
tasa_o_cuota: '0.160000',
tipo_factor: 'Tasa'
}
]
},
metodo_pago: 'PUE',
moneda: 'MXN',
receptor: {
domicilio_fiscal: '65000',
nombre: 'UNIVERSIDAD ROBOTICA ESPANOLA',
regimen_fiscal: '601',
rfc: 'URE180429TM6',
uso_cfdi: 'G03'
},
rfc_emisor: 'EKU9003173C9',
subtotal: 1000,
tipo_comprobante: 'I',
total: 1160
})
};
fetch('https://api.ipsofactura.com/cfdi/timbrar', 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://api.ipsofactura.com/cfdi/timbrar",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'conceptos' => [
[
'cantidad' => 1,
'clave_prod_serv' => '01010101',
'clave_unidad' => 'H87',
'descripcion' => 'Servicio',
'importe' => 1000,
'impuestos' => [
'traslados' => [
[
'base' => 1000,
'importe' => 160,
'impuesto' => '002',
'tasa_o_cuota' => '0.160000',
'tipo_factor' => 'Tasa'
]
]
],
'objeto_imp' => '02',
'valor_unitario' => 1000
]
],
'forma_pago' => '03',
'impuestos' => [
'total_impuestos_trasladados' => 160,
'traslados' => [
[
'base' => 1000,
'importe' => 160,
'impuesto' => '002',
'tasa_o_cuota' => '0.160000',
'tipo_factor' => 'Tasa'
]
]
],
'metodo_pago' => 'PUE',
'moneda' => 'MXN',
'receptor' => [
'domicilio_fiscal' => '65000',
'nombre' => 'UNIVERSIDAD ROBOTICA ESPANOLA',
'regimen_fiscal' => '601',
'rfc' => 'URE180429TM6',
'uso_cfdi' => 'G03'
],
'rfc_emisor' => 'EKU9003173C9',
'subtotal' => 1000,
'tipo_comprobante' => 'I',
'total' => 1160
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api: <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://api.ipsofactura.com/cfdi/timbrar"
payload := strings.NewReader("{\n \"conceptos\": [\n {\n \"cantidad\": 1,\n \"clave_prod_serv\": \"01010101\",\n \"clave_unidad\": \"H87\",\n \"descripcion\": \"Servicio\",\n \"importe\": 1000,\n \"impuestos\": {\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"objeto_imp\": \"02\",\n \"valor_unitario\": 1000\n }\n ],\n \"forma_pago\": \"03\",\n \"impuestos\": {\n \"total_impuestos_trasladados\": 160,\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"metodo_pago\": \"PUE\",\n \"moneda\": \"MXN\",\n \"receptor\": {\n \"domicilio_fiscal\": \"65000\",\n \"nombre\": \"UNIVERSIDAD ROBOTICA ESPANOLA\",\n \"regimen_fiscal\": \"601\",\n \"rfc\": \"URE180429TM6\",\n \"uso_cfdi\": \"G03\"\n },\n \"rfc_emisor\": \"EKU9003173C9\",\n \"subtotal\": 1000,\n \"tipo_comprobante\": \"I\",\n \"total\": 1160\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ipsofactura.com/cfdi/timbrar")
.header("x-api", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"conceptos\": [\n {\n \"cantidad\": 1,\n \"clave_prod_serv\": \"01010101\",\n \"clave_unidad\": \"H87\",\n \"descripcion\": \"Servicio\",\n \"importe\": 1000,\n \"impuestos\": {\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"objeto_imp\": \"02\",\n \"valor_unitario\": 1000\n }\n ],\n \"forma_pago\": \"03\",\n \"impuestos\": {\n \"total_impuestos_trasladados\": 160,\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"metodo_pago\": \"PUE\",\n \"moneda\": \"MXN\",\n \"receptor\": {\n \"domicilio_fiscal\": \"65000\",\n \"nombre\": \"UNIVERSIDAD ROBOTICA ESPANOLA\",\n \"regimen_fiscal\": \"601\",\n \"rfc\": \"URE180429TM6\",\n \"uso_cfdi\": \"G03\"\n },\n \"rfc_emisor\": \"EKU9003173C9\",\n \"subtotal\": 1000,\n \"tipo_comprobante\": \"I\",\n \"total\": 1160\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ipsofactura.com/cfdi/timbrar")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"conceptos\": [\n {\n \"cantidad\": 1,\n \"clave_prod_serv\": \"01010101\",\n \"clave_unidad\": \"H87\",\n \"descripcion\": \"Servicio\",\n \"importe\": 1000,\n \"impuestos\": {\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"objeto_imp\": \"02\",\n \"valor_unitario\": 1000\n }\n ],\n \"forma_pago\": \"03\",\n \"impuestos\": {\n \"total_impuestos_trasladados\": 160,\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"metodo_pago\": \"PUE\",\n \"moneda\": \"MXN\",\n \"receptor\": {\n \"domicilio_fiscal\": \"65000\",\n \"nombre\": \"UNIVERSIDAD ROBOTICA ESPANOLA\",\n \"regimen_fiscal\": \"601\",\n \"rfc\": \"URE180429TM6\",\n \"uso_cfdi\": \"G03\"\n },\n \"rfc_emisor\": \"EKU9003173C9\",\n \"subtotal\": 1000,\n \"tipo_comprobante\": \"I\",\n \"total\": 1160\n}"
response = http.request(request)
puts response.read_body{
"cadena_original_sat": "||1.1|...||",
"fecha_timbrado": "2026-05-28T10:00:00",
"folio": "1",
"id": "9a4f07ff-3abc-435f-b7a6-88c2bc65b4c1",
"numero_certificado_sat": "00001000000500000000",
"sello_cfdi": "...",
"sello_sat": "...",
"uuid": "6128396f-c09b-4ec6-8699-43da5a244971"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "REQUEST_TOO_LARGE",
"message": "The request body exceeds the maximum of 4194304 bytes."
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "STAMPING_OUTCOME_UNKNOWN",
"idempotency_key": "order-4711",
"message": "We could not confirm the stamping result. The CFDI may already be stamped, so do NOT retry blindly: retry with the same idempotency_key, wait for the cfdi.timbrado webhook, or check GET /cfdi?serie=&folio=",
"retry_after": 60
}Timbrar CFDI
Genera, sella y timbra un CFDI 4.0 (ingreso o egreso) ante el SAT; devuelve el folio fiscal (UUID) y el Timbre Fiscal Digital. Es seguro reintentar: si envías idempotency_key (o folio, del que se deriva la clave), un reintento devuelve la respuesta del primer intento con la cabecera Idempotency-Replayed: true, en lugar de timbrar un segundo CFDI.
curl --request POST \
--url https://api.ipsofactura.com/cfdi/timbrar \
--header 'Content-Type: application/json' \
--header 'x-api: <api-key>' \
--data '
{
"conceptos": [
{
"cantidad": 1,
"clave_prod_serv": "01010101",
"clave_unidad": "H87",
"descripcion": "Servicio",
"importe": 1000,
"impuestos": {
"traslados": [
{
"base": 1000,
"importe": 160,
"impuesto": "002",
"tasa_o_cuota": "0.160000",
"tipo_factor": "Tasa"
}
]
},
"objeto_imp": "02",
"valor_unitario": 1000
}
],
"forma_pago": "03",
"impuestos": {
"total_impuestos_trasladados": 160,
"traslados": [
{
"base": 1000,
"importe": 160,
"impuesto": "002",
"tasa_o_cuota": "0.160000",
"tipo_factor": "Tasa"
}
]
},
"metodo_pago": "PUE",
"moneda": "MXN",
"receptor": {
"domicilio_fiscal": "65000",
"nombre": "UNIVERSIDAD ROBOTICA ESPANOLA",
"regimen_fiscal": "601",
"rfc": "URE180429TM6",
"uso_cfdi": "G03"
},
"rfc_emisor": "EKU9003173C9",
"subtotal": 1000,
"tipo_comprobante": "I",
"total": 1160
}
'import requests
url = "https://api.ipsofactura.com/cfdi/timbrar"
payload = {
"conceptos": [
{
"cantidad": 1,
"clave_prod_serv": "01010101",
"clave_unidad": "H87",
"descripcion": "Servicio",
"importe": 1000,
"impuestos": { "traslados": [
{
"base": 1000,
"importe": 160,
"impuesto": "002",
"tasa_o_cuota": "0.160000",
"tipo_factor": "Tasa"
}
] },
"objeto_imp": "02",
"valor_unitario": 1000
}
],
"forma_pago": "03",
"impuestos": {
"total_impuestos_trasladados": 160,
"traslados": [
{
"base": 1000,
"importe": 160,
"impuesto": "002",
"tasa_o_cuota": "0.160000",
"tipo_factor": "Tasa"
}
]
},
"metodo_pago": "PUE",
"moneda": "MXN",
"receptor": {
"domicilio_fiscal": "65000",
"nombre": "UNIVERSIDAD ROBOTICA ESPANOLA",
"regimen_fiscal": "601",
"rfc": "URE180429TM6",
"uso_cfdi": "G03"
},
"rfc_emisor": "EKU9003173C9",
"subtotal": 1000,
"tipo_comprobante": "I",
"total": 1160
}
headers = {
"x-api": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
conceptos: [
{
cantidad: 1,
clave_prod_serv: '01010101',
clave_unidad: 'H87',
descripcion: 'Servicio',
importe: 1000,
impuestos: {
traslados: [
{
base: 1000,
importe: 160,
impuesto: '002',
tasa_o_cuota: '0.160000',
tipo_factor: 'Tasa'
}
]
},
objeto_imp: '02',
valor_unitario: 1000
}
],
forma_pago: '03',
impuestos: {
total_impuestos_trasladados: 160,
traslados: [
{
base: 1000,
importe: 160,
impuesto: '002',
tasa_o_cuota: '0.160000',
tipo_factor: 'Tasa'
}
]
},
metodo_pago: 'PUE',
moneda: 'MXN',
receptor: {
domicilio_fiscal: '65000',
nombre: 'UNIVERSIDAD ROBOTICA ESPANOLA',
regimen_fiscal: '601',
rfc: 'URE180429TM6',
uso_cfdi: 'G03'
},
rfc_emisor: 'EKU9003173C9',
subtotal: 1000,
tipo_comprobante: 'I',
total: 1160
})
};
fetch('https://api.ipsofactura.com/cfdi/timbrar', 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://api.ipsofactura.com/cfdi/timbrar",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'conceptos' => [
[
'cantidad' => 1,
'clave_prod_serv' => '01010101',
'clave_unidad' => 'H87',
'descripcion' => 'Servicio',
'importe' => 1000,
'impuestos' => [
'traslados' => [
[
'base' => 1000,
'importe' => 160,
'impuesto' => '002',
'tasa_o_cuota' => '0.160000',
'tipo_factor' => 'Tasa'
]
]
],
'objeto_imp' => '02',
'valor_unitario' => 1000
]
],
'forma_pago' => '03',
'impuestos' => [
'total_impuestos_trasladados' => 160,
'traslados' => [
[
'base' => 1000,
'importe' => 160,
'impuesto' => '002',
'tasa_o_cuota' => '0.160000',
'tipo_factor' => 'Tasa'
]
]
],
'metodo_pago' => 'PUE',
'moneda' => 'MXN',
'receptor' => [
'domicilio_fiscal' => '65000',
'nombre' => 'UNIVERSIDAD ROBOTICA ESPANOLA',
'regimen_fiscal' => '601',
'rfc' => 'URE180429TM6',
'uso_cfdi' => 'G03'
],
'rfc_emisor' => 'EKU9003173C9',
'subtotal' => 1000,
'tipo_comprobante' => 'I',
'total' => 1160
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api: <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://api.ipsofactura.com/cfdi/timbrar"
payload := strings.NewReader("{\n \"conceptos\": [\n {\n \"cantidad\": 1,\n \"clave_prod_serv\": \"01010101\",\n \"clave_unidad\": \"H87\",\n \"descripcion\": \"Servicio\",\n \"importe\": 1000,\n \"impuestos\": {\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"objeto_imp\": \"02\",\n \"valor_unitario\": 1000\n }\n ],\n \"forma_pago\": \"03\",\n \"impuestos\": {\n \"total_impuestos_trasladados\": 160,\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"metodo_pago\": \"PUE\",\n \"moneda\": \"MXN\",\n \"receptor\": {\n \"domicilio_fiscal\": \"65000\",\n \"nombre\": \"UNIVERSIDAD ROBOTICA ESPANOLA\",\n \"regimen_fiscal\": \"601\",\n \"rfc\": \"URE180429TM6\",\n \"uso_cfdi\": \"G03\"\n },\n \"rfc_emisor\": \"EKU9003173C9\",\n \"subtotal\": 1000,\n \"tipo_comprobante\": \"I\",\n \"total\": 1160\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ipsofactura.com/cfdi/timbrar")
.header("x-api", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"conceptos\": [\n {\n \"cantidad\": 1,\n \"clave_prod_serv\": \"01010101\",\n \"clave_unidad\": \"H87\",\n \"descripcion\": \"Servicio\",\n \"importe\": 1000,\n \"impuestos\": {\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"objeto_imp\": \"02\",\n \"valor_unitario\": 1000\n }\n ],\n \"forma_pago\": \"03\",\n \"impuestos\": {\n \"total_impuestos_trasladados\": 160,\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"metodo_pago\": \"PUE\",\n \"moneda\": \"MXN\",\n \"receptor\": {\n \"domicilio_fiscal\": \"65000\",\n \"nombre\": \"UNIVERSIDAD ROBOTICA ESPANOLA\",\n \"regimen_fiscal\": \"601\",\n \"rfc\": \"URE180429TM6\",\n \"uso_cfdi\": \"G03\"\n },\n \"rfc_emisor\": \"EKU9003173C9\",\n \"subtotal\": 1000,\n \"tipo_comprobante\": \"I\",\n \"total\": 1160\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ipsofactura.com/cfdi/timbrar")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"conceptos\": [\n {\n \"cantidad\": 1,\n \"clave_prod_serv\": \"01010101\",\n \"clave_unidad\": \"H87\",\n \"descripcion\": \"Servicio\",\n \"importe\": 1000,\n \"impuestos\": {\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"objeto_imp\": \"02\",\n \"valor_unitario\": 1000\n }\n ],\n \"forma_pago\": \"03\",\n \"impuestos\": {\n \"total_impuestos_trasladados\": 160,\n \"traslados\": [\n {\n \"base\": 1000,\n \"importe\": 160,\n \"impuesto\": \"002\",\n \"tasa_o_cuota\": \"0.160000\",\n \"tipo_factor\": \"Tasa\"\n }\n ]\n },\n \"metodo_pago\": \"PUE\",\n \"moneda\": \"MXN\",\n \"receptor\": {\n \"domicilio_fiscal\": \"65000\",\n \"nombre\": \"UNIVERSIDAD ROBOTICA ESPANOLA\",\n \"regimen_fiscal\": \"601\",\n \"rfc\": \"URE180429TM6\",\n \"uso_cfdi\": \"G03\"\n },\n \"rfc_emisor\": \"EKU9003173C9\",\n \"subtotal\": 1000,\n \"tipo_comprobante\": \"I\",\n \"total\": 1160\n}"
response = http.request(request)
puts response.read_body{
"cadena_original_sat": "||1.1|...||",
"fecha_timbrado": "2026-05-28T10:00:00",
"folio": "1",
"id": "9a4f07ff-3abc-435f-b7a6-88c2bc65b4c1",
"numero_certificado_sat": "00001000000500000000",
"sello_cfdi": "...",
"sello_sat": "...",
"uuid": "6128396f-c09b-4ec6-8699-43da5a244971"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "REQUEST_TOO_LARGE",
"message": "The request body exceeds the maximum of 4194304 bytes."
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "VALIDATION_ERROR",
"id": "<string>",
"idempotencyKey": "<string>",
"message": "CFDI40147: El RFC del receptor no se encuentra en la lista de contribuyentes inscritos no cancelados del SAT",
"retryAfter": 123,
"sat_code": "CFDI40147"
}{
"code": "STAMPING_OUTCOME_UNKNOWN",
"idempotency_key": "order-4711",
"message": "We could not confirm the stamping result. The CFDI may already be stamped, so do NOT retry blindly: retry with the same idempotency_key, wait for the cfdi.timbrado webhook, or check GET /cfdi?serie=&folio=",
"retry_after": 60
}Authorizations
API key emitida por Ipsofactura, enviada en el header x-api.
Headers
Alternativa a idempotency_key en el cuerpo: reenviar la misma llave devuelve la respuesta del primer intento (Idempotency-Replayed: true) en lugar de timbrar otra vez, y la misma llave con un cuerpo distinto es 422 IDEMPOTENCY_KEY_REUSED. Máximo 100 caracteres ASCII imprimibles, sin espacios. Si además envías el campo en el cuerpo, los dos valores deben coincidir; si no, la respuesta es 400 VALIDATION_ERROR.
100"order-4711"
Body
1Show child attributes
Show child attributes
Show child attributes
Show child attributes
1[A-Z&Ñ]{3,4}[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])[A-Z0-9]{2}[0-9A]Tipo de comprobante: I (ingreso), E (egreso) o P (pago).
I, E, P 1[IEP]CFDI relacionados (nodo CfdiRelacionados). Un elemento por tipo_relacion, con los folios fiscales (UUID) que relaciona. Caso típico: una nota de crédito (tipo_comprobante E) con tipo_relacion 01 y el UUID de la factura original.
Show child attributes
Show child attributes
Datos del emisor. Objeto opcional, y cada campo dentro de él es opcional por separado: el que envíes sobreescribe el default de la empresa registrada y el que omitas se toma de ella. El RFC nunca se envía aquí: rfc_emisor (raíz) es el que resuelve la empresa y su CSD.
Show child attributes
Show child attributes
Clave de exportación (c_Exportacion). Default: 01 (no aplica).
Fecha de emisión ISO 8601. Default: la fecha actual. El SAT acepta hasta 72 horas hacia atrás y 5 minutos hacia adelante.
\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})?Si se omite, Ipsofactura asigna el folio consecutivo siguiente para el emisor + serie.
40[^|]*Clave estable de la operación (p. ej. el id del pedido). Si reintentas la misma petición con la misma clave, Ipsofactura devuelve la respuesta del primer intento en lugar de timbrar un segundo CFDI. Si se omite y envías folio, la clave se deriva de rfc_emisor + tipo_comprobante + serie + folio. Máximo 100 caracteres.
100^[\x21-\x7E]+$Show child attributes
Show child attributes
Show child attributes
Show child attributes
Código postal de expedición. Default: el código postal de la empresa emisora.
Clave de moneda (c_Moneda). Default: MXN. Para moneda distinta de MXN, tipo_cambio es requerido.
25[^|]*Response
CFDI timbrado
Show child attributes
Show child attributes
La clave de idempotencia con la que se timbró este CFDI, si se envió una.