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 — ComplianceOpinionDocument

ComplianceOpinionDocument 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 options are 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" }
  }
}