Generator · Maltese data

Maltese VAT number

Endpoint GET /v1/mt/vat

What it covers

Returns a valid Maltese VAT number (8 digits with a correct mod-37 check). Use `format=vat` for the `MT`-prefixed form. Set `invalid=true` for a number with a deliberately wrong check.

How it’s calculated

The Maltese VAT number's last two digits are a mod-37 check value: the weighted sum of the six payload digits (weights 3,4,6,7,8,9) is 37-complemented and written as two zero-padded decimal digits.

Algorithm

  1. Take the six payload digits d1..d6 (the number's first six digits; d1 is drawn 1-9, d2..d6 are 0-9).
  2. Compute the weighted sum using position weights [3, 4, 6, 7, 8, 9]: sum = 3*d1 + 4*d2 + 6*d3 + 7*d4 + 8*d5 + 9*d6 (plain sum, no reduction of individual products).
  3. Compute remainder r = sum mod 37 (a value 0..36).
  4. Compute the check value v = (37 - r) mod 37 (also 0..36; when r is 0 the mod brings v back to 0).
  5. Render v as a two-digit zero-padded decimal string (e.g. 3 -> "03", 34 -> "34"). Because v is always 0..36 it always fits in exactly two digits.
  6. Append those two digits to the six payload digits to form the 8-digit national number. For the 'vat' format prefix the literal string 'MT'.
  7. Consistency note: with the two check digits placed as the 7th and 8th positions, the full 8-digit rule weightedSum(all 8 digits, [3,4,6,7,8,9,10,1]) mod 37 == 0 holds, since 10*d7 + d8 == v.

Worked example

Maltese VAT payload 123456 -> 123456??

Payload digits: d1=1, d2=2, d3=3, d4=4, d5=5, d6=6; weights [3,4,6,7,8,9].
Weighted sum = 3*1 + 4*2 + 6*3 + 7*4 + 8*5 + 9*6 = 3 + 8 + 18 + 28 + 40 + 54 = 151.
r = 151 mod 37 = 151 - (37*4=148) = 3.
v = (37 - 3) mod 37 = 34.
Render 34 zero-padded to two digits -> "34".
Verify with full-8-digit rule: weights [3,4,6,7,8,9,10,1] over 1,2,3,4,5,6,3,4 = 151 + 10*3 + 1*4 = 151 + 30 + 4 = 185 = 37*5, and 185 mod 37 = 0. Correct.

The check digits are "34"; the full national number is 12345634 (MT12345634 in VAT format).

Edge cases

  • Zero check value: when the weighted sum is already a multiple of 37 (r = 0), v = 0 and the check digits render as "00" — a valid number the generator emits deliberately as an edge case.
  • First payload digit is drawn 1-9 (never 0), so the common shape has no leading zero; the generator also emits explicit first-digit-boundary edges with d1 = 1 or 9.

Gotchas

  • The check is a single mod-37 VALUE spanning both trailing digits, not two independent per-digit checks. The two digits encode one number 0..36 as 10*d7 + d8, which is why the equivalent full-length rule uses weights 10 and 1 for positions 7 and 8.
  • weightedSum sums weight*digit with NO per-product reduction (e.g. 9*6 = 54 stays 54); only the final total is reduced mod 37.
  • Because v is at most 36 it never reaches three digits, so the two-digit render never overflows — the code relies on this and never redraws.
  • The (37 - r) % 37 form matters only at r = 0: it maps 0 back to 0 rather than to 37, keeping the value in 0..36.

Parameters

ParameterTypeDescription
countinteger1–1000Number of records to return, 1–1000 (your plan may lower this). Omitted returns a single record; set it for a batch.
edgebooleanRestrict output to valid edge-case VAT numbers from the rare corners.
extremebooleanReturn a correct value wrapped in a hostile encoding (untrimmed whitespace, invisible/zero-width characters, BOM, or bidi/combining marks). Homoglyphs are excluded so the value stays machine-parseable; it still validates after normalisation.
format"national" | "vat"Rendering: bare 8-digit national number (default) or MT-prefixed VAT number.
invalidbooleanReturn a number with a deliberately wrong mod-37 check digit.
seedintegerInteger seed for reproducible output: the same seed always yields the same record.

Response fields

FieldTypeDescription
valuestringThe VAT number in the requested format (national or MT-prefixed).
digitsstringThe canonical, unprefixed 8-digit number.

Other generators for Malta

See all generators for Malta →

The same kind of identifier elsewhere

Try it

Generate a live example below — every response is valid by format and entirely synthetic.