Skip to main content

Prerequisites

1

API key from Dashboard

Get your API key from the Cadana Dashboard. See Authentication for details.
2

Business with workers in supported jurisdictions

At least one business must be created with workers onboarded via the Persons Service in a supported jurisdiction.

Core Concepts

The Statutory Compliance API connects four existing Cadana services into a single compliance workflow:
ServiceWhat the Statutory API Uses
Businesses Service (/businesses)Employer identity: KYB.taxId, registrationId, nationalId, country, address
Persons Service (/v1/persons)Worker identity: taxId, nationalId, socialSecurityId, taxProfile, compensation
Tax Engine (/v1/tax)Gross-to-net calculation results with legislative citations
Payroll ServicePayroll run data — filing creation can be triggered from completed payroll runs

Step 1: Discover Jurisdictions

List every jurisdiction the Statutory API supports, along with the filing types available in each. Response:
{
  "data": [
    {
      "countryCode": "MX",
      "countryName": "Mexico",
      "currency": "MXN",
      "filingTypesCount": 4,
      "payrollFrequency": "MONTHLY",
      "status": "active"
    },
    {
      "countryCode": "BR",
      "countryName": "Brazil",
      "currency": "BRL",
      "filingTypesCount": 4,
      "payrollFrequency": "MONTHLY",
      "status": "active"
    }
  ]
}

Step 2: Understand a Jurisdiction

Once you know which jurisdictions are available, drill into a specific country to see its filing types, deadlines, and cadence. Response:
{
  "data": [
    {
      "id": "ft_mx_isr_monthly",
      "name": "ISR Withholding",
      "description": "Monthly income tax withholding return",
      "governmentFormName": "Declaración Provisional ISR",
      "authority": { "id": "auth_mx_sat", "name": "Servicio de Administración Tributaria", "abbreviation": "SAT" },
      "frequency": "MONTHLY",
      "dueDay": 17,
      "includesRemittance": true,
      "legislativeReference": "Ley del Impuesto Sobre la Renta (LISR), Artículo 96"
    },
    {
      "id": "ft_mx_imss_bimonthly",
      "name": "IMSS Contributions",
      "description": "Social security contributions",
      "authority": { "id": "auth_mx_imss", "name": "Instituto Mexicano del Seguro Social", "abbreviation": "IMSS" },
      "frequency": "BIMONTHLY",
      "dueDay": 17,
      "includesRemittance": true,
      "legislativeReference": "Ley del Seguro Social (LSS), Artículo 39"
    },
    {
      "id": "ft_mx_infonavit_bimonthly",
      "name": "INFONAVIT Contributions",
      "description": "Housing fund contributions",
      "authority": { "id": "auth_mx_infonavit", "name": "Instituto del Fondo Nacional de la Vivienda para los Trabajadores", "abbreviation": "INFONAVIT" },
      "frequency": "BIMONTHLY",
      "dueDay": 17,
      "includesRemittance": true,
      "legislativeReference": "Ley del INFONAVIT, Artículo 29"
    },
    {
      "id": "ft_mx_isn_monthly",
      "name": "ISN Payroll Tax",
      "description": "State-level payroll tax",
      "authority": { "id": "auth_mx_state", "name": "State Tax Authority", "abbreviation": "State" },
      "frequency": "MONTHLY",
      "dueDay": 17,
      "includesRemittance": true,
      "legislativeReference": "Ley de Hacienda del Estado (varies by state)"
    }
  ]
}

What Fields Do Workers Need?

Before filing, you need to know which fields are required on the Person record. The required-fields endpoint returns the exact fields needed for tax calculation and statutory filing in a given jurisdiction. Response:
{
  "countryCode": "MX",
  "workerType": "employee",
  "version": 3,
  "fields": [
    {
      "key": "first_name",
      "name": "First Name",
      "description": "Worker's legal first name, required on all statutory returns",
      "path": "firstName",
      "type": "string",
      "required": true,
      "scope": ["filing"]
    },
    {
      "key": "last_name",
      "name": "Last Name",
      "description": "Worker's legal last name, required on all statutory returns",
      "path": "lastName",
      "type": "string",
      "required": true,
      "scope": ["filing"]
    },
    {
      "key": "job_title",
      "name": "Job Title",
      "description": "Worker's job title, required for statutory classification",
      "path": "jobInfo.title",
      "type": "string",
      "required": true,
      "scope": ["filing"]
    },
    {
      "key": "start_date",
      "name": "Employment Start Date",
      "description": "Date the worker started employment, required for social security and filing",
      "path": "jobInfo.startDate",
      "type": "string",
      "required": true,
      "scope": ["filing"]
    },
    {
      "key": "tax_id",
      "name": "RFC (Registro Federal de Contribuyentes)",
      "description": "13-character tax ID for individuals",
      "path": "taxId",
      "type": "string",
      "pattern": "^[A-Z&Ñ]{4}\\d{6}[A-Z0-9]{3}$",
      "required": true,
      "scope": ["calculation", "filing"]
    },
    {
      "key": "imss_number",
      "name": "IMSS Social Security Number (NSS)",
      "description": "11-digit social security number",
      "path": "socialSecurityId",
      "type": "string",
      "required": true,
      "scope": ["filing"]
    },
    {
      "key": "marital_status",
      "name": "Marital Status",
      "description": "Used for tax deduction eligibility under LISR",
      "path": "taxProfile.maritalStatus",
      "type": "string",
      "required": true,
      "scope": ["calculation"],
      "enum": ["single", "married", "divorced", "widowed"]
    },
    {
      "key": "state",
      "name": "State",
      "description": "ISO 3166-2 state code (e.g. MX-JAL)",
      "path": "address.state",
      "type": "string",
      "required": true,
      "scope": ["calculation", "filing"]
    }
  ]
}
Fields like firstName, lastName, jobInfo.title, and jobInfo.startDate are required across all jurisdictions. Country-specific fields (tax IDs, social security numbers) vary by country and appear after the common fields in the response.
The scope field tells you why a field is needed. calculation means the Tax Engine uses it for gross-to-net math. filing means it appears on the statutory return submitted to the government. Some fields are needed for both.
The path field is a dot-path on the Person aggregate. For example, taxProfile.maritalStatus maps to the maritalStatus field inside the taxProfile object when creating or updating a Person.

Step 3: Check Requirements

Before you can file, every business and worker must meet the jurisdiction’s data requirements. The requirements endpoint gives you a checklist of what’s missing.

Business-Level Requirements

Response:
{
  "data": [
    {
      "category": "business_registration",
      "status": "outstanding",
      "name": "IMSS Employer Registration",
      "description": "IMSS employer registration number is required for social security filings",
      "affectedField": "imssRegistration",
      "resourceType": "business",
      "resourceId": "bus_abc123",
      "resolutionGuide": "Update the business KYB data via PUT /v1/businesses/{id}/kyb"
    },
    {
      "category": "worker_data",
      "status": "outstanding",
      "name": "Social Security Number (NSS)",
      "description": "Worker NSS is required for IMSS and INFONAVIT filings",
      "affectedField": "socialSecurityId",
      "resourceType": "person",
      "resourceId": "per_xyz789",
      "resolutionGuide": "Update the person profile via PUT /v1/persons/{id}/personalInfo",
      "affectedPersons": [
        {
          "personId": "per_xyz789",
          "personName": "María García",
          "missingField": "socialSecurityId",
          "missingFieldLabel": "IMSS Social Security Number (NSS)"
        }
      ]
    }
  ]
}
Each requirement includes a resolutionGuide that tells you exactly which endpoint to call and what data to provide. Once you update the upstream record, the requirement is resolved automatically.
Filings that depend on outstanding requirements will be in blocked status until the requirements are resolved. You do not need to manually retry — the Statutory API monitors upstream data changes and unblocks filings automatically.

Per-Worker Requirements

You can also check requirements for a specific worker to see what’s missing before their next payroll run. Response:
{
  "data": [
    {
      "category": "worker_data",
      "status": "outstanding",
      "name": "Job Title",
      "description": "Worker's job title is required for statutory classification",
      "affectedField": "jobInfo.title",
      "resourceType": "person",
      "resourceId": "per_xyz789",
      "resolutionGuide": "Update the person profile via PUT /v1/persons/{id}/personalInfo",
      "affectedPersons": [
        {
          "personId": "per_xyz789",
          "personName": "María García",
          "missingField": "jobInfo.title",
          "missingFieldLabel": "Job Title"
        }
      ]
    },
    {
      "category": "worker_data",
      "status": "outstanding",
      "name": "Social Security Number (NSS)",
      "description": "Worker NSS is required for IMSS and INFONAVIT filings",
      "affectedField": "socialSecurityId",
      "resourceType": "person",
      "resourceId": "per_xyz789",
      "resolutionGuide": "Update the person profile via PUT /v1/persons/{id}/personalInfo",
      "affectedPersons": [
        {
          "personId": "per_xyz789",
          "personName": "María García",
          "missingField": "socialSecurityId",
          "missingFieldLabel": "IMSS Social Security Number (NSS)"
        }
      ]
    }
  ]
}
Filter by status=outstanding to find what still needs attention. Once you update the upstream person or business record, requirements resolve automatically.

Step 4: Check the Compliance Calendar

Once requirements are met, list upcoming and active filings for a business. This gives you a view of the compliance calendar across all jurisdictions. Response:
{
  "data": [
    {
      "id": "fil_001",
      "businessId": "bus_abc123",
      "countryCode": "MX",
      "filingTypeId": "ft_mx_isr_monthly",
      "filingTypeName": "ISR Withholding",
      "authorityName": "SAT",
      "status": "pending",
      "period": { "start": "2024-06-01", "end": "2024-06-30", "label": "June 2024" },
      "dueAt": "2024-07-17",
      "workerCount": 12,
      "createdAt": "2024-07-01T00:00:00Z"
    },
    {
      "id": "fil_002",
      "businessId": "bus_abc123",
      "countryCode": "MX",
      "filingTypeId": "ft_mx_imss_bimonthly",
      "filingTypeName": "IMSS Contributions",
      "authorityName": "IMSS",
      "status": "blocked",
      "period": { "start": "2024-04-01", "end": "2024-06-30", "label": "Q2 2024" },
      "dueAt": "2024-07-17",
      "workerCount": 12,
      "createdAt": "2024-07-01T00:00:00Z"
    }
  ],
  "summary": {
    "total": 4,
    "pending": 2,
    "inReview": 0,
    "approved": 0,
    "submitted": 0,
    "accepted": 0,
    "blocked": 1,
    "cancelled": 0,
    "rejected": 0
  }
}
The summary object provides a quick overview of your compliance posture. Use blocked to surface filings that need attention.

Next Steps