Maintain Modelo 036 census facts in your profile

Use this guide to keep your AEAT census facts - the censo - correct in the active local profile. In Spain, the censo is tied to Modelo 036 registration and changes.

This guide covers Modelo 036. Modelo 037 is superseded and not used in this workflow.

You fill census facts three ways: pull them from AEAT, read them from a certificate you downloaded, or enter them by hand. The pull reads AEAT’s own Mis Datos Censales consulta and fills your identity and address; it cannot reach the regime facts, so you enter those yourself.

The tool never files Modelo 036, never submits changes to AEAT, and never modifies AEAT records. The pull reads and stops there.

Before you start

You need:

  • an active taxpayer profile; see Set up your taxpayer profile

  • the taxpayer’s fiscal ID (NIF, CIF, DNI, or NIE) saved in that profile

  • your censo facts as AEAT holds them: activity description and start date, tax regime, IVA regime, and enrollment facts. Read them from your Modelo 036 copy or from the AEAT sede.

Every command on this page needs your master-key passphrase; the tool prompts for it. The tool’s messages are in Spanish.

If you have no profile yet, create one non-interactively with --quiet (a bare profile create NAME opens an interactive wizard instead):

1Create a taxpayer profile non-interactively.
aeat config profile create me --quiet --tax-residence-jurisdiction-scope common_regime \
  --entity-type natural_person --tax-id 12345678Z --name Ana --surnames Garcia Lopez \
  --activity consultoria
aeat config profile create me --quiet --tax-residence-jurisdiction-scope common_regime `
  --entity-type natural_person --tax-id 12345678Z --name Ana --surnames Garcia Lopez `
  --activity consultoria

Check the active profile first:

1Check the active profile.
aeat --format json config profile status
aeat --format json config profile status
{
  "active_profile": "docs-sequence-sandbox",
  "command": "config.profile.status",
  "notices": [],
  "result": {
    "active_profile": "docs-sequence-sandbox",
    "activity_present": true,
    "configured": true,
    "iva_regime": "GENERAL",
    "precondition_action": null,
    "profile_id": "<profile-id>",
    "profile_record_error": null,
    "profile_record_present": null,
    "registered_profile": null,
    "tax_id_present": true,
    "tax_residence_ccaa": ""
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the active profile reports its status.

Why census facts matter

Census facts drive profile-dependent workflows:

  • the activity start date keeps the filing calendar from showing obligations before your registered activity start

  • the tax regime, IVA regime, and Renta/IRPF regime select which modelos and which calculation paths apply

  • enrollment facts feed the filing calendar’s obligation derivation

Enter them carefully. The application treats your entries as operator-declared facts, not as AEAT-verified facts. The filing calendar reports census-dependent obligations with a censo.enrolment_unverified warning and refuses strict projection until you accept that basis; see Plan your filing calendar.

Enter or correct census facts

Edit the active profile with the wizard:

1Edit the active profile with the interactive wizard.
aeat config profile edit <profile-name>
aeat config profile edit <profile-name>

The wizard walks the profile fields, including the census-backed ones. For a scripted update, pass the field flags with --quiet. Name your own profile in place of docs-sequence-sandbox:

1Record the activity description from your Modelo 036 copy.
aeat --format json config profile edit docs-sequence-sandbox --quiet --activity \
  consultoria
aeat --format json config profile edit docs-sequence-sandbox --quiet --activity `
  consultoria
{
  "active_profile": "docs-sequence-sandbox",
  "command": "config.profile.edit",
  "notices": [],
  "result": {
    "profile_name": "docs-sequence-sandbox",
    "status": "updated"
  },
  "schema_version": "2",
  "status": "success"
}
2Confirm the edited profile still validates.
aeat --format json config profile validate {edited_profile_name}
aeat --format json config profile validate {edited_profile_name}
{
  "active_profile": "docs-sequence-sandbox",
  "command": "config.profile.validate",
  "notices": [],
  "result": {
    "display_name": "docs-sequence-sandbox",
    "issues": [],
    "profile_id": "<profile-id>",
    "schema_version": 6,
    "setup_state": "complete",
    "valid": true
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the profile validates after you record the census facts.

Copy each value from your Modelo 036 copy or the AEAT sede exactly. Do not guess a regime or a start date.

Pull your census facts from AEAT

AEAT publishes your current census position at Mis Datos Censales. Pull it into the active profile. The first step previews; the second performs a new authenticated read and records that read’s eligible facts:

1Preview the census facts AEAT holds for you.
aeat config profile censo pull
aeat config profile censo pull
2Acquire once, review the exact proposal, and apply it through the canonical resumable operation.
aeat config profile censo pull --apply
aeat config profile censo pull --apply

Nothing is written until you add --apply.

Warning

The current CLI does not turn the first command’s preview into a saved approval. The --apply command reads AEAT again and applies that new observation. Review the --apply result itself before relying on the updated profile. Work is in progress to expose the application’s captured, exact-baseline reviewed-apply lifecycle on this command; until that lands, do not treat the earlier preview as the operand that was applied.

Authenticate first; see Authenticate with AEAT. The pull reads your own record and takes your fiscal ID from the authenticated session, so you cannot point it at another taxpayer.

What the pull reports

Every field comes back as one of three outcomes.

Adopted: the profile had no answer, or the value came from an earlier censal read, so --apply writes AEAT’s current value. A preview only reports what would be eligible.

Unchanged: you and AEAT already agree.

Diverging: you and AEAT disagree. The pull reports the difference and writes nothing. You decide which is right, then correct the profile or your censo. A value you declared is never overwritten. A field you deliberately cleared stays cleared, and the pull tells you AEAT still holds a value for it.

Once the pull has filled a blank field, a later pull refreshes that same field when AEAT’s value changes. It filled it, so it may update it. Anything you declared yourself stays yours.

What the pull cannot fill

The pull fills your fiscal address, postcode, and cadastral reference.

It does not fill your fiscal ID. It reads your fiscal ID to confirm the record AEAT returned is yours, and never writes it.

It does not fill your regime facts: activity, tax regime, IVA regime, enrollment. AEAT publishes no read-only surface that carries them. Enter those by hand as described below.

It does not split your name. AEAT returns surnames and given names as one string, and a wrong split is worse than a blank field, so the pull leaves both alone.

If a pull returns a record whose fiscal ID is not your profile’s, it refuses outright rather than reporting a difference. A read of someone else’s census is not a disagreement to weigh.

Import a Certificado de Situación Censal

The sede issues a Certificado de Situación Censal (procedure G313) that states your census facts as AEAT holds them. Download it yourself from the sede, then read it into your profile from the file. The first step previews; the second records:

1Preview the census facts the downloaded certificate carries.
aeat config profile censo import --file certificado-g313.pdf
aeat config profile censo import --file certificado-g313.pdf
2Record the certificate's facts onto the active profile.
aeat config profile censo import --file certificado-g313.pdf --apply
aeat config profile censo import --file certificado-g313.pdf --apply

The command previews the census facts the certificate carries without writing anything. Add --apply to record them onto the active profile.

Facts recorded this way carry a non-official evidence marker: they came from a document you supplied, not from an AEAT-confirmed read, so profile views show their provenance and the filing calendar’s censo.enrolment_unverified warning still applies. Where a certificate value disagrees with an answer you gave in setup, the profile keeps a record of the divergence and aeat config profile view warns you until you resolve it.

Note

Reading the certificate’s contents is not yet active: the command currently refuses every document while layout coverage for AEAT-issued certificates is being completed, and tells you so. Until then, enter the facts by hand as described above. The command’s interface is stable, and this page applies unchanged once reading activates.

Record a Modelo 036 filing done outside Cadrumo

If you file a Modelo 036 alta, modificacion, or baja in AEAT’s sede, record that fact locally so later filings can rely on it. Record a Modelo 036 declaration you filed at AEAT owns the commands, the success output, and what the record does and does not change. After you record a filing, update the profile fields the filing changed.

Check the profile afterwards

Validate the active profile after editing census facts:

1Read the active profile status.
aeat --format json config profile status
aeat --format json config profile status
{
  "active_profile": "docs-sequence-sandbox",
  "command": "config.profile.status",
  "notices": [],
  "result": {
    "active_profile": "docs-sequence-sandbox",
    "activity_present": true,
    "configured": true,
    "iva_regime": "GENERAL",
    "precondition_action": null,
    "profile_id": "<profile-id>",
    "profile_record_error": null,
    "profile_record_present": null,
    "registered_profile": null,
    "tax_id_present": true,
    "tax_residence_ccaa": ""
  },
  "schema_version": "2",
  "status": "success"
}
2Validate the active profile.
aeat --format json config profile validate {active_profile_name}
aeat --format json config profile validate {active_profile_name}
{
  "active_profile": "docs-sequence-sandbox",
  "command": "config.profile.validate",
  "notices": [],
  "result": {
    "display_name": "docs-sequence-sandbox",
    "issues": [],
    "profile_id": "<profile-id>",
    "schema_version": 6,
    "setup_state": "complete",
    "valid": true
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the active profile validates after the census edits.

If the profile still reports missing facts, edit those fields directly:

1Edit a specific profile field directly.
aeat config profile edit <profile-name> --quiet --activity <value>
aeat config profile edit <profile-name> --quiet --activity <value>

For modelo-specific readiness, use modelo readiness:

1Check readiness for Modelo 303, first quarter of 2026.
aeat --format json app modelo readiness --modelo 303 --year 2026 --period 1T
aeat --format json app modelo readiness --modelo 303 --year 2026 --period 1T
{
  "active_profile": "docs-sequence-sandbox",
  "command": "modelo.readiness",
  "notices": [
    {
      "action": null,
      "code": "modelo.readiness.per_operation_axis_not_assessed",
      "context": {
        "modelo": "303",
        "profile_ready": "True"
      },
      "message": "No schema-required profile field is currently declared for Modelo 303, so profile_ready reflects only the export-identity and conditional checks, not a per-modelo assessment. Do not read profile_ready as a complete check for this modelo.",
      "severity": "warning"
    },
    {
      "action": null,
      "code": "modelo.readiness.ledger_preflight_scope",
      "context": {
        "binding_ready": "false",
        "ledger_ready": "true",
        "missing_bindings": "4"
      },
      "message": "ledger_ready only means the period ledger rows passed transaction preflight; missing_bindings/source_binding_ready still decide source completeness.",
      "severity": "info"
    }
  ],
  "result": {
    "binding_ready": false,
    "filing_year": 2026,
    "ledger_checked_transaction_count": 0,
    "ledger_issues": [],
    "ledger_period": {
      "code": "1T",
      "filing_year": 2026
    },
    "ledger_preflight_required": true,
    "ledger_ready": true,
    "missing": [],
    "missing_bindings": [
      {
        "binding_id": "modelo-303-autoconsumo-promotor-base",
        "input_channel": "decimal",
        "source": "profile"
      },
      {
        "binding_id": "modelo-303-bienes-inversion-regularizacion-casilla-43",
        "input_channel": "decimal",
        "source": "bienes_inversion_regularizacion"
      },
      {
        "binding_id": "modelo-303-compensacion-pendiente-anteriores",
        "input_channel": "decimal",
        "source": "previous_filing"
      },
      {
        "binding_id": "modelo-303-prorrata-regularizacion-casilla-44",
        "input_channel": "decimal",
        "source": "prorrata_regularizacion"
      }
    ],
    "modelo": "303",
    "operation": "modelo.readiness",
    "period": {
      "code": "1T",
      "filing_year": 2026
    },
    "profile_id": "<profile-id>",
    "profile_ready": true,
    "profile_refusal": "",
    "ready": false,
    "registry_ready": true,
    "registry_refusal": "",
    "revision_id": "2026-y-siguientes"
  },
  "schema_version": "2",
  "status": "warning"
}

Confirm the readiness check runs for the target modelo and period.

Keep the facts current

Your AEAT census can change - a new activity, a regime change, a baja.

Pull again to catch drift in your identity and address. The pull reports anything AEAT now holds that your profile does not.

The pull cannot see a regime change, so re-check those fields against your latest Modelo 036 copy whenever you file a censo change, and before you plan a new filing year.

Next steps