> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cadanapay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Statutory Filing

> File statutory returns with government authorities across jurisdictions

export const ApiExample = ({method = "GET", path, params, body, reference, tenantKey}) => {
  const baseUrl = "https://api.cadanapay.com";
  const query = params ? "?" + Object.entries(params).map(([k, v]) => `${k}=${v}`).join("&") : "";
  const url = `${baseUrl}${path}${query}`;
  const isPlatformPath = (/^\/(v1\/)?platform(\/|$)/).test(path || "");
  const includeTenantKey = tenantKey === undefined ? !isPlatformPath : tenantKey;
  let curl = `curl -X ${method} '${url}' \\\n  -H 'Authorization: Bearer YOUR_API_KEY'`;
  if (includeTenantKey) {
    curl += ` \\\n  -H 'X-MultiTenantKey: YOUR_BUSINESS_TENANT_KEY'`;
  }
  if (body) {
    const formatted = JSON.stringify(body, null, 2);
    curl += ` \\\n  -H 'Content-Type: application/json' \\\n  -d '${formatted}'`;
  }
  return <div>
      <CodeBlock language="bash" filename="bash" wrap>
        {curl}
      </CodeBlock>
      {reference && <div style={{
    marginTop: "-0.5rem",
    marginBottom: "1rem"
  }}>
          <a href={reference} style={{
    fontSize: "0.875rem"
  }}>
            Try it in the playground →
          </a>
        </div>}
    </div>;
};

<Note>
  **Beta** — this functionality is fully supported today: statutory obligations are calculated, withheld, filed, and remitted for you as part of [Cadana's payroll process](/workforce/pay-workers-via-payroll). What's in beta is the standalone API surface on this page, which puts filings and remittances under your direct, self-serve control. Contact Cadana to enable it for your business.
</Note>

A filing is the unit of statutory obligation — one return for one authority, one period. Every filing is described by a `breakdown` of contribution lines that sum to the filing total — that breakdown is what gives the filing its meaning, whether Cadana prepared it or you did.

Filings come from two sources:

* **`source: cadana`** — Cadana submits the return to the authority on your behalf. Each breakdown line must reference a `personId`. You can either link a Cadana payroll run (Cadana populates the breakdown from the tax engine) or provide the breakdown yourself if you computed the amounts elsewhere. Filings run the full `pending → in_review → approved → submitted → accepted` lifecycle.
* **`source: external`** — You filed the return with the authority yourself and are sending Cadana the resulting data so a remittance can be created. Breakdown lines may use `personId`, `externalEmployeeId`, or neither (for business-level taxes). The filing is created directly in `accepted` and skips the submission lifecycle. See the [Remittance walkthrough](/statutory/remittance#remittance-only-walkthrough-external-filing) for the end-to-end flow.

This page covers the `source: cadana` flow — Cadana-prepared filings — including review, approval, and submission.

***

## How It Works

<Steps>
  <Step title="Create filings">
    After payroll closes, batch-create all required filings for the period. Cadana determines the applicable filing types based on country, business registrations, and employee profiles.
  </Step>

  <Step title="Review and approve">
    Your finance team reviews the amounts and line items, then approves each filing for submission.
  </Step>

  <Step title="Cadana submits">
    Cadana submits the filing to the relevant government authority (SAT, IMSS, INFONAVIT, etc.).
  </Step>

  <Step title="Authority accepts">
    The authority confirms receipt. Download the acknowledgement document for your records.
  </Step>
</Steps>

***

## Step 1: Create Filings

### From a Cadana Payroll Run

Create all required filings for a period in a single call by referencing a completed payroll run:

<ApiExample method="POST" path="/v1/statutory/filings/batch" body={{ businessId: "biz_01ABC", periodStart: "2026-02-01", periodEnd: "2026-02-28", payrollRunIds: ["pr_01MNO"] }} reference="/api-reference/statutory/filings/create-all-filings-for-a-period" />

**Response:**

```json theme={null}
{
  "data": [
    {
      "id": "fil_01JKL",
      "source": "cadana",
      "filingTypeId": "ft_mx_isr_monthly",
      "filingTypeName": "ISR Withholding",
      "authorityName": "SAT",
      "status": "pending",
      "dueAt": "2026-03-17",
      "amounts": { "currency": "MXN", "total": 82345.00 }
    },
    {
      "id": "fil_02MNO",
      "source": "cadana",
      "filingTypeId": "ft_mx_imss_bimonthly",
      "filingTypeName": "IMSS Contributions",
      "authorityName": "IMSS",
      "status": "pending",
      "dueAt": "2026-03-17",
      "amounts": { "currency": "MXN", "total": 45123.00 }
    }
  ]
}
```

### Without a Cadana Payroll Run

If you calculate taxes outside Cadana but want Cadana to file with the authority, create the filing one at a time with `source: cadana` and provide the `breakdown` directly. Each breakdown line must reference a `personId` so Cadana has the worker context it needs to file. The filing still runs the full review and submission lifecycle.

<ApiExample
  method="POST"
  path="/v1/statutory/filings"
  body={{
businessId: "biz_01ABC",
countryCode: "MX",
source: "cadana",
filingTypeId: "ft_mx_isr_monthly",
periodStart: "2026-02-01",
periodEnd: "2026-02-28",
currency: "MXN",
breakdown: [
  { personId: "per_01ABC", amount: 5489.67 },
  { personId: "per_02DEF", amount: 6121.40 },
  { personId: "per_03GHI", amount: 4998.20 }
]
}}
  reference="/api-reference/statutory/filings/create-a-filing"
/>

<Info>
  Already filed with the authority yourself and just need Cadana to remit? Use `source: external` instead — the filing is created directly in `accepted`, breakdown lines can identify workers by `externalEmployeeId`, and you provide the `filingReference` from the authority. See the [Remittance-only walkthrough](/statutory/remittance#remittance-only-walkthrough-external-filing).
</Info>

### Inspect Filing Detail

Each filing returns its `breakdown` (the contribution lines you supplied or that Cadana derived from payroll) plus a derived `amounts` rollup:

<ApiExample method="GET" path="/v1/statutory/filings/fil_01JKL" reference="/api-reference/statutory/filings/get-a-filing" />

**Response:**

```json theme={null}
{
  "id": "fil_01JKL",
  "businessId": "biz_01ABC",
  "source": "cadana",
  "filingTypeId": "ft_mx_isr_monthly",
  "filingTypeName": "ISR Withholding",
  "authorityId": "auth_mx_sat",
  "authorityName": "SAT",
  "countryCode": "MX",
  "period": { "start": "2026-02-01", "end": "2026-02-28", "label": "February 2026" },
  "status": "pending",
  "dueAt": "2026-03-17",
  "workerCount": 15,
  "amounts": {
    "currency": "MXN",
    "total": 82345.00
  },
  "breakdown": [
    { "personId": "per_01ABC", "employeeName": "María García López", "amount": 5489.67 },
    { "personId": "per_02DEF", "employeeName": "Juan Pérez Rivera",  "amount": 6121.40 },
    { "personId": "per_03GHI", "employeeName": "Ana Hernández",      "amount": 4998.20 }
  ],
  "payrollRunIds": ["pr_01MNO"],
  "createdAt": 1709280000
}
```

<Tip>
  `amounts.total` is computed from `breakdown` — you never pass `amounts` on create. The breakdown is the source of truth; the total is just its sum.
</Tip>

***

## Step 2: Review and Approve

Before Cadana submits a filing, it must be approved. This gives your finance team a chance to review the amounts.

<ApiExample method="POST" path="/v1/statutory/filings/fil_01JKL/approve" reference="/api-reference/statutory/filings/approve-a-filing-for-submission" />

The endpoint returns `204 No Content` on success. Fetch the filing to see the updated status:

<ApiExample method="GET" path="/v1/statutory/filings/fil_01JKL" reference="/api-reference/statutory/filings/get-a-filing" />

**Response:**

```json theme={null}
{
  "id": "fil_01JKL",
  "filingTypeId": "ft_mx_isr_monthly",
  "filingTypeName": "ISR Withholding",
  "authorityName": "SAT",
  "status": "approved",
  "dueAt": "2026-03-17",
  "amounts": { "currency": "MXN", "total": 82345.00 },
  "statusHistory": [
    { "from": "in_review", "to": "approved", "timestamp": "2026-03-05T14:30:00Z" }
  ]
}
```

<Warning>
  A filing must be in `in_review` status before it can be approved. Once approved, the filing is queued for submission. Review amounts carefully before approving — reversals require contacting the tax authority directly.
</Warning>

***

## Step 3: Submission and Acceptance

After approval, Cadana submits the filing to the authority. The status transitions through `submitted` → `accepted`. Poll the filing or listen for the `filing.accepted` webhook event:

```json theme={null}
{
  "id": "fil_01JKL",
  "filingTypeId": "ft_mx_isr_monthly",
  "filingTypeName": "ISR Withholding",
  "authorityId": "auth_mx_sat",
  "authorityName": "SAT",
  "status": "accepted",
  "dueAt": "2026-03-17",
  "filingReference": "0123456ABCD7890EF",
  "amounts": { "currency": "MXN", "total": 82345.00 },
  "statusHistory": [
    { "from": "pending", "to": "in_review", "timestamp": 1709654400 },
    { "from": "in_review", "to": "approved", "timestamp": 1709656200 },
    { "from": "approved", "to": "submitted", "timestamp": 1709658000 },
    { "from": "submitted", "to": "accepted", "timestamp": 1709658150 }
  ]
}
```

Once the authority confirms receipt, Cadana populates the `filingReference` field (e.g., the Línea de Captura returned by SAT). This is the reference your subsequent remittance will use to attribute the payment.

***

## Filing Lifecycle

The lifecycle below applies to `source: cadana` filings. `source: external` filings are created directly in `accepted` and do not transition through the other states.

```
pending → in_review → approved → submitted → accepted
  |          |                        |
  v          v                        v
blocked   blocked                  rejected
  |          |                        |
  v          v                        v
pending   pending               pending (retry)
```

| Status      | Description                                                                      |
| :---------- | :------------------------------------------------------------------------------- |
| `pending`   | Created with amounts, ready for review                                           |
| `in_review` | Validated and ready for approval                                                 |
| `approved`  | Queued for submission to government authority                                    |
| `submitted` | Sent to the authority                                                            |
| `accepted`  | Authority acknowledged receipt — terminal state for both `cadana` and `external` |
| `blocked`   | Missing data prevents submission — returns to `pending` when data is updated     |
| `rejected`  | Authority rejected the filing — returns to `pending` for correction              |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Statutory Remittance" icon="building-columns" href="/statutory/remittance">
    Pay government authorities after filings are accepted
  </Card>

  <Card title="The Full Loop" icon="arrows-rotate" href="/statutory/the-full-loop">
    See filing and remittance together in an end-to-end walkthrough
  </Card>

  <Card title="Getting Started" icon="rocket" href="/statutory/getting-started">
    Discover jurisdictions, required fields, and requirements
  </Card>

  <Card title="Filing API Reference" icon="code" href="/api-reference/statutory">
    Full endpoint documentation
  </Card>
</CardGroup>
