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

# Forms

> One API for the government forms Nmbr produces, from ROEs to T4s to TD1s

Forms are the government documents you produce for payroll, like ROEs and T4s. They share one set of endpoints and one shape. Learn the shape once and it carries across every form.

There are two things to keep straight:

* A **form type** is the definition. It describes which fields exist, what they mean, and how to fill them in. `roe`, `t4`, and `td1on` are form types.
* A **form** is one filled-in instance of a type, tied to an owner. A T4 for one employee is a form.

## Forms are self-describing

The fields on a form are not a fixed schema you hard-code. They depend on the form type and its version, and they change over time as the government revises each form. So you don't build a T4 by memorizing its boxes. You ask the API what the current T4 looks like, then render and fill what it returns.

This is the core idea: **the API hands you the field definitions at runtime, and you build against them.** A form editor built this way keeps working when a form gains a box or a new version ships.

## Listing form types

Retrieve the available form types with the [List form types](/api-reference/form-types/list-form-types) endpoint.

**Request**

```json theme={null}
# GET /services/payroll/form_types
```

**Response**

```json theme={null}
{
  "object": "list",
  "data": [
    {
      "id": "roe",
      "object": "form_type",
      "data": {
        "type": "roe",
        "label": "Record of Employment",
        "owner_types": ["employee"]
      }
    },
    {
      "id": "t4",
      "object": "form_type",
      "data": {
        "type": "t4",
        "label": "T4 Statement of Remuneration Paid",
        "owner_types": ["employee"]
      }
    }
  ]
}
```

## Retrieving a form type

Retrieve one form type with the [Retrieve a form type](/api-reference/form-types/retrieve-a-form-type) endpoint to get its full definition: its version, its capabilities, and every field.

**Request**

```json theme={null}
# GET /services/payroll/form_types/roe?effective_date=2026-08-01
```

**Response**

```json theme={null}
{
  "id": "roe",
  "object": "form_type",
  "data": {
    "type": "roe",
    "label": "Record of Employment",
    "version_year": 2026,
    "version_month": "august",
    "owner_types": ["employee"],
    "supports_population": true,
    "supports_generation": true,
    "exportable_as": ["xml", "pdf"],
    "groups": {
      "employment_details": "Employment Details",
      "separation_information": "Separation Information"
    },
    "fields": [
      {
        "key": "block_10_first_day_worked",
        "label": "First Day Worked (Block 10)",
        "type": "date",
        "required": true,
        "readonly": false,
        "group": "employment_details"
      }
    ]
  }
}
```

### Field definitions

Each entry in `fields` tells you how to render and handle one input:

* `key`: the field to read and write, for example `block_10_first_day_worked`. This is the name you send back when you fill the form.
* `label`: the display name.
* `type`: which control to render. One of `text`, `numeric`, `currency`, `date`, `boolean`, or `select`.
* `required`: whether to mark the input as required.
* `readonly`: whether to disable the input.
* `options`: for `select` fields, the allowed values as a map of value to label. Render these as the choices.
* `group`: which section the field belongs to. The top-level `groups` map gives each group its heading. The grouping is a suggestion for laying out your form, and it may change.
* `help`: guidance to show alongside the field, when the form provides it.

A `select` field carries its own options:

```json theme={null}
{
  "key": "block_6_pay_period_type",
  "label": "Pay Period Type (Block 6)",
  "type": "select",
  "required": true,
  "readonly": false,
  "options": {
    "W": "(W) Weekly",
    "B": "(B) Biweekly",
    "S": "(S) Semi-Monthly",
    "M": "(M) Monthly"
  },
  "group": "employment_details"
}
```

### Versions and `effective_date`

`effective_date` picks the version of the form. Governments revise their forms over time: new fields appear, a select gains options, claim amounts and validation rules change. Each revision is a new version, and the API resolves your `effective_date` to the version in effect on that date. Pass the date the form applies to and you always build against the right version.

If you omit `effective_date`, it defaults to today.

### Owners

`owner_types` tells you what a form attaches to. It's one or more of `employee`, `contractor`, or `work_assignment`. A T4 belongs to an employee; a TD1 belongs to a work assignment; a T4A can belong to either an employee or a contractor. You set the owner when you create the form, and the owner's type is inferred from its ID prefix (`emp_`, `ctr_`, `wrkas_`).

### Capabilities vary by form type

Not every form supports every operation. Three fields on the definition tell you what a given form type can do:

* `supports_population`: you can fetch suggested field values from the employee's payroll data.
* `supports_generation`: the API can build completed forms for you in the background.
* `exportable_as`: which file formats you can export, such as `xml` or `pdf`. An empty list means the form is not exportable.

The range is wide. Here's how a few form types compare:

| Form type                                | Owner                | Populate | Generate | Export   | Fields |
| ---------------------------------------- | -------------------- | -------- | -------- | -------- | ------ |
| Record of Employment (`roe`)             | Employee             | Yes      | Yes      | XML, PDF | 246    |
| T4 (`t4`)                                | Employee             | No       | Yes      | PDF      | 85     |
| T4A (`t4a`)                              | Employee, Contractor | No       | Yes      | PDF      | 80     |
| RL-1 (`rl1`)                             | Employee             | No       | Yes      | PDF      | 45     |
| Québec Source Deductions (`tp_1015_3_v`) | Work Assignment      | No       | No       | None     | 13     |
| TD1 Ontario (`td1on`)                    | Work Assignment      | No       | No       | None     | 12     |

## Creating a form

Create a form with the [Create a form](/api-reference/forms/create-a-form) endpoint. Send the `type` and the `owner_id`. You can set field values in the same request, or leave them empty and fill them later.

**Request**

```json theme={null}
# POST /services/payroll/forms
{
  "type": "td1on",
  "owner_id": "wrkas_01HX3F7T8B2D",
  "line_1_basic_personal_amount": 12747.0
}
```

The response is the created form. Even if you set only one field, it returns every field for the form, unset ones as `null`.

**Response**

```json theme={null}
{
  "id": "form_01JSCE1S1CF5C0VFPZZVBS6X5R",
  "object": "form",
  "data": {
    "type": "td1on",
    "owner": { "id": "wrkas_01HX3F7T8B2D", "object": "work_assignment" },
    "effective_date": "2026-01-01",
    "version_year": 2026,
    "version_month": "january",
    "is_editable": true,
    "validation_error_count": 0,
    "line_1_basic_personal_amount": 12747.0,
    "line_2_age_amount": null
  }
}
```

A form's field values sit alongside its metadata in `data`. Read them by the same `key` the definition uses.

## Populating a form

For form types where `supports_population` is `true`, the API can suggest field values from the employee's payroll data instead of you calculating them. Fetch the suggestions with the [Populate a form](/api-reference/form-types/populate-a-form) endpoint.

**Request**

```json theme={null}
# POST /services/payroll/form_types/roe/populate
{
  "employee_id": "emp_01H7M9X2QV4N",
  "work_assignment_ids": ["wrkas_01HX3F7T8B2D"],
  "first_day_worked": "2026-01-06",
  "last_day_for_which_paid": "2026-07-31"
}
```

**Response**

```json theme={null}
{
  "object": "form_population_result",
  "data": {
    "fields": {
      "block_10_first_day_worked": "2026-01-06",
      "block_11_last_day_for_which_paid": "2026-07-31",
      "pp1_insurable_earnings": 1840.0
    }
  }
}
```

Population data is not saved on its own. Send the values you want to keep to the [Update a form](/api-reference/forms/update-a-form) endpoint to persist them.

## Generating forms

For form types where `supports_generation` is `true`, the API can build completed forms for you: it creates each form and fills its fields from the owner's payroll data in one step. Start a run with the [Generate forms](/api-reference/form-types/generate-forms) endpoint.

Generation runs in the background, so the endpoint returns an [async task](/api-reference/async-tasks/retrieve-an-async-task) rather than the forms. Poll the task or listen for the `async_task_completed` [webhook](/api/overview/webhook-structure) to know when it finishes. Each form type shapes its own request, and one request can create many forms.

## Reading and editing a form

Retrieve a form with the [Retrieve a form](/api-reference/forms/retrieve-a-form) endpoint, and list a company's forms with [List forms](/api-reference/forms/list-forms).

Two fields on a form tell you its editing state:

* `is_editable`: whether the form can still be changed. A submitted form is not editable.
* `validation_error_count`: how many fields currently fail validation.

Change a form's fields with the [Update a form](/api-reference/forms/update-a-form) endpoint. Send only the fields you want to change.

**Request**

```json theme={null}
# PUT /services/payroll/forms/form_01JSCE1S1CF5C0VFPZZVBS6X5R
{
  "line_1_basic_personal_amount": 13000.0
}
```

## Validating a form

Check a form's fields before submission with the [Validate a form](/api-reference/form-types/validate-a-form) endpoint. Send the form's `effective_date` and the fields you want to check. The `effective_date` picks the version to validate against, so use the form's own date. The response lists any errors, keyed by field.

**Request**

```json theme={null}
# POST /services/payroll/form_types/roe/validate
{
  "effective_date": "2026-08-07",
  "block_10_first_day_worked": "2026-01-06",
  "pp1_insurable_earnings": 0.0
}
```

**Response**

```json theme={null}
{
  "data": {
    "errors": {
      "pp1_insurable_earnings": ["pp1_insurable_earnings cannot be 0"]
    }
  }
}
```

## Submitting a form

Submit a form with the [Submit a form](/api-reference/forms/submit-a-form) endpoint. What submission means depends on the form type. Some forms, like the ROE, are filed with a government agency and move through a status lifecycle (`draft`, `processing`, `submitted`, `done`, `rejected`). Others are records you complete and export yourself. See the form-specific guide for what a given form does on submission.

## Exporting a form

For form types with a non-empty `exportable_as`, retrieve the file from the [Retrieve a form](/api-reference/forms/retrieve-a-form) endpoint by setting the `Accept` header to the format you want:

* `Accept: application/pdf` for a PDF.
* `Accept: application/xml` for XML.

Without one of these headers, the endpoint returns the form as JSON.

A format listed in `exportable_as` is not always available for every form. The ROE is the clearest example: a managed ROE exports as a PDF only once Service Canada has accepted it, and never as XML, because Nmbr files it for you. When a format is not available for a given form, the endpoint returns `406 Not Acceptable`. The form-specific guides spell out the conditions.

## Form-specific guides

Each form type builds on everything above and adds its own rules, request shapes, and submission behaviour:

* [Record of Employment (ROE)](/guides/canada/record-of-employment)
* [Year-end tax forms (T4, T4A, RL-1)](/guides/canada/year-end-tax-forms)
* [TD1 tax credit forms](/guides/payroll-fundamentals/td1-forms)
