Skip to content

Prepare a filing period's report

The filing_periods.prepare operation: POST /api/v1/filing_periods/{id}/prepare in the REST API and the filing_periods_prepare tool in the MCP server.

POST/api/v1/filing_periods/{id}/prepare

Generates the period's report (spec §21.2) from the entity's invoices and credit notes and its ledger, never from processor data, for every brand of the entity, and stores it on the period with its CSV and XLSX files. The period becomes prepared. The report follows the regime (reportKind):

  • eu_oss: taxable amount and VAT per member state of consumption and rate in EUR (ECB rate of the period's last day, or of the next publication day), corrections of earlier periods by original period, and the balance per member state;
  • eu_domestic: domestic supplies by rate, corrections, the return values by rate, and the EC Sales List (reverse-charged services to businesses in other member states, per customer VAT ID);
  • uk_vat: the nine boxes of the UK VAT return, with sales by rate;
  • ch_mwst: turnover and tax by rate in CHF;
  • us_state: gross, taxable and exempt sales and the tax by state;
  • generic: sales and tax by jurisdiction and rate in the regime's currency.

Except for eu_oss, other currencies are converted per the filing spec's exchange-rate rule: the ECB rate of the period's last day when it names it, else of each document's tax-point date. Credit notes for sales reported in an earlier period are corrections of that period. Sales made during a grace period are reported in the first return after the registration's effective date.

Every report includes a reconciliation: its tax per jurisdiction and currency must equal the movement of the regime's tax payable accounts in the ledger for the period. If they differ, nothing is stored and the call fails with filing_reconciliation_failed, listing the documents that differ.

Works on a locked period, and again on a prepared one until it is submitted. Write tier: tax managers, finance, owners and admins. Dry-run it to see the report without storing anything.

At a glance

  • REST: POST /api/v1/filing_periods/{id}/prepare
  • MCP tool: filing_periods_prepare
  • Operation ID: filing_periods.prepare
  • Scope: Legal entity
  • Permission: filings:write
  • Risk tier: write
  • Dry run: Supported (send Ownrecord-Dry-Run: true)
  • Idempotency: Idempotency-Key required
  • Modes: Test and live
  • Authentication: API key with the filings:write scope
  • Since: M8

Request

Path parameters

FieldTypeDescription
idfp_… IDThe filing period (fp_…).

Body

A JSON object (Content-Type: application/json):

FieldTypeRequiredDescription
notestringNoA note for the period's history, e.g. who checked the figures.

Response

200 OK with a JSON object:

FieldTypeDescription
idfp_… ID
object"filing_period"
entityIdent_… ID
livemodeboolean
regimeIdstring
registrationIdregn_… ID
reportKindone of eu_oss, eu_domestic, uk_vat, ch_mwst, generic, us_state
reportAvailableboolean
frequencyone of monthly, quarterly, annual
periodKeystringThe period: "2026-Q3", "2026-07" or "2026".
periodStartdate-time
periodEnddate-timeThe end (exclusive): the next period's first local midnight.
firstDaystring
lastDaystring
timeZonestring
currencystring
dueDatestring
dueAtdate-time23:59:59 local time on the due date.
lockableAtdate-time
statusone of open, locked, prepared, submitted, paid
statusChangedAtdate-time
lockedAtdate-time or null
preparedAtdate-time or null
submittedAtdate-time or null
referencestring or null
paidAtdate-time or null
paymentRefstring or null
totalsobject or null
createdAtdate-time
updatedAtdate-time
registrationobject or null
endsBeforeRegistrationboolean
reportobject or null
filesarray of object
files[].formatone of csv, xlsx, xml
files[].fileIdfile_… ID
files[].filenamestring
files[].contentTypestring
files[].sizeinteger
files[].sha256string
receiptsarray of object
receipts[].kindone of file, reference
receipts[].referencestring
receipts[].labelstring or null
receipts[].addedAtdate-time
receipts[].addedBystring
paymentLedgerTxnIdsarray of txn_… ID
remindersarray of object
reminders[].codestring
reminders[].atdate-time
reminders[].skippedboolean
historyarray of object
history[].fromone of open, locked, prepared, submitted, paid or null
history[].toone of open, locked, prepared, submitted, paid
history[].atdate-time
history[].bystring
history[].notestring or null
actionsobject
actions.lockobject
actions.lock.allowedboolean
actions.lock.codestring or null
actions.lock.messagestring or null
actions.prepareobject
actions.prepare.allowedboolean
actions.prepare.codestring or null
actions.prepare.messagestring or null
actions.submitobject
actions.submit.allowedboolean
actions.submit.codestring or null
actions.submit.messagestring or null
actions.markPaidobject
actions.markPaid.allowedboolean
actions.markPaid.codestring or null
actions.markPaid.messagestring or null

Examples

Generate the Q3 OSS return

HTTP
POST /api/v1/filing_periods/fp_01m4tx5nj8emwbyf7y9vcf47y0/prepare
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14

Response (200):

JSON
{
  "id": "fp_01m4tx5nj8emwbyf7y9vcf47y0",
  "object": "filing_period",
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
  "livemode": true,
  "regimeId": "EU_OSS_UNION",
  "registrationId": "regn_01m4tx5nj8emwbyf7y9vcf47xk",
  "reportKind": "eu_oss",
  "reportAvailable": true,
  "frequency": "quarterly",
  "periodKey": "2026-Q3",
  "periodStart": "2026-06-30T22:00:00.000Z",
  "periodEnd": "2026-09-30T22:00:00.000Z",
  "firstDay": "2026-07-01",
  "lastDay": "2026-09-30",
  "timeZone": "Europe/Zagreb",
  "currency": "EUR",
  "dueDate": "2026-10-31",
  "dueAt": "2026-10-31T22:59:59.000Z",
  "lockableAt": "2026-09-30T22:00:00.000Z",
  "status": "prepared",
  "statusChangedAt": "2026-10-02T08:05:00.000Z",
  "lockedAt": "2026-10-02T08:00:00.000Z",
  "preparedAt": "2026-10-02T08:05:00.000Z",
  "submittedAt": null,
  "reference": null,
  "paidAt": null,
  "paymentRef": null,
  "totals": {
    "currency": "EUR",
    "taxable": "1500000000",
    "tax": "290000000",
    "corrections": "-19000000",
    "due": "271000000",
    "refundable": "0"
  },
  "createdAt": "2026-07-01T03:00:00.000Z",
  "updatedAt": "2026-10-02T08:05:00.000Z",
  "registration": {
    "id": "regn_01m4tx5nj8emwbyf7y9vcf47xk",
    "state": "registered",
    "registrationNumber": "HR12345678901",
    "effectiveFrom": "2026-03-31T22:00:00.000Z"
  },
  "endsBeforeRegistration": false,
  "report": {
    "kind": "eu_oss",
    "currency": "EUR",
    "rounding": "half_up",
    "fxRule": null,
    "generatedAt": "2026-10-02T08:05:00.000Z",
    "fx": [],
    "sections": [
      {
        "id": "supplies",
        "title": "Supplies by member state of consumption and rate",
        "columns": [
          {
            "key": "memberState",
            "label": "Member state",
            "type": "text"
          },
          {
            "key": "rate",
            "label": "VAT rate",
            "type": "rate"
          },
          {
            "key": "rateKind",
            "label": "Rate type",
            "type": "text"
          },
          {
            "key": "taxable",
            "label": "Taxable amount",
            "type": "money"
          },
          {
            "key": "vat",
            "label": "VAT",
            "type": "money"
          },
          {
            "key": "lines",
            "label": "Lines",
            "type": "count"
          }
        ],
        "rows": [
          {
            "memberState": "DE",
            "rate": "190000",
            "rateKind": "standard",
            "taxable": "1000000000",
            "vat": "190000000",
            "lines": 8
          },
          {
            "memberState": "FR",
            "rate": "200000",
            "rateKind": "standard",
            "taxable": "500000000",
            "vat": "100000000",
            "lines": 3
          }
        ]
      },
      {
        "id": "corrections",
        "title": "Corrections of earlier periods",
        "columns": [
          {
            "key": "originalPeriod",
            "label": "Period corrected",
            "type": "text"
          },
          {
            "key": "memberState",
            "label": "Member state",
            "type": "text"
          },
          {
            "key": "taxable",
            "label": "Taxable amount",
            "type": "money"
          },
          {
            "key": "vat",
            "label": "VAT",
            "type": "money"
          },
          {
            "key": "lines",
            "label": "Lines",
            "type": "count"
          }
        ],
        "rows": [
          {
            "originalPeriod": "2026-Q2",
            "memberState": "DE",
            "taxable": "-100000000",
            "vat": "-19000000",
            "lines": 1
          }
        ]
      },
      {
        "id": "balances",
        "title": "VAT due per member state",
        "columns": [
          {
            "key": "memberState",
            "label": "Member state",
            "type": "text"
          },
          {
            "key": "supplies",
            "label": "VAT on supplies",
            "type": "money"
          },
          {
            "key": "corrections",
            "label": "Corrections",
            "type": "money"
          },
          {
            "key": "balance",
            "label": "Balance",
            "type": "money"
          }
        ],
        "rows": [
          {
            "memberState": "DE",
            "supplies": "190000000",
            "corrections": "-19000000",
            "balance": "171000000"
          },
          {
            "memberState": "FR",
            "supplies": "100000000",
            "corrections": "0",
            "balance": "100000000"
          }
        ]
      },
      {
        "id": "reconciliation",
        "title": "Reconciliation with the ledger",
        "columns": [
          {
            "key": "jurisdiction",
            "label": "Jurisdiction",
            "type": "text"
          },
          {
            "key": "currency",
            "label": "Currency",
            "type": "text"
          },
          {
            "key": "reportTax",
            "label": "Report tax",
            "type": "money"
          },
          {
            "key": "ledgerTax",
            "label": "Ledger tax payable",
            "type": "money"
          },
          {
            "key": "difference",
            "label": "Difference",
            "type": "money"
          }
        ],
        "rows": [
          {
            "jurisdiction": "DE",
            "currency": "EUR",
            "reportTax": "171000000",
            "ledgerTax": "171000000",
            "difference": "0"
          },
          {
            "jurisdiction": "FR",
            "currency": "EUR",
            "reportTax": "100000000",
            "ledgerTax": "100000000",
            "difference": "0"
          }
        ]
      }
    ],
    "reconciliation": {
      "matches": true,
      "rows": [
        {
          "jurisdictionId": "DE",
          "currency": "EUR",
          "reportTax": "171000000",
          "ledgerTax": "171000000",
          "difference": "0"
        },
        {
          "jurisdictionId": "FR",
          "currency": "EUR",
          "reportTax": "100000000",
          "ledgerTax": "100000000",
          "difference": "0"
        }
      ]
    },
    "counts": {
      "lines": 12,
      "corrections": 1,
      "notReported": 0,
      "documents": 12
    }
  },
  "files": [
    {
      "format": "csv",
      "fileId": "file_01m4tx5nj8emwbyf7y9vcf47y2",
      "filename": "EU_OSS_UNION-2026-Q3.csv",
      "contentType": "text/csv; charset=utf-8",
      "size": 2381,
      "sha256": "5d1c9d6b7f3e0a4c8b2f1e6d9a7c3b5e0f4d8a2c6b1e9f7d3a5c0b8e2f6d4a1c"
    },
    {
      "format": "xlsx",
      "fileId": "file_01m4tx5nj8emwbyf7y9vcf47y3",
      "filename": "EU_OSS_UNION-2026-Q3.xlsx",
      "contentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      "size": 9184,
      "sha256": "8a3f6c1e9d4b7a2f5c0e8d3b6a1f4c9e7d2b5a0f3c8e6d1b4a9f7c2e5d0b3a6f"
    }
  ],
  "receipts": [],
  "paymentLedgerTxnIds": [],
  "reminders": [],
  "history": [
    {
      "from": null,
      "to": "open",
      "at": "2026-07-01T03:00:00.000Z",
      "by": "system",
      "note": null
    },
    {
      "from": "open",
      "to": "locked",
      "at": "2026-10-02T08:00:00.000Z",
      "by": "usr_01m4tx5nj8emwbyf7y9vcf47xa",
      "note": null
    },
    {
      "from": "locked",
      "to": "prepared",
      "at": "2026-10-02T08:05:00.000Z",
      "by": "usr_01m4tx5nj8emwbyf7y9vcf47xa",
      "note": null
    }
  ],
  "actions": {
    "lock": {
      "allowed": false,
      "code": "filing_period_status_invalid",
      "message": "This period is prepared: \"lock\" needs open."
    },
    "prepare": {
      "allowed": true,
      "code": null,
      "message": null
    },
    "submit": {
      "allowed": true,
      "code": null,
      "message": null
    },
    "markPaid": {
      "allowed": false,
      "code": "filing_period_status_invalid",
      "message": "This period is prepared: \"mark_paid\" needs submitted."
    }
  }
}

Errors

CodeHTTP statusWhenWhat to do
validation_failed400A field is malformed (param names it).Fix the fields listed in details.issues and send the request again.
resource_not_found404No filing period with this ID exists for this legal entity and mode.Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.
scope_required400The request names no legal entity (an org key without Ownrecord-Entity).Call the operation with credentials or a target at its level: an organization, a legal entity, a brand or the platform (details.required_scope).
filing_period_status_invalid409The period isn't locked or prepared (details.status).Reload the period and check its status: details.allowed_from lists the statuses the action needs. Periods go open → locked → prepared → submitted → paid.
filing_report_kind_unsupported409Ownrecord can't generate this regime's report yet (details.report_kind).Prepare the return outside Ownrecord for now; the report for this kind of regime comes in a later release.
filing_registration_not_effective409The registration is still pending: grace sales have no return until it has an effective date.Mark the registration registered with its number and effective date first: sales made during the grace period are reported in the first return after it.
fx_rate_unavailable404The ECB rates the report converts with (of the period's last day or the next publication day, or of a document's tax-point date) aren't loaded yet. Retry after the next publication.Check the currency (the ECB publishes about 30) and the date. Rates are fetched every day after 16:00 CET; for a date with no rate yet, try again after the next publication.
filing_reconciliation_failed409The report's tax differs from the ledger's tax payable (details.rows, details.documents).Check the documents in details.documents: each shows the report's and the ledger's tax. Correct the ledger or the documents (for example with a manual ledger adjustment or a credit note), then prepare the period again.
upstream_timeout502The file store didn't answer in time; nothing was stored. Retry.Retry the request with the same Idempotency-Key after a short wait.
version_conflict409The period changed at the same moment. Reload it and try again.Fetch the object again and retry the change.
permission_denied403You can't work on this entity's filings (tax managers, finance, owners and admins can).Ask an organization owner or admin for a role or scope that allows this action.

It can also return these common errors: api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, idempotency_key_required, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.