Claims · Coding

Medical Aid Claim Codes Explained: ICD-10, Tariff and NAPPI

Published 21 September 2026 · 7 min read

The three code sets on a South African claim: an ICD-10 diagnosis code, a tariff or procedure code, and a NAPPI code for items used

Every claim you send a South African medical scheme carries three different kinds of code, and each one answers a different question. The diagnosis code says why the patient was there. The tariff code says what you did. The NAPPI code says what you used. Get all three right and the claim pays. Get one subtly wrong and it comes back, often with a message that does not obviously explain itself.

Most coding advice stops at "use the right code". This is about the specific ways the three code sets go wrong in practice, and what the scheme's rejection message is actually telling you. For the wider list of reasons claims come back, start with why medical aid claims get rejected - this is the coding half of that story, in detail.

1. ICD-10: the diagnosis code, and the specificity trap

ICD-10 codes are arranged as a tree. A three-character code is a broad category, a four-character code narrows it, and a five-character code is usually the specific, codeable thing at the bottom. The rule is simple to state and easy to breach: code to the most specific level the clinical record supports.

Where this bites hardest is Chapter XX, the external-cause codes beginning with V, W, X and Y - the codes that say how an injury happened. In that chapter the three and four-character forms are headings, not codes. They exist to group the real codes beneath them. Send one on a claim and the scheme rejects it with a message like:

NOT FOR CLINICAL USE POSITION 2

That message is more helpful than it looks. It is telling you two things: a code you sent is a category header rather than a billable code, and the position number is the ICD-10 slot on the claim where it sits. You do not have to hunt through the whole claim.

A worked example. A patient falls and injures a hip. The claim goes out as:

  • S73.0 - dislocation of hip, as the primary diagnosis
  • W01.0 - a fall on the same level, as the cause
  • V49.9 - a car occupant injured in an unspecified event, also as a cause

This claim is rejected, and for more than one reason. W01.0 and V49.9 are both category headers, not billable codes - the billable form is the five-character leaf, W01.00 and so on. And the two cause codes contradict each other: the patient either fell on the level or was in a vehicle, not both. Schemes read cause codes as a statement about mechanism, and two mechanisms is not a more complete answer, it is a less credible one.

The injury rule worth pinning above the desk

  • An injury code in the S or T range needs an external cause code. Without a valid one the claim is rejected with NO CAUSE CODE SUPPLIED - and note that a category header counts as "not supplied", because it was never a usable code in the first place.
  • Sequence it: injury primary, cause secondary. The thing you treated leads.
  • One mechanism, not two. Pick the cause that actually happened.
  • Five characters on external causes. If your cause code has three or four, you are looking at a heading.

2. Tariff codes: why the same procedure has two different forms

Tariff codes - also called procedure or billing codes - are where discipline matters more than most practices expect. South African tariff codes are always at least four digits and zero-padded, so a "code 190" is written 0190. Beyond that there are two billed forms, and which one applies depends on what kind of practice you are.

Medical specialists bill the bare four-digit code. A GP, anaesthetist, paediatrician, dermatologist, surgeon or radiologist bills 0190 as 0190. That four-digit code is the code. Do not dress it up.

Allied and paramedical disciplines bill a five-digit code made of their BHF discipline number followed by the three-digit procedure. A physiotherapist's discipline number is 72, so the procedure written as 303 on a tariff schedule is billed as 72303 - not as 0303. The disciplines that work this way include:

  • Physiotherapy 72, Occupational Therapy 66, Biokinetics 91
  • Dietetics 84, Psychology 86, Social Work 89
  • Podiatry 68, Radiography 39, Audiology 82
  • Registered nursing 88 and home-based nursing care 80

This is the single most common structural coding error in allied practices, and it is invisible on a tariff schedule - the schedule prints the short procedure number, and it is on you to bill it in your discipline's form. If your codes are being rejected as unknown or priced at zero across the board rather than case by case, check the form before you check anything else.

One honest caveat: clinical technology (discipline 75) is inconsistent between schemes. The relationship between the short procedure number and the billed code is not uniform there, so confirm against each scheme's own schedule rather than assuming the pattern above holds.

3. NAPPI codes: what you used, not what you did

A NAPPI code identifies a specific item - a medicine at a specific strength and pack size, or a consumable, device or material. It is how the scheme knows what to price for the things you dispensed or consumed, as distinct from the professional act itself.

  • Medicines and materials are different buckets. A dispensed medicine and a surgical consumable are both NAPPI-coded, but they are not interchangeable categories on a claim.
  • Discontinued codes do not pay. NAPPI codes are retired as products change. Billing a retired code produces a rejection that looks like a pricing problem and is really a currency problem.
  • Specificity again. The pack and strength you actually used, not the nearest similar entry.

If you dispense, this is also where the remittance advice earns its keep: short-paid item lines are usually a NAPPI or a quantity question, not a tariff one.

How to stop coding errors costing you money

Coding errors are unusually expensive because they are silent. A rejected claim is not a bill you chase, it is money that does not exist yet, and it decays: claims generally go stale four months after the date of service. A coding rejection discovered in month five is not a rejection, it is a write-off.

  1. Pick codes from a maintained list, not from memory or a printout. Remembered and handwritten codes are how retired NAPPI codes and category headers get onto claims in the first place.
  2. Have the specificity trap caught before you submit, not by the scheme. A category header should be hard to select, and a missing external cause on an S or T code should be obvious while the patient's file is still open.
  3. See the rejection the same day. Every rejection reason above is a two-minute fix if you find it on the day of service, and a lost payment run if you find it next week. That difference is the whole argument for real-time submission.
  4. Read the reason code literally. Scheme messages are terse but precise. "Position 2" means position 2. "No cause code supplied" means the cause code you sent was not a code.

Frequently asked questions

My code worked last year and is rejected now. What changed?

Usually the code, not the claim. ICD-10 and NAPPI lists are revised, and codes are retired or replaced. It can also be a scheme tightening validation it previously let through - the same claim, newly checked.

Is a more general code the safer option when the notes are thin?

No, and this is worth being blunt about. A vaguer code is more likely to be rejected, and in the external-cause chapter it is not billable at all. The safe move is a specific code the record supports, which is an argument for capturing enough detail at the point of care.

Who is responsible if a coder gets it wrong?

The claim is submitted in the practice's name, so the rejection, the delay and the four-month clock are the practice's problem regardless of who typed the code. That is why the check belongs in the workflow rather than in one person's memory.

Codes picked from a live list, validated before submission, with the rejection reason back in seconds. Start claiming with NetPractice - free under 11 claims a month →