curl --request GET \
--url https://api.example.com/invoices/{uuid} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.example.com/invoices/{uuid}"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.example.com/invoices/{uuid}', 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.example.com/invoices/{uuid}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <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"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/invoices/{uuid}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/invoices/{uuid}")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/invoices/{uuid}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "0f2a1c3e-1a2b-4c3d-9e8f-1234567890ab",
"uuid": "d3bfbc57-44af-4390-a064-f0afab85e5df",
"status": "valid",
"type": "I",
"series": "A",
"folioNumber": "1",
"total": 116,
"date": "2026-07-30T22:50:00",
"xml": "<string>",
"createdAt": "2026-07-30T22:50:03.412Z",
"environment": "production",
"rfcReceptor": "GODE561231GR8",
"relatedCfdis": [
{
"type": "04",
"uuids": [
"D3BFBC57-44AF-4390-A064-F0AFAB85E5DF"
]
}
],
"substitutedBy": [
{
"uuid": "6F2B1C9A-3D4E-4F5A-8B7C-9D0E1F2A3B4C",
"serie": "A",
"folio": "124",
"status": "vigente"
}
]
}Get Invoice
Authenticate with either a Supabase session (member of the invoice’s organization) or an API key belonging to that same organization. Returns the same shape as the POST /invoices response — use this to recover an invoice’s metadata/XML if the original create response was lost.
curl --request GET \
--url https://api.example.com/invoices/{uuid} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.example.com/invoices/{uuid}"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.example.com/invoices/{uuid}', 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.example.com/invoices/{uuid}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <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"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/invoices/{uuid}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/invoices/{uuid}")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/invoices/{uuid}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "0f2a1c3e-1a2b-4c3d-9e8f-1234567890ab",
"uuid": "d3bfbc57-44af-4390-a064-f0afab85e5df",
"status": "valid",
"type": "I",
"series": "A",
"folioNumber": "1",
"total": 116,
"date": "2026-07-30T22:50:00",
"xml": "<string>",
"createdAt": "2026-07-30T22:50:03.412Z",
"environment": "production",
"rfcReceptor": "GODE561231GR8",
"relatedCfdis": [
{
"type": "04",
"uuids": [
"D3BFBC57-44AF-4390-A064-F0AFAB85E5DF"
]
}
],
"substitutedBy": [
{
"uuid": "6F2B1C9A-3D4E-4F5A-8B7C-9D0E1F2A3B4C",
"serie": "A",
"folio": "124",
"status": "vigente"
}
]
}/organizations/{organizationId}/ in the URL. The invoice’s uuid (its folio fiscal, globally unique across all organizations) is enough to resolve the owning organization server-side, combined with the caller’s own auth context (session or API key).
Authentication
Accepts either:- A Supabase Bearer session (
Authorization: Bearer <token>) — the authenticated user must be a member of the invoice’s organization. - An API key (
X-API-Key: sk_...) with theread:invoicesscope — the key’s own organization must match the invoice’s organization, or the request is rejected with403 Forbidden.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
uuid | string (UUID) | Yes | Folio fiscal UUID (uuidFiscal) of the invoice to fetch — globally unique, not scoped to an organization |
Example Request
curl -X GET https://api.timbrix.mx/invoices/d3bfbc57-44af-4390-a064-f0afab85e5df \
-H "Authorization: Bearer <your_token>"
const invoice = await timbrix.invoices.get(
"d3bfbc57-44af-4390-a064-f0afab85e5df"
)
console.log(invoice.xml)
Example Response
{
"id": "0f2a1c3e-1a2b-4c3d-9e8f-1234567890ab",
"uuid": "d3bfbc57-44af-4390-a064-f0afab85e5df",
"status": "valid",
"type": "I",
"series": "A",
"folioNumber": "1",
"total": 116,
"date": "2026-07-30T15:50:00",
"xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><cfdi:Comprobante ...>",
"rfcReceptor": "GODE561231GR8",
"relatedCfdis": [],
"substitutedBy": [
{
"uuid": "a1b2c3d4-5e6f-4890-9abc-def012345678",
"serie": "A",
"folio": "2",
"status": "vigente"
}
],
"createdAt": "2026-07-30T15:50:03.412Z"
}
| Field | Type | Description |
|---|---|---|
id | string | Timbrix invoice record ID |
uuid | string | Folio fiscal UUID asignado por el SAT vía PAC |
status | string | Always "valid" — this endpoint only ever returns stamped CFDIs |
type | string | I = Ingreso, E = Egreso, T = Traslado |
series | string | Invoice series |
folioNumber | string | Invoice folio number |
total | number | Invoice total |
date | string | Issuance date-time (ISO 8601, no timezone) |
xml | string | The full stamped CFDI XML, inline (UTF-8) |
rfcReceptor | string | RFC of the receptor (customer) |
relatedCfdis | array | CFDI this one relates to, as { type, uuids }. Empty when none. A substitute CFDI carries [{ "type": "04", "uuids": ["<UUID of the CFDI it substitutes>"] }] — see Substituting a CFDI |
substitutedBy | array | CFDI whose 04 relation points at this one, as { uuid, serie, folio, status } (status is vigente or cancelado). Empty when this CFDI has not been substituted |
createdAt | string | ISO 8601 timestamp of when the CFDI was stamped |
status, type, and the full xml — fields not
present in the List Invoices summary shape. If
you only need the XML file itself (not wrapped in JSON), use Download Invoice
XML instead.Common Errors
401 Unauthorized
Missing or invalid Bearer token / API key.403 Forbidden
The authenticated user is not a member of the invoice’s organization, or the API key does not have theread:invoices scope / belongs to a different organization than the one that owns the invoice.
404 Not Found
uuid does not match any invoice.Authorizations
API Key for authentication (format: sk_...)
Path Parameters
Response
Timbrix invoice record ID
"0f2a1c3e-1a2b-4c3d-9e8f-1234567890ab"
Folio fiscal UUID asignado por el SAT vía PAC
"d3bfbc57-44af-4390-a064-f0afab85e5df"
valid "valid"
I = Ingreso, E = Egreso, T = Traslado
I, E, T "I"
"A"
"1"
116
"2026-07-30T22:50:00"
XML del CFDI timbrado (UTF-8)
"2026-07-30T22:50:03.412Z"
Ambiente en el que se timbró el CFDI. Los CFDI de sandbox no tienen validez fiscal ante el SAT.
sandbox, production "production"
RFC del receptor del CFDI
"GODE561231GR8"
Relaciones de este CFDI (CfdisRelacionados). Con tipo 04 apunta al CFDI que sustituye.
Show child attributes
Show child attributes
CFDI cuya relación 04 apunta a este comprobante (sustitutos emitidos).
Show child attributes
Show child attributes