← About the Classification API
The same engine behind RAMcalc, as a REST API: send radionuclides and package details, get back the full DOT Class 7 classification — UN number, proper shipping name, shipment type, exempt-material evaluation, fissile determination, HRCQ/RQ flags, and optional air-transport (IATA / 49 CFR 175.700) eligibility — with the regulatory reasoning and CFR citations for every determination.
API access is currently offered as a managed integration. Contact us to get an API key — we'll help you map your data to the request schema and validate your first classifications.
Authenticate every request with your key in the x-api-key header. Keys can be revoked and re-issued at any time; treat them as secrets.
Classifies one package. Example:
POST /api/classify HTTP/1.1
Host: radship.com
Content-Type: application/json
x-api-key: rsk_live_...
{
"radionuclides": [
{
"radionuclideId": "Cs-137",
"activity": 5,
"unit": "Ci",
"physicalState": "Solid",
"materialForm": "Special Form",
"massInGrams": 100
}
],
"packageCharacterization": "none"
}| Field | Type | Notes |
|---|---|---|
| radionuclides[] | array | One entry per radionuclide in the package. |
| .radionuclideId | string | e.g. Cs-137. Full list: GET /api/radionuclides. Unknown IDs return suggestions. |
| .activity | number | Positive. |
| .unit | enum | TBq GBq MBq kBq Bq Ci mCi uCi nCi g — grams converts via specific activity. |
| .physicalState | enum | Solid | Liquid | Gas |
| .materialForm | enum | Normal Form | Special Form |
| .massInGrams | number | null | Total material mass (material + matrix) for the exempt-concentration check. Optional when unit is g. |
| maxSurfaceDoseRateMsvHr | number | Optional survey reading (mSv/h). When present and > 0.005 mSv/h (0.5 mrem/hr), excepted-package pathways (173.421(a)(1)/.424/.426/.428) fail their radiation gate — e.g. a Limited Quantity reclassifies to Type A. When absent, excepted results carry a condition note. |
| packageCharacterization | enum | none | instruments_articles | empty_packaging | du_thorium_articles | sco | lsa |
| lsaProfile | enum | Required with lsa: ore_norm | unirradiated_nat_u_th | tritiated_water | distributed_activity | solid_object. Classifies as UN2912/3321/3322 (primary result) per 49 CFR 173.403. |
| lsaAttestations | string[] | Shipper attestation statements for the chosen profile (exact strings; a missing-attestation response lists the required ones). |
| fissileInputs | object | Optional — enrichment %, fissile/nonfissile/moderator masses for the 49 CFR 173.453 evaluation. |
| airTransport | object | Optional — adds an IATA / 49 CFR 175.700 air-eligibility assessment (transportMode, aircraftType, intendedUse, transportIndex, attestations). |
| decay | object | Optional — { assayDate, shipDate }. Decays each activity to the ship date (parent-only, IAEA half-lives) before classifying; per-nuclide factors returned in data.decay. Daughter ingrowth is not modeled. |
| transport | object | Optional — package survey readings (maxSurfaceDoseRateMsvHr, maxDoseRateAt1mMsvHr, optional grossMassKg and subsidiary-hazard fields). Returns data.transport: Transport Index, label category, exclusive use, markings, placards, segregation, and shipping-paper fields (49 CFR 172.403/.504 · 173.441 · 178.350). packageCategory is derived from the classification result when omitted. |
{
"success": true,
"data": {
"unNumber": "UN3332",
"properShippingName": "Radioactive material, Type A package, special form",
"shipmentType": "Type A — Special Form, Non-fissile",
"isRegulatedClass7": true,
"hazardClass": 7,
"totalActivityTBq": 0.185,
"totalSumOfFractions": 0.0925,
"containsFissile": false,
"exemptCheck": { ... },
"tierAnalysis": { ... },
"effectiveAValues": null,
"labelingNuclides": [ "Cs-137" ],
"reasons": [ ... ],
"cfrReferences": [ ... ],
"airTransport": null,
"transport": null,
"decay": null
},
"meta": {
"engineVersion": "...",
"dataVersion": "...",
"timestamp": "...",
"inputHash": "..."
}
}Every response carries meta.engineVersion, meta.dataVersion, and an inputHash so classifications are reproducible and audit-traceable.
A complete working example: classify a batch, then scan ship dates to find the shipping window. Requires pip install requests and your API key in the RADSHIP_API_KEY environment variable (keep keys out of code and notebooks).
import os
from datetime import date, timedelta
import requests
API_URL = "https://radship.com/api/classify"
API_KEY = os.environ["RADSHIP_API_KEY"] # never hardcode the key
BATCH = [
{
"radionuclideId": "Lu-177",
"activity": 3,
"unit": "Ci",
"physicalState": "Liquid",
"materialForm": "Normal Form",
"massInGrams": 20,
},
]
ASSAY_DATE = date(2026, 7, 22)
def classify(ship_date=None):
body = {"radionuclides": BATCH, "packageCharacterization": "none"}
if ship_date is not None:
body["decay"] = {
"assayDate": ASSAY_DATE.isoformat(),
"shipDate": ship_date.isoformat(),
}
r = requests.post(API_URL, json=body,
headers={"x-api-key": API_KEY}, timeout=30)
payload = r.json()
if not payload.get("success"):
raise RuntimeError(payload["error"])
return payload["data"]
# 1. Classify as assayed
result = classify()
print(f"As assayed: {result['unNumber']} ({result['shipmentType']}) "
f"SoF={result['totalSumOfFractions']:.3f}")
# 2. Shipping-window scan
for days in range(0, 29, 7):
ship = ASSAY_DATE + timedelta(days=days)
r = classify(ship)
print(f" +{days:2d}d: {r['unNumber'] or 'not regulated':>8} "
f"{r['totalActivityCi']:.3f} Ci SoF={r['totalSumOfFractions']:.3f}")Example output — watch the batch decay toward exempt over four weeks:
As assayed: UN2915 (Type A — Normal Form, Non-fissile) SoF=0.159
+ 0d: UN2915 3.000 Ci SoF=0.159
+ 7d: UN2915 1.445 Ci SoF=0.076
+14d: UN2915 0.696 Ci SoF=0.037
+21d: UN2915 0.335 Ci SoF=0.018
+28d: UN2915 0.162 Ci SoF=0.009Returns the supported radionuclide IDs — entries verified against 49 CFR 173.435, plus DOT Table 7/8 default entries — for autocomplete and pre-validation.
| HTTP | Code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid API key. |
| 400 | INVALID_JSON | Body is not valid JSON. |
| 400 | UNKNOWN_RADIONUCLIDE | ID not in database — response includes suggestions. |
| 400 | MISSING_SPECIFIC_ACTIVITY | Grams unit used for a nuclide with no specific activity on file. |
| 400 | INVALID_INPUT | Schema validation failed — details list each field with regulatory context. |
| 400 | INVALID_AIR_INPUT | Air-transport overlay input invalid. |
| 400 | INVALID_TRANSPORT_INPUT | Transport overlay input invalid (or packageCategory underivable for a non-transportable result). |
| 400 | INVALID_DECAY_INPUT | Decay overlay input invalid (dates malformed or ship date before assay date). |
| 429 | RATE_LIMITED | Per-key request rate exceeded — retry with backoff. |
| 500 | INTERNAL_ERROR | Unexpected failure — contact support. |