Constaia
Use-case guides

Sport medical certificate

Check that a sport medical certificate declares the athlete fit, is signed and stamped, belongs to the athlete and is not older than your window.

Esta página ainda não está traduzida para o seu idioma. Mostramos a versão em inglês.

Many federations, clubs and organisers require a medical certificate stating that the person is fit for sport. Checking them by hand is slow: you have to look at the date, the signature, the stamp, the name and that it says "fit".

With the medical_certificate_sport type Constaia extracts that data and applies the rules you ask for.

Options

options.json
{
  "expect": "medical_certificate_sport",
  "checks": {
    "max_age_days": 365,
    "require_signature": true,
    "require_stamp": true,
    "holder": { "full_name": "María García López", "document_number": "12345678Z" }
  },
  "storage": "none",
  "metadata": { "athlete_id": "5521", "season": "2026-27" }
}
CheckWhat it checksIf it fails
max_age_daysThat the issue date is not older than N days.max_age_days with severity: "error". If the date can't be found, warning (→ review).
require_signatureThat a signature is visible (signature_present).require_signature with error.
require_stampThat a stamp is visible (stamp_present).require_stamp with error.
holderThat the patient is the athlete (name and ID).holder with error, or warning if the data can't be read.

Also, without asking for it, if the certificate does not declare the person fit (fit_for_sport: false) the verdict is invalid with the reason not_fit_for_sport: "The certificate does not declare the holder fit for sport.".

If you need a specific field to be present, such as the doctor's licence number, add "require_fields": ["doctor_license_number"]: if it's missing you get the required_field_missing reason with error.

Age of the certificate and the season

max_age_days counts the days between the issue date and the reference date, which is today by default. Your organisation decides the window: 365 days is common, but some regulations require a certificate from the current season.

If you want the certificate to still be within the window at the end of the season, pass the end date in reference_date:

{ "max_age_days": 365, "reference_date": "2027-08-31" }

A certificate issued more than one day after reference_date also fails the check, so don't use the season start date as the reference if you accept certificates issued during the season.

The code

check-medical.js
import { Constaia, ConstaiaError } from "@constaia/sdk";
import { fromPath } from "@constaia/sdk/node";

const constaia = new Constaia(); // reads CONSTAIA_API_KEY

export async function checkMedicalCertificate(path, athlete) {
  const analysis = await constaia.analyze(await fromPath(path), {
    expect: "medical_certificate_sport",
    checks: {
      maxAgeDays: 365,
      requireSignature: true,
      requireStamp: true,
      holder: { fullName: athlete.fullName, documentNumber: athlete.documentNumber },
    },
    storage: "none",
    language: "en",
    metadata: { athlete_id: String(athlete.id), season: "2026-27" },
  });

  const { fields, verdict } = analysis;
  return {
    analysisId: analysis.id,
    status: verdict?.status ?? "review",
    problems: (verdict?.reasons ?? []).filter((r) => r.severity !== "info").map((r) => r.message),
    issueDate: fields.issue_date?.value ?? null,
    restrictions: fields.restrictions?.value ?? null,
    doctorLicenseNumber: fields.doctor_license_number?.value ?? null,
  };
}

try {
  const result = await checkMedicalCertificate("./medical_certificate.pdf", {
    id: 5521,
    fullName: "María García López",
    documentNumber: "12345678Z",
  });
  console.log(result);
} catch (err) {
  if (err instanceof ConstaiaError) console.error(err.code, err.message, err.requestId);
  else throw err;
}

What it returns

With the test file medical_certificate.pdf and the options of the curl example, the verdict is (messages in Spanish, the default language):

verdict
{
  "expected": ["medical_certificate_sport"],
  "match": true,
  "status": "valid",
  "reasons": [
    { "code": "type_match", "severity": "info", "message": "El documento es Certificado médico deportivo." },
    { "code": "max_age_days", "severity": "info", "message": "Emitido hace 28 días (máximo 365)." },
    { "code": "require_signature", "severity": "info", "message": "El documento está firmado." },
    { "code": "require_stamp", "severity": "info", "message": "El documento tiene sello." }
  ]
}

With "language": "en" the max_age_days message reads "Issued 28 days ago (maximum 365).". The number of days depends on the date you run it. Extracted fields (each one is an object with value, confidence, validated and source):

FieldSample value
patient_nameMARÍA GARCÍA LÓPEZ
patient_id12345678Z (with the nif_check_digit validation)
issue_date2026-09-01
doctor_nameLAURA MARTÍN RUIZ
doctor_license_number282845678
fit_for_sporttrue
sportTiro con arco
restrictionsSin restricciones
signature_present, stamp_presenttrue

restrictions is free text: if the certificate says fit with limitations (e.g. "not fit for high-level competition"), decide in your code what to do. Constaia doesn't interpret restrictions beyond fit_for_sport.

What Constaia does not check

Constaia reads the doctor's licence number, but it does not ask the medical association whether that number exists or whether the doctor is registered. It doesn't verify the PDF's electronic signature either. If your regulations require it, do that check separately.

Decide

VerdictAction
VálidoMark the certificate as accepted and store the issue date to remind the athlete before it runs out.
No válidoShow the reasons (not fit, too old, no signature or stamp, different holder) and ask for another certificate.
RevisarA person reviews it: missing date, poor photo or low confidence. See Human review.

Store the analysis id, the verdict, issue_date and, if you need it, doctor_license_number in your system. With the issue date and your window you can work out when to ask for the next certificate.

Test it

With a ck_test_… key, a PDF named medical_certificate.pdf (any name containing medical or medico also works) returns the fit, signed and stamped certificate issued on 2026-09-01 shown above. With holder { "full_name": "María García López" } it adds an informational holder reason. Try another name to see invalid. More in Test mode.

Next steps

Nesta página