Compliance opinion (32-D)
The Opinión de Cumplimiento de Obligaciones Fiscales (Artículo 32-D) is an official SAT document that states whether a taxpayer is up to date with its fiscal obligations. Its key value is the sentido (result): Positivo, Negativo, No inscrito, or No localizado.
A compliance opinion is fetched by creating an extraction with extractor: "compliance_opinion". The same CIEC credentials stored for the entity are used to authenticate against the SAT portal.
Lifecycle
sequenceDiagram
autonumber
participant App as Your app
participant API as Meefi API
participant SAT as SAT portal
App->>+API: POST /v1/extractions
{ entity_id, extractor: "compliance_opinion" }
API-->>-App: 201 Created
{ status: pending }
Note over API,SAT: Async extraction
API->>+SAT: Authenticate with RFC + CIEC
SAT-->>API: Session established
API->>+SAT: Request 32-D PDF
SAT-->>-API: PDF bytes
API->>API: Parse PDF → result, folio, issued_at
API->>API: Upload PDF to storage
API->>API: Create ComplianceOpinionDocument record
API->>App: webhook compliance_opinion_document.create
API->>App: webhook extraction.update { status: finished }
App->>+API: GET /v1/compliance-opinion/{entity_id}
API-->>-App: 200 OK — ComplianceOpinionDocumentComplianceOpinionDocument object
| Field | Type | Description |
|---|---|---|
id |
UUID | Primary key |
result |
string | null | Sentido de la opinión: Positivo, Negativo, No inscrito, or No localizado |
folio |
string | null | Document folio assigned by the SAT |
issued_at |
date | null | Date the opinion was issued (YYYY-MM-DD) |
pdf_available |
boolean | Whether the raw PDF is available for download |
entity |
object | { id, name, tax_id } |
extraction |
object | { id, status } of the extraction that produced it |
Parsed fields are extracted from the PDF using pattern matching. If a field cannot be parsed it is returned as null; the document is still created and the PDF remains available for download.
Create a compliance opinion extraction
POST /v1/extractions
{
"entity_id": "018abc12-...",
"extractor": "compliance_opinion"
}
Requirements:
- The entity must have
credential_status: valid - No
optionsare required for compliance opinion extractions
Response (201 Created):
{
"id": "...",
"extractor": "compliance_opinion",
"status": "pending",
"entity": { "id": "...", "tax_id": "XAXX010101000", "name": "Acme SA de CV" }
}
Get the latest compliance opinion
GET /v1/compliance-opinion/{entity_id}
Returns the most recently created ComplianceOpinionDocument for the entity. Returns 404 if no compliance opinion extraction has completed yet.
{
"id": "...",
"result": "Positivo",
"folio": "ABCD1234567890",
"issued_at": "2026-06-10",
"pdf_available": true,
"entity": { "id": "...", "name": "Acme SA de CV", "tax_id": "XAXX010101000" },
"extraction": { "id": "...", "status": "finished" }
}
Download the compliance opinion PDF
GET /v1/compliance-opinion/{entity_id}/download
Returns the raw PDF encoded as base64. Decode the data field and save it with a .pdf extension. Returns 404 if the PDF is unavailable.
{
"data": "JVBERi0xLjcK...",
"mime_type": "application/pdf",
"filename": "compliance_opinion_XAXX010101000.pdf",
"encoding": "base64"
}
Webhooks
Two events fire during a compliance opinion extraction:
extraction.update
Fires twice: when the extraction moves to running, and when it reaches finished or failed.
{
"type": "extraction.update",
"object": {
"status": "finished",
"entity": { "id": "...", "tax_id": "XAXX010101000", "name": "Acme SA de CV" }
}
}
compliance_opinion_document.create
Fires once when the compliance opinion document is created (after the PDF is parsed). This is the signal that a new opinion is available.
{
"type": "compliance_opinion_document.create",
"object": {
"id": "...",
"entity_id": "...",
"extraction_id": "...",
"result": "Positivo",
"folio": "ABCD1234567890",
"issued_at": "2026-06-10",
"entity": { "id": "...", "tax_id": "XAXX010101000", "name": "Acme SA de CV" }
}
}