Architecture

How Meefi Analytics fits into your integration: resources, data flow, and how invoice amounts are derived.

System context

flowchart TB
    subgraph Client["Your product"]
        App[Application / backend]
        Hook[Webhook handler]
    end

    subgraph Meefi["Meefi Analytics"]
        API["REST API
/v1"] Worker[Background processing] API --> Worker end subgraph External["External systems"] SAT[SAT CFDI portal] end App <-->|"HTTP Basic · JSON"| API API -->|"POST events
Bearer token"| Hook Worker <-->|"CIEC session"| SAT
Layer Responsibility
API (/v1) Entities, extractions, invoices, webhooks
Background processing SAT sync, XML parsing, aggregate updates

All API resources belong to your organization. Requests cannot access another organization's data.

Core resources

erDiagram
    ORGANIZATION ||--o{ ENTITY : owns
    ORGANIZATION ||--o{ WEBHOOK : owns
    ENTITY ||--o{ EXTRACTION : runs
    ENTITY ||--o{ INVOICE : contains
    INVOICE ||--o{ PAYMENT : "type P only"
    INVOICE ||--o{ INVOICE_RELATION : links

    ORGANIZATION {
        uuid id
        string name
    }
    ENTITY {
        uuid id
        string tax_id
        string credential_status
    }
    EXTRACTION {
        uuid id
        string status
        json options
    }
    INVOICE {
        uuid id
        string uuid
        string type
        string status
    }

Entity

One SAT taxpayer (RFC) registered with a CIEC password. The service validates credentials with the SAT before extractions can succeed.

credential_status Meaning
pending Validation in progress
valid CIEC accepted
invalid CIEC rejected — update the password
error SAT unreachable after retries

Extraction

An asynchronous job that downloads CFDI for a date range, parses XML, links related documents, and refreshes financial aggregates.

Status Meaning
pending Queued
running Download or processing in progress
finished Completed successfully
failed Could not complete — check failed_reason if present

Invoice

One CFDI UUID for an entity. List endpoints return processed invoices only (is_processed = true): metadata plus parsed XML fields and aggregates.

type Role
I Income invoice — PPD or PUE; receives payment aggregates
E Credit note — may reduce a type I invoice
P Payment complement — records payments against other UUIDs
N Payroll
T Transfer

End-to-end data flow

sequenceDiagram
    autonumber
    participant App as Your app
    participant API as Meefi API
    participant Worker as Processing
    participant SAT as SAT portal

    App->>+API: POST /v1/extractions
    API-->>-App: 201 { id, status: pending }

    API->>+Worker: Enqueue extraction job
    Worker->>Worker: status → running
    Worker->>+SAT: CIEC login + list CFDI by month
    SAT-->>-Worker: Metadata list

    loop Each invoice in range
        Worker->>SAT: Download XML / PDF
        Worker->>Worker: Parse CFDI fields
        Worker->>Worker: Store metadata + files
    end

    Worker->>Worker: Link payment complements → invoices
    Worker->>Worker: Link credit notes → invoices
    Worker->>Worker: Refresh paid / due / credited amounts
    Worker->>Worker: status → finished

    App->>+API: GET /v1/extractions/{id}
    API-->>-App: 200 { status: finished }

    App->>+API: GET /v1/entities/{id}/invoices
    API-->>-App: 200 Invoice collection

Payment complements and missing invoices

A type P complement references type I invoices by UUID. If the original invoice is outside your extraction window, the payment is stored and linked automatically when that invoice is downloaded in a later extraction.

flowchart LR
    P["Type P complement
references UUID X"] I["Type I invoice
UUID X"] Agg["Aggregates on invoice X
paid_amount · due_amount"] P -->|"stored immediately"| Pending[(Pending link)] Pending -->|"invoice X downloaded
in later extraction"| I I --> Agg P --> Agg

See Extractions — Historical coverage.

Financial aggregates (type I, PPD)

Field Meaning
due_amount Outstanding balance from the latest payment complement
paid_amount Total paid so far
last_payment_at Most recent payment date
fully_paid_at Set when the invoice is fully paid
credited_amount Sum of eligible linked credit notes
subtotal_credited_amount Subtotal portion of those credit notes

PUE invoices are paid at issuance; these fields stay empty.

Webhooks

When extraction status or entity credentials change, the API POSTs an event to your registered URLs.

Event When
extraction.update Extraction starts, finishes, or fails
entity.update Credential validation completes or status changes

Deliveries include Authorization: Bearer {webhook.token}. Return 2xx quickly and handle retries idempotently.

API map

Area Prefix Purpose
Entities /v1/entities Register and manage RFC + CIEC
Extractions /v1/extractions, /v1/entities/{id}/extractions Start and monitor downloads
Invoices /v1/entities/{id}/invoices, /v1/invoices/{id} Query processed CFDI
Webhooks /v1/webhooks Subscribe to events
Health /up Service liveness (no auth)

Request and response schemas: OpenAPI reference.

Recommended integration

sequenceDiagram
    autonumber
    participant App as Your app
    participant API as Meefi API

    App->>API: POST /entities
    Note over App,API: Store entity id

    loop Poll until valid
        App->>API: GET /entities/{id}
    end

    App->>API: POST /extractions (12+ month backfill)
    Note over App,API: Poll or webhook until finished

    App->>API: POST /extractions (incremental sync)
    App->>API: GET /entities/{id}/invoices?filters
    App->>API: GET /invoices/{id}/cfdi