Registry entry

Finland Residence Permit Application for an Employed Person (Työntekijän oleskelulupahakemus, OLE_TY1 / 'TTOL')

Maahanmuuttovirasto's (the Finnish Immigration Service, Migri) form OLE_TY1, the residence permit application for an employed person ('TTOL'), used by a non-EU/EEA national coming to Finland to work for a Finnish (or Finland-operating) employer under a signed employment contract or accepted binding job offer, subject to labour market testing (the employer must first check whether suitable labour is available within the EU/EEA). A single bounded 10-page English-language fillable AcroForm PDF covering: the applicant's own personal details, passport, and digital-passport-photo details (sections 1-3); home-country and Finland contact information (section 4); intended residence in Finland, applicable only to first-time applicants (section 5); the applicant's spouse and up to 3 children under 18 (section 6); the sponsoring employer's own details (section 7); the terms of employment — occupation, working time, grounds for pay, and up to 3 taxable fringe-benefit rows — required only when the employer lacks Migri's own employer certification (section 8); criminal history and entry-ban questions covering conduct outside Finland only, since Migri obtains Finland-internal records itself (section 9); free-text additional information (section 10); a supporting-attachments checklist with up to 4 free-form 'other attachment' rows (section 11); informational text on personal-data processing with no fillable fields (section 12); and the final date/place/signature/declaration block (section 13). Opens Finland as GovSchema's 34th jurisdiction, via one of GovSchema's weakest-covered verticals (Visa). This document describes the form only; it does not submit anything, and does not imply Finnish government endorsement.

Registry entry

fi/migri/residence-permit-employed-person

Jurisdiction
Finland · national
Version
1.0.0
Verification
draft

Authoritative source OLE_TY1, 'Residence permit application for an employed person (\'TTOL\')', Migri's own English-language fillable AcroForm PDF

Machine access

Registry catalog
registry/index.jsonone record per schema id

Field reference

134 fields, read from the published schema.json, with names, types, requiredness, and validation as the document states them. The live government form remains the authoritative source.

Fields

  • applicationType enum required

    The form's own two mutually-exclusive cover-page checkboxes ('a first residence permit' / 'an extended permit'), implemented on the source PDF as two independent checkbox widgets (Haen_ensimmaista_oleskelulupaa / Haen_jatkolupaa), not a shared radio group.

    enum: first_permit | extended_permit
  • lastName string required

    Last name

    length: 1–200classification: pii
  • firstNames string required

    First names

    length: 1–200classification: pii
  • formerLastNames string optional

    Former last names (if any)

    length: 0–300classification: pii
  • formerFirstNames string optional

    Former first names (if any)

    length: 0–300classification: pii
  • gender enum required

    The form's own two-option 'Gender' checkbox pair (no third option is printed on this form).

    enum: female | maleclassification: sensitive-pii
  • dateOfBirth date required

    The source PDF splits this date across three separate day/month/year text-field widgets (dd.mm.yyyy); combined here into a single ISO date field, per this registry's established convention for split date widgets.

    classification: sensitive-pii
  • finnishPersonalIdentityCode string optional

    Finnish personal identity code (if applicable)

    length: 0–20classification: sensitive-pii
  • countryOfBirth string required

    Country of birth

    length: 1–100classification: pii
  • placeOfBirth string required

    Place of birth

    length: 1–200classification: pii
  • currentCitizenship string required

    Current citizenship(s)

    length: 1–200classification: pii
  • formerCitizenship string optional

    Former citizenship(s) (if any)

    length: 0–200classification: pii
  • maritalStatus enum required

    Marital status

    enum: unmarried | married | cohabiting | divorced | widowed | registered_partnership
  • currentOccupation string optional

    Current occupation

    length: 0–200
  • educationLevel string optional

    Education

    length: 0–200
  • nativeLanguage string required

    Native language

    length: 1–100
  • preferredContactLanguage enum required

    Language you wish to use

    enum: finnish | swedish | english
  • passportNumber string required

    Passport number

    length: 1–50classification: sensitive-pii
  • passportType enum required

    The form's own 6 mutually-exclusive passport-type checkboxes, including 'I do not have a passport' as one of the options.

    enum: ordinary | official_diplomatic | refugee_travel_document | aliens_passport | other | no_passport
  • passportTypeOtherDescription string optional

    Passport type — other, please specify

    length: 0–200
  • noPassportExplanation string optional

    I do not have a passport. Explain why not

    length: 0–500
  • passportCountryOfIssue string optional

    Country of issue

    length: 0–100classification: pii
  • passportIssuingAuthority string optional

    Issuing authority

    length: 0–200
  • passportDateOfIssue date optional

    The source PDF splits this date across three separate day/month/year text-field widgets (dd.mm.yyyy); combined here into a single ISO date field.

  • passportDateOfExpiry date optional

    The source PDF splits this date across three separate day/month/year text-field widgets (dd.mm.yyyy); combined here into a single ISO date field.

  • hasDigitalPassportPhoto boolean required

    Do you have a digital passport photo?

  • digitalPassportPhotoRetrievalCode string optional

    Retrieval code for your digital passport photo

    length: 0–50
  • homeStreetAddress string required

    Street address (in place of residence)

    length: 1–300classification: pii
  • homePostalCode string required

    Postal code (in place of residence)

    length: 1–50classification: pii
  • homeCity string required

    City/town (in place of residence)

    length: 1–150classification: pii
  • homeCountry string required

    Country (in place of residence)

    length: 1–100classification: pii
  • homeTelephone string required

    Telephone number (in place of residence)

    length: 1–50classification: pii
  • homeEmail string required

    Email address (in place of residence)

    length: 1–200classification: pii
  • finlandStreetAddress string optional

    Street address in Finland (if different from above)

    length: 0–300classification: pii
  • finlandPostalCode string optional

    Postal code in Finland (if different from above)

    length: 0–50classification: pii
  • finlandCity string optional

    City/town in Finland (if different from above)

    length: 0–150classification: pii
  • finlandTelephone string optional

    Telephone number in Finland (if different from above)

    length: 0–50classification: pii
  • finlandEmail string optional

    Email address in Finland (if different from above)

    length: 0–200classification: pii
  • intendedMoveToFinlandDate date optional

    The source form instructs: 'Fill in this section only if you are applying for a first residence permit.' The source PDF splits this date across three separate day/month/year widgets; combined here into a single ISO date field.

  • arrivalInFinlandDate date optional

    Only applicable if the applicant is already physically in Finland while applying for a first residence permit. The source PDF splits this date across three separate day/month/year widgets; combined here into a single ISO date field.

  • intendedLengthOfStay string optional

    The source form instructs: 'Fill in this section only if you are applying for a first residence permit.'

    length: 0–300
  • noSpouse boolean optional

    No spouse

  • spouseLastName string optional

    Spouse: last name

    length: 0–200classification: pii
  • spouseFirstNames string optional

    Spouse: first names

    length: 0–200classification: pii
  • spouseFormerLastNames string optional

    Spouse: former last names (if any)

    length: 0–300classification: pii
  • spouseFormerFirstNames string optional

    Spouse: former first names (if any)

    length: 0–300classification: pii
  • spouseGender enum optional

    Spouse: gender

    enum: female | maleclassification: sensitive-pii
  • spouseDateOfBirth date optional

    The source PDF splits this date across three separate day/month/year widgets; combined here into a single ISO date field.

    classification: sensitive-pii
  • spouseFinnishPersonalIdentityCode string optional

    Spouse: Finnish personal identity code (if applicable)

    length: 0–20classification: sensitive-pii
  • spouseCountryOfBirth string optional

    Spouse: country of birth

    length: 0–100classification: pii
  • spousePlaceOfBirth string optional

    Spouse: place of birth

    length: 0–200classification: pii
  • spouseCurrentCitizenship string optional

    Spouse: current citizenship(s)

    length: 0–200classification: pii
  • spouseApplyingSimultaneously boolean optional

    The spouse must fill in a separate application form, per the source form's own note.

  • noChildrenUnder18 boolean optional

    No children

  • child1LastName string optional

    The form provides 3 rows for children under 18 ('If you have more than three children, give the same details of your other children as a separate attachment.'); bounded to 3 rows here, matching the source's own printed row count.

    length: 0–200classification: pii
  • child1FirstNames string optional

    Child 1: first names

    length: 0–200classification: pii
  • child1Gender enum optional

    Child 1: gender

    enum: female | male
  • child1DateOfBirth date optional

    The source PDF splits this date across three separate day/month/year widgets; combined here into a single ISO date field.

    classification: sensitive-pii
  • child1ApplyingSimultaneously boolean optional

    A separate application form must be filled in for the child, per the source form's own note.

  • child2LastName string optional

    Child 2: last name

    length: 0–200classification: pii
  • child2FirstNames string optional

    Child 2: first names

    length: 0–200classification: pii
  • child2Gender enum optional

    Child 2: gender

    enum: female | male
  • child2DateOfBirth date optional

    The source PDF splits this date across three separate day/month/year widgets; combined here into a single ISO date field.

    classification: sensitive-pii
  • child2ApplyingSimultaneously boolean optional

    A separate application form must be filled in for the child, per the source form's own note.

  • child3LastName string optional

    Child 3: last name

    length: 0–200classification: pii
  • child3FirstNames string optional

    Child 3: first names

    length: 0–200classification: pii
  • child3Gender enum optional

    Child 3: gender

    enum: female | male
  • child3DateOfBirth date optional

    The source PDF splits this date across three separate day/month/year widgets; combined here into a single ISO date field.

    classification: sensitive-pii
  • child3ApplyingSimultaneously boolean optional

    A separate application form must be filled in for the child, per the source form's own note.

  • employerName string required

    Name of company

    length: 1–300
  • employerBusinessId string required

    Instead of a Business ID, the form permits stating the personal identity code of a private individual who is the applicant's employer.

    length: 1–50
  • employerStreetAddress string required

    Employer: street address

    length: 1–300
  • employerPostalCode string required

    Employer: postal code

    length: 1–50
  • employerCity string required

    Employer: city/town

    length: 1–150
  • employerCountry string required

    Employer: country

    length: 1–100
  • employerContactName string optional

    The person who will give additional information on behalf of the employer if needed.

    length: 0–200classification: pii
  • employerContactTelephone string optional

    Telephone number of contact person

    length: 0–50
  • employerContactEmail string optional

    Email address of contact person

    length: 0–200
  • jobOccupation string required

    The source form instructs: 'Fill in section 8 only if your employer has no employer certification.' A certified employer instead attaches its own certification in lieu of section 8; this schema still models every section-8 field for the (more common, for a first-time applicant's employer) uncertified case.

    length: 1–200
  • mainDuties string required

    Main duties

    length: 1–1000
  • workingTimeBasis enum required

    The form's own 'Choose one' instruction over 4 mutually-exclusive working-time bases.

    enum: per_week | over_three_weeks | per_month | other
  • workingTimeHoursPerWeek number optional

    Working time: hours per week

    range: 0–∞
  • workingTimeHoursPerThreeWeeks number optional

    Working time: hours over three weeks

    range: 0–∞
  • workingTimeHoursPerMonth number optional

    Working time: hours per month

    range: 0–∞
  • workingTimeOtherDescription string optional

    Working time: other, please specify

    length: 0–300
  • workingTimeOtherHours number optional

    Working time: other — hours

    range: 0–∞
  • paymentBasis enum required

    The form's own 'Choose one' instruction over 3 mutually-exclusive grounds for pay.

    enum: hourly | monthly | seasonal_piece_project
  • hourlyPayRate number optional

    Hourly pay (EUR per hour)

    range: 0–∞classification: financial
  • monthlyPayRate number optional

    Monthly pay (EUR per month)

    range: 0–∞classification: financial
  • seasonalPieceProjectPayRate number optional

    Choose this option if paid a lump sum for work done during a certain period (e.g. the entire employment relationship), or per task, piece, season, or project.

    range: 0–∞classification: financial
  • payPeriodFrom date optional

    The time period for which wages will be paid, when paid a lump sum by season/task/piece/project. The source PDF splits each of the two dates across three separate day/month/year widgets; combined here into single ISO date fields.

  • payPeriodTo date optional

    Pay period: to

  • benefit1Name string optional

    The form provides 3 rows to list taxable fringe benefits provided by the employer (such as accommodation benefit, meal allowance, full room and board, commuter tickets, company car, or telephone benefit); bounded to 3 rows here, matching the source's own printed row count.

    length: 0–300
  • benefit1PartOfSalary boolean optional

    Taxable fringe benefit 1: as part of the salary

  • benefit1PartOfSalaryValue number optional

    Taxable fringe benefit 1: taxable value as part of salary (EUR per month)

    range: 0–∞classification: financial
  • benefit1InAdditionToSalary boolean optional

    Taxable fringe benefit 1: in addition to the salary

  • benefit1InAdditionToSalaryValue number optional

    Taxable fringe benefit 1: taxable value in addition to salary (EUR per month)

    range: 0–∞classification: financial
  • benefit1Description string optional

    Taxable fringe benefit 1: description

    length: 0–300
  • benefit2Name string optional

    Taxable fringe benefit 2

    length: 0–300
  • benefit2PartOfSalary boolean optional

    Taxable fringe benefit 2: as part of the salary

  • benefit2PartOfSalaryValue number optional

    Taxable fringe benefit 2: taxable value as part of salary (EUR per month)

    range: 0–∞classification: financial
  • benefit2InAdditionToSalary boolean optional

    Taxable fringe benefit 2: in addition to the salary

  • benefit2InAdditionToSalaryValue number optional

    Taxable fringe benefit 2: taxable value in addition to salary (EUR per month)

    range: 0–∞classification: financial
  • benefit2Description string optional

    Taxable fringe benefit 2: description

    length: 0–300
  • benefit3Name string optional

    Taxable fringe benefit 3

    length: 0–300
  • benefit3PartOfSalary boolean optional

    Taxable fringe benefit 3: as part of the salary

  • benefit3PartOfSalaryValue number optional

    Taxable fringe benefit 3: taxable value as part of salary (EUR per month)

    range: 0–∞classification: financial
  • benefit3InAdditionToSalary boolean optional

    Taxable fringe benefit 3: in addition to the salary

  • benefit3InAdditionToSalaryValue number optional

    Taxable fringe benefit 3: taxable value in addition to salary (EUR per month)

    range: 0–∞classification: financial
  • benefit3Description string optional

    Taxable fringe benefit 3: description

    length: 0–300
  • convictedOfCrimeAbroad boolean required

    The Finnish Immigration Service obtains information on crimes and suspected crimes committed in Finland itself from official registers; this question and section 9.2 concern only crimes/suspected crimes in other countries.

  • crimeDescription string optional

    Crime

    length: 0–500classification: sensitive-pii
  • crimeCountry string optional

    Country where the crime took place

    length: 0–100classification: sensitive-pii
  • crimeDate date optional

    The source PDF splits this date across three separate day/month/year widgets; combined here into a single ISO date field.

    classification: sensitive-pii
  • crimePunishment string optional

    Punishment sentenced for the crime

    length: 0–500classification: sensitive-pii
  • suspectedOfCrimeAbroad boolean required

    Are you suspected of committing a crime in countries other than Finland?

  • suspectedCrimeDescription string optional

    Crime that you are suspected of

    length: 0–500classification: sensitive-pii
  • suspectedCrimeCountry string optional

    Country where the suspected crime took place

    length: 0–100classification: sensitive-pii
  • suspectedCrimeDate date optional

    The source PDF splits this date across three separate day/month/year widgets; combined here into a single ISO date field.

    classification: sensitive-pii
  • hasOrHadEntryBan boolean required

    I have or have had an entry ban

  • entryBanCountry string optional

    Country imposing the entry ban

    length: 0–100classification: sensitive-pii
  • entryBanValidPeriod string optional

    During which time was/is the entry ban valid?

    length: 0–300classification: sensitive-pii
  • additionalInformation string optional

    Additional information for the application

    length: 0–2000
  • otherAttachment1Included boolean optional

    The form provides 4 blank rows for any other attachments the applicant wants to name, each with its own checkbox and free-text name field; bounded to 4 rows here, matching the source's own printed row count.

  • otherAttachment1Description string optional

    Other attachment 1: name of document

    length: 0–200
  • otherAttachment2Included boolean optional

    Other attachment 2 included

  • otherAttachment2Description string optional

    Other attachment 2: name of document

    length: 0–200
  • otherAttachment3Included boolean optional

    Other attachment 3 included

  • otherAttachment3Description string optional

    Other attachment 3: name of document

    length: 0–200
  • otherAttachment4Included boolean optional

    Other attachment 4 included

  • otherAttachment4Description string optional

    Other attachment 4: name of document

    length: 0–200
  • signatureDate date required

    The source PDF splits this date across three separate day/month/year widgets; combined here into a single ISO date field.

  • signaturePlace string required

    Place

    length: 1–150
  • signatureNameInBlockLetters string required

    Name in block letters

    length: 1–200classification: pii

Verification record

Candidate selection

This session's brief (GOV-2276, "GovSchema Standard Research") targeted opening Finland as GovSchema's 34th jurisdiction, via Finland's Visa vertical — one of GovSchema's weakest-covered verticals globally. The target form, Migri's OLE_TY1 ("Residence permit application for an employed person", Finnish short name "TTOL"), had already been scouted in a prior pass as a genuine, unauthenticated, English-language fillable AcroForm PDF, with a rough estimate of ~205 fields across 14 pages. This session re-derived the form's structure entirely from scratch rather than trusting that estimate.

Source

  • Scouted URL (from the prior pass): a shorter, un-suffixed migri.fi/documents/5202425/5790178/... path. Fetched fresh this session with a plain HTTP GET: HTTP 404. The URL as scouted no longer resolves.
  • Corrected, currently-live URL (found via web search against migri.fi's own site, which surfaced the form's full CDN path including its UUID suffix): https://migri.fi/documents/5202425/5790178/Ty%C3%B6ntekij%C3%A4n+oleskelulupahakemus+(TTOL),+OLE_TY1+(en)/24dfac76-fe3e-43ab-b61d-94be6f1c6f76/Ty%C3%B6ntekij%C3%A4n+oleskelulupahakemus+(TTOL),+OLE_TY1+(en).pdf. Fetched fresh with a plain HTTP GET: HTTP 200, content-type application/pdf, 477,135 bytes — matching the prior scouting pass's ~477 KB estimate exactly, independently reproduced rather than assumed. Confirmed a genuine PDF (%PDF-1.6 header) with an /AcroForm dictionary (a genuine, non-flattened fillable form).
  • Landing/guidance pages (read for context, not for field extraction — this form is entirely self-documenting via its own printed section numbering 1–13): migri.fi/en/residence-permit-for-an-employed-person and migri.fi/en/residence-permit-applications.

Extraction technique

pdfjs-dist v4 (legacy/build/pdf.mjs, installed fresh into a scratch directory) was used for a three-pass technique matching this registry's established is/utl / dk/skattestyrelsen / dk/erst precedent:

  1. page.getAnnotations({ intent: "display" }) per page — captured every /Widget annotation's fieldName, fieldType (Tx/Btn/Ch), rect, checkBox/radioButton flags, and export value. Result: exactly 10 pages (not the scouted 14) and exactly 194 distinct AcroForm widgets — 131 Tx text fields, 63 Btn checkboxes, 0 Ch choice fields. annotation.radioButton was false and annotation.checkBox was true for all 63 Btn widgets — confirming none of the checkbox groups on this form share a PDF radio-group parent; every checkbox is independently named and independently checkable, and mutual exclusivity (e.g. gender, marital status, passport type) is a form-design convention only, not a PDF-structural one. This is the same situation this registry's at/bmeia and se/migrationsverket schemas already document.
  2. page.getTextContent(), clustered into visual lines by y-coordinate (3pt tolerance) and read in page order — reconstructed the form's full printed English text for all 10 pages independent of any AcroForm metadata. This form's own visible text is entirely in English (Migri's English-language edition of OLE_TY1); the underlying AcroForm field keys are Finnish (e.g. Sukunimi_1_1, Etunimet_1_1) — a deliberate cross-check against relying on the field-name strings as if they were English labels.
  3. Cross-reference: every widget's rect x/y range matched against the clustered text lines by proximity (same line for left/right-column siblings; nearest line above for label-above-blank-field layouts), confirming each field's real label and column order (e.g. Nainen_1_1 ["woman"] sits left of Mies_1_1 ["man"] at x=201 vs x=278, matching the printed "☐ Female ☐ Male" order — not assumed from the Finnish variable names alone).

The 194 widgets were consolidated into 134 fields[] entries plus 6 documents[] entries by exhaustive, script-checked reconciliation (see below) — not a hand count.

Widget → field consolidation

Two categories of widget were combined into single fields, both matching this registry's own established conventions:

  • 14 printed day/month/year date splits (dd.mm.yyyy across 3 separate text widgets each — 42 widgets total): dateOfBirth, passportDateOfIssue, passportDateOfExpiry, intendedMoveToFinlandDate, arrivalInFinlandDate, spouseDateOfBirth, child1DateOfBirth, child2DateOfBirth, child3DateOfBirth, payPeriodFrom, payPeriodTo, crimeDate, suspectedCrimeDate, signatureDate — each combined into a single type: "date" field, per dk/cpr/notification-of-entry's and is/utl/other-residence-permit-application's own precedent for split date widgets, with the split disclosed in each field's description.
  • 15 mutually-exclusive independent-checkbox groups (42 widgets total): applicationType (2), gender (2), maritalStatus (6), preferredContactLanguage (3), passportType (6), hasDigitalPassportPhoto (2), spouseGender/child1Gender/ child2Gender/child3Gender (2 each = 4 groups), workingTimeBasis (4), paymentBasis (3), convictedOfCrimeAbroad/ suspectedOfCrimeAbroad/hasOrHadEntryBan (2 each = 3 groups) — each combined into a single enum or boolean field, since no PDF radio-group parent exists to group them structurally.

A disposable reconciliation script (/tmp/fi-migri-extract/reconcile.mjs, not committed) mapped every one of the 194 extracted widget names to exactly one of: a grouped field, a 1:1 single field, or a documents[] checklist widget — with 0 leftover and 0 double-counted widget names, confirmed by set-difference against the full widget list extracted directly from the PDF.

Total: 134 fields[] + 6 documents[] entries. Arithmetic: 14 date groups (42 widgets) + 15 checkbox groups (42 widgets) = 29 grouped fields, consuming 84 widgets; the remaining 110 widgets split into 105 singleton fields[] (1 widget = 1 field each) and 5 documents[] checklist widgets (section 11.1's fixed attachment list, see below). 29 + 105 = 134 fields[]; 5 + 1 (the attestation entry with no widget of its own, also below) = 6 documents[]. The script's own printed output — field count (groups + singles): 134, document checklist widgets: 5, leftover widgets (0), names referenced but not found in PDF (0) — is the authoritative source for these counts; schema.json was generated directly from this mapping, not hand-transcribed from it.

documents[]

5 of section 11.1's fixed attachment-checklist checkboxes were modelled as documents[] entries (matching is/utl/other-residence-permit-application's established convention for checklist blocks) rather than invented per-item boolean fields: colorCopyOfPassportPages, passportPhotoOrRetrievalCode, proofOfLegalStayInCountryOfApplication, formMP1 (conditionally needed only for a first-permit applicant already in Finland, per the form's own note), and termsOfEmploymentForm (required unless the employer holds Migri's own employer certification, per section 8's own note). A 6th documents[] entry, applicantSignatureDeclaration (category attestation), quotes the section 13 declaration paragraph verbatim; it has no corresponding AcroForm widget of its own — the physical signature line is not a fillable text field on this specimen, only the date/place/name-in-block-letters fields are.

Section 11.1's 4 free-form "other attachment" rows (a checkbox + a free-text name field per row) are, by contrast, modelled as ordinary bounded-repeating-group fields[] (otherAttachment1Included/ otherAttachment1DescriptionotherAttachment4...), since they are applicant-named, not fixed document types.

Disclosed scope decisions

  • Section 5 ("Residence in Finland") carries the form's own printed instruction "Fill in this section only if you are applying for a first residence permit." Since applicationType (first_permit / extended_permit) already exists as a field on this form, this gating is expressed structurally via visibleWhen/requiredWhen against applicationType, not left as prose alone.
  • Section 8 ("Terms of employment") carries the form's own printed instruction "Fill in section 8 only if your employer has no employer certification." Unlike section 5, there is no corresponding "is my employer certified?" field anywhere on the form to gate against structurally, so this remains disclosed in the field description/sourceRef only; all section 8 fields are modelled as required: true, matching the more common case (a first-time applicant's employer, not yet Migri-certified).
  • Gender is modelled as a 2-value enum (female/male) — this form prints no third option, unlike is/utl/other-residence-permit-application's 3-option ("Female"/"Male"/"Non binary/Other") D-110 form. Confirmed by reading the raw text stream at every gender checkbox row on this specimen (applicant, spouse, and all 3 child rows): none print a third option.
  • Children (section 6.2) and "other attachments" (section 11.1) are each disclosed, bounded repeating groups — 3 rows and 4 rows respectively, matching the source's own printed row counts exactly — flattened to numbered slots (child1child3, otherAttachment1otherAttachment4) per this registry's established repeating-group convention, since GovSchema's flat field model (SPEC.md §6.1) has no array/nested-object field type.

Mock conformance test run

Two scenarios and eight mutation/negative controls were built and checked against this schema's own required/requiredWhen/visibleWhen/ validation/crossFieldValidation grammar with a disposable checker script (/tmp/fi-migri-extract/check_conformance.mjs, not committed — same technique as this registry's other recent cycles):

  • application-minimal-extended-permit-no-dependents.json: a Finnish applicant renewing/extending their own permit (applicationType: extended_permit, so section 5 is not visible/required), with no spouse, no children, an ordinary passport with no digital photo, a monthly-paid software-developer role, and no criminal-history/entry-ban disclosures. 44 fields collected, 90 correctly not-applicable (spouse/children detail fields, section 5's first-permit-only fields, fringe-benefit rows, working-time/pay-basis alternatives not chosen, criminal/entry-ban detail fields, other-attachment rows), 0 errors.
  • application-full-coverage-first-permit-with-family.json: a maximal-coverage scenario — an Indian software engineer applying for a first residence permit (applicationType: first_permit, activating section 5) to work for a Finnish employer, with a spouse and 2 children applying simultaneously, a digital passport photo, 2 fringe-benefit rows, a disclosed minor foreign conviction (all 4 conditional crime-detail fields populated), and 2 "other attachment" rows. 96 fields collected, 38 correctly not-applicable (the 3rd child slot, the suspected-crime and entry-ban detail fields since those questions were answered "no", the 3rd fringe-benefit row, the 2 unused working-time/pay-basis alternatives and their conditional detail fields, otherAttachment rows 3–4), 0 errors.
  • Eight mutation/negative controls, each derived from the full-coverage scenario with exactly one defect introduced, each correctly raising exactly one error:
    1. Removing the required lastNamemissing-required.
    2. Setting gender to "unspecified" (not in its 2-option enum) → enum-violation.
    3. Setting monthlyPayRate to -500 (violates validation.minimum: 0) → minimum-violation.
    4. Setting noSpouse to false while removing spouseLastNamemissing-required (requiredWhen conditional-required violation).
    5. Setting paymentBasis to seasonal_piece_project with payPeriodFrom: "2026-06-01" and payPeriodTo: "2026-01-01" (return before departure) → cross-field-violation on payPeriodToNotBeforePayPeriodFrom — confirming crossFieldValidation actually fires.
    6. Removing the required signatureNameInBlockLettersmissing-required.
    7. Setting otherAttachment1Included to true while removing otherAttachment1Descriptionmissing-required (requiredWhen conditional-required violation).
    8. Setting lastName to a 300-character string (violates validation.maxLength: 200) → maxLength-violation.
    9. Removing termsOfEmploymentForm from documents (violates a documents[].required: true entry with no requiredWhen) → missing-required-document.

Correction (independent re-check, review gate): the disposable checker script above only checked fields[] against required/requiredWhen/visibleWhen/validation/crossFieldValidation — it never checked documents[] requiredness, and neither committed scenario originally carried a documents key at all. Both scenarios were therefore silently missing all 5 of this schema's unconditionally-required documents[] entries (colorCopyOfPassportPages, passportPhotoOrRetrievalCode, proofOfLegalStayInCountryOfApplication, termsOfEmploymentForm, applicantSignatureDeclaration), which a from-scratch re-check (extending the checker to also evaluate documents[].required/requiredWhen, matching this registry's own established documents-array convention — e.g. at/gewerbebehoerde, dk/um/application-for-danish-passport) confirmed by raising exactly 5 missing-required-document errors on each scenario as originally committed. Both scenario files were corrected to include a documents array marking these 5 entries provided: true (mutation control 9 above added to cover the gap going forward); the re-check now confirms 0 errors on both scenarios with the corrected fixtures, and field collection counts (44/90 and 96/38) are unchanged. formMP1, the schema's one optional documents[] entry, is intentionally omitted from both scenarios.

The schema was also validated against the GovSchema v0.3 meta-schema with node tools/validate.mjs and node tools/validate-ajv.mjs — both pass, individually and as part of the full 348-document registry run (347 pre-existing + this one; no other document affected).

Pre-PR re-verification

The corrected PDF URL was re-fetched a final time immediately before finalizing this record with curl -sSL -o /dev/null -w "%{http_code} %{size_download}", confirming HTTP 200 and 477,135 bytes remain stable and reproducible.

View the raw record (VERIFICATION.md)

Version history

  • 1.0.0 draft latest this page has verification record schema.json

Independent and non-affiliated

GovSchema is an independent, open-source project. This reference is not produced, reviewed, or endorsed by Maahanmuuttovirasto (Finnish Immigration Service) or any government. The authoritative source is always the live government form and its official instructions.