Norvya Developers
Get a sandbox
API reference · Specialty practices

Dermatology

Built — gated12 endpoints · 2 webhook events · OpenAPI tag derm

Lesion photo history and rechecks due, HS and acne severity scores, patch tests and their reads, and dermatology wound records (the record and its assessment dates, no measurements). No image bytes and no AI classification: the skin classifier is its own family below and is switched off. Webhooks: derm.lesion_recheck_due, derm.patch_test_read_recorded.

Who calls it
useful for Med spas
Before production
Treating practices; the patient's sharing choices apply.
Sandbox
Build against synthetic members first. What each sandbox holds

Markets that use this family

Scopes

ScopeAllows
derm.readRead a patient's tracked skin lesions (location, monitoring cadence, next recheck, and per photograph the date, the symptoms recorded and any biopsy result; size changes between photographs as image-based estimates; never the photograph and never the classifier's label or probabilities), your panel's lesion rechecks that are due, hidradenitis and acne severity history, patch tests with the allergen avoidance list, and the wound log (each wound's location and assessment dates, never its measurements) (treating practices with a BAA on file; lesions and wounds need the patient to share skin scans with you, severity and patch tests their medical history).
derm.writeRecord a hidradenitis suppurativa (IHS4 / Hurley) or acne (IGA) assessment, start a patch test with your own panel and record its 48h / 96h / day 7 reads, each attributed to a named clinician of your practice and scored by Norvya; never from a photograph (treating practices with a BAA on file).

Endpoints

A patient's tracked skin lesions: metadata and recheck state

GET/v1/patients/{member_ref}/lesionsderm.read

Each lesion the patient is watching in Norvya: their name for it, the body site, first noticed, monitoring cadence, next recheck and whether it is due, photographs taken, growth rate (image-based estimate) and status. Never the photograph and never the classifier's output (label, probabilities, risk level). The patient must share skin scans with you (403 consent_not_granted).

Parameters

member_refpath · stringrequired
include_archivedquery · boolean

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s "https://norvya.fly.dev/v1/patients/$MEMBER_REF/lesions" \
  -H "Authorization: Bearer $TOKEN"
Response 200
{
  "member_ref": "string",
  "external_id": "string",
  "count": 0,
  "lesions": [
    {}
  ],
  "withheld_fields": [
    "string"
  ],
  "images_available": false,
  "note": "string"
}

The response is the shape from the schema, not live data.

One tracked lesion: photograph series (metadata) and size changes

GET/v1/patients/{member_ref}/lesions/{lesion_ref}derm.read

The lesion's summary plus, per photograph, when it was taken, the site, whether an image is on file (never the image), the symptoms the patient recorded and any biopsy pathology result; and between photographs the size, colour and shape changes Norvya's comparison engine estimated. Another member's or an unknown lesion is 404 lesion_not_found.

Parameters

member_refpath · stringrequired
lesion_refpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

Errors specific to this call

404lesion_not_found

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s "https://norvya.fly.dev/v1/patients/$MEMBER_REF/lesions/$LESION_REF" \
  -H "Authorization: Bearer $TOKEN"
Response 200
{
  "member_ref": "string",
  "lesion": {},
  "withheld_fields": [
    "string"
  ],
  "images_available": false,
  "note": "string"
}

The response is the shape from the schema, not live data.

Your panel's lesion rechecks that are due (most overdue first)

GET/v1/derm/rechecksderm.read

Watched lesions whose own recheck date has passed, for your active members who share skin scans with you (or one member with ?member_ref=). Being overdue changes the urgency of the photograph, never an assessment; the classifier's risk level is not used to order or shown.

Parameters

member_refquery · string | null

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s "https://norvya.fly.dev/v1/derm/rechecks" \
  -H "Authorization: Bearer $TOKEN"
Response 200
{
  "items": [
    {}
  ],
  "count": 0,
  "members_not_sharing": 0,
  "method": "string"
}

The response is the shape from the schema, not live data.

Hurley stages, HS and acne sites, the IGA scale, patch-test grades and timepoints

GET/v1/derm/vocabularyderm.read

What a client needs to build the severity and patch-test forms, with each instrument's source. Needs derm.read or derm.write. No patient data.

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s "https://norvya.fly.dev/v1/derm/vocabulary" \
  -H "Authorization: Bearer $TOKEN"

A patient's hidradenitis (IHS4 / Hurley) and acne (IGA) assessments

GET/v1/patients/{member_ref}/derm-severityderm.read

Assessments clinicians recorded (Norvya never scores severity from a photograph), newest first, with the instrument sources. SCORAD and PASI are stateless calculators in Norvya and are not stored, so there is no history to return (not_available). The patient must share their medical history with you (403 consent_not_granted).

Parameters

member_refpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

Errors specific to this call

403consent_not_granted

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s "https://norvya.fly.dev/v1/patients/$MEMBER_REF/derm-severity" \
  -H "Authorization: Bearer $TOKEN"

Record a hidradenitis suppurativa assessment a named clinician made

POST/v1/patients/{member_ref}/derm-severity/hsderm.write

The clinician's lesion counts (and, when they judged it, the Hurley stage); Norvya computes IHS4 and its band exactly as the staff screen does. clinician is an active clinical staff member of your practice (422 clinician_not_found). Medical history shared (403 consent_not_granted).

Parameters

member_refpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

Request body

Content type: application/json (required)

clinicianstringrequired

staff_ref of the clinician who examined (GET /v1/panel/clinicians).

nodulesintegerrequired
abscessesintegerrequired
draining_tunnelsintegerrequired
hurley_stageinteger | null
sitesarray of string | null

GET /v1/derm/vocabulary hs_sites.

flareboolean
notestring | null
assessed_onstring | null

Errors specific to this call

403consent_not_granted

All responses

201Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s -X POST "https://norvya.fly.dev/v1/patients/$MEMBER_REF/derm-severity/hs" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clinician": "string",
    "nodules": 0,
    "abscesses": 0,
    "draining_tunnels": 0,
    "hurley_stage": 0,
    "sites": [
      "string"
    ],
    "flare": false,
    "note": "string",
    "assessed_on": "string"
  }'
Response 201
{
  "member_ref": "string",
  "assessment_ref": "string",
  "kind": "string",
  "assessment": {},
  "clinician": "string",
  "disclaimer": "string"
}

The response is the shape from the schema, not live data.

Record an acne (IGA) assessment a named clinician made

POST/v1/patients/{member_ref}/derm-severity/acnederm.write

The FDA 2005 IGA grade the clinician assigned, with optional counts and sites, stored exactly as the staff screen stores it. Medical history shared (403 consent_not_granted).

Parameters

member_refpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

Request body

Content type: application/json (required)

clinicianstringrequired
iga_gradeintegerrequired
sitesarray of string | null
inflammatory_countinteger | null
noninflammatory_countinteger | null
nodule_countinteger | null
scarringboolean
notestring | null
assessed_onstring | null

Errors specific to this call

403consent_not_granted

All responses

201Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s -X POST "https://norvya.fly.dev/v1/patients/$MEMBER_REF/derm-severity/acne" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clinician": "string",
    "iga_grade": 0,
    "sites": [
      "string"
    ],
    "inflammatory_count": 0,
    "noninflammatory_count": 0,
    "nodule_count": 0,
    "scarring": false,
    "note": "string",
    "assessed_on": "string"
  }'
Response 201
{
  "member_ref": "string",
  "assessment_ref": "string",
  "kind": "string",
  "assessment": {},
  "clinician": "string",
  "disclaimer": "string"
}

The response is the shape from the schema, not live data.

A patient's patch tests at your practice and their allergen avoidance list

GET/v1/patients/{member_ref}/patch-testsderm.read

Your practice's sessions (panel, schedule, per-allergen reads, positives, unread allergens) and the patient's avoidance list across every session a clinician read (only reactions graded positive; doubtful and irritant excluded with a count). Medical history shared (403 consent_not_granted).

Parameters

member_refpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

Errors specific to this call

403consent_not_granted

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s "https://norvya.fly.dev/v1/patients/$MEMBER_REF/patch-tests" \
  -H "Authorization: Bearer $TOKEN"

Start a patch test with your own panel

POST/v1/patients/{member_ref}/patch-testsderm.write

Patches applied by your practice: the panel you use, substance by substance (Norvya ships no allergen series), and when they went on. The answer carries the read schedule (48h, 96h, day 7). Medical history shared (403 consent_not_granted).

Parameters

member_refpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

Request body

Content type: application/json (required)

clinicianstringrequired
panel_namestringrequired
allergensarray of stringrequired

Your own panel, substance by substance (Norvya ships no series).

applied_atstring | null

Errors specific to this call

403consent_not_granted

All responses

201Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s -X POST "https://norvya.fly.dev/v1/patients/$MEMBER_REF/patch-tests" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clinician": "string",
    "panel_name": "string",
    "allergens": [
      "string"
    ],
    "applied_at": "string"
  }'
Response 201
{
  "member_ref": "string",
  "patch_test_ref": "string",
  "session": {}
}

The response is the shape from the schema, not live data.

One patch test of your practice

GET/v1/patch-tests/{patch_test_ref}derm.read

Another practice's or an unknown session is 404 patch_test_not_found; the patient must still be your member and share their medical history.

Parameters

patch_test_refpath · stringrequired

Errors specific to this call

404patch_test_not_found

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s "https://norvya.fly.dev/v1/patch-tests/$PATCH_TEST_REF" \
  -H "Authorization: Bearer $TOKEN"
Response 200
{
  "member_ref": "string",
  "patch_test_ref": "string",
  "session": {}
}

The response is the shape from the schema, not live data.

Record what a named clinician graded at one read

POST/v1/patch-tests/{patch_test_ref}/readsderm.write

ICDRG grades per allergen at 48h, 96h or day 7, read by the clinician who looked at the skin (Norvya never reads a patch test from a photograph). A corrected read supersedes the earlier one, never edits it. Allergens must be on the session's panel (422 allergen_not_in_panel).

Parameters

patch_test_refpath · stringrequired

Request body

Content type: application/json (required)

clinicianstringrequired
timepointstringrequired

48h | 96h | day7

gradesobjectrequired

allergen -> grade key (GET /v1/derm/vocabulary patch_grades).

read_atstring | null

Errors specific to this call

422allergen_not_in_panel

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s -X POST "https://norvya.fly.dev/v1/patch-tests/$PATCH_TEST_REF/reads" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clinician": "string",
    "timepoint": "48h",
    "grades": {},
    "read_at": "string"
  }'
Response 200
{
  "member_ref": "string",
  "patch_test_ref": "string",
  "session": {}
}

The response is the shape from the schema, not live data.

A patient's wound log: the record and its assessment dates (practices)

GET/v1/patients/{member_ref}/derm-woundsderm.read

The same wound log hospitals read (GET /v1/patients/{ref}/wounds), for a treating practice: location, first and last assessment and the date of each assessment. No measurements (they are the wound tracker's image-based estimates and are not shared with partners) and never the wound model's classification (type, stage, severity, trajectory, tissue percentages), the photograph, the patient's notes, pain score or treatment text. Skin scans shared (403 consent_not_granted).

Parameters

member_refpath · stringrequired

EMR vendors also pass vendor (the practice) with a vendor-issued token. EMR vendor tokens

Errors specific to this call

403consent_not_granted

All responses

200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service Unavailable

Codes every call can return are in Errors & limits.

curl -s "https://norvya.fly.dev/v1/patients/$MEMBER_REF/derm-wounds" \
  -H "Authorization: Bearer $TOKEN"
Response 200
{
  "member_ref": "string",
  "external_id": "string",
  "count": 0,
  "wounds": [
    {
      "wound_ref": "string",
      "body_location": "string",
      "case_type": "string",
      "first_assessed": "string",
      "last_assessed": "string",
      "assessments": 0,
      "series": [
        {}
      ],
      "images_available": false
    }
  ],
  "images_available": false,
  "note": "string"
}

The response is the shape from the schema, not live data.

Webhook events

Payloads carry no health data, only a reference to fetch with your token. Each event needs its scope as well as webhooks.manage. Signing and retries

EventScopeWhen
derm.lesion_recheck_duederm.readA tracked lesion of a member who shares skin scans with the practice reached its recheck date (once per lesion per due date).
derm.patch_test_read_recordedderm.readA read was recorded on a patch test of the practice (once per read set; never an allergen or a grade).

Generated from the Partner API router and developers_catalog.py. The router docstring is the source of each description.

↑ ↓ to moveEnter to open