RadShip.com Home

← About the Classification API

RadShip 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.

Getting access

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.

POST /api/classify

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"
}

Request fields

FieldTypeNotes
radionuclides[]arrayOne entry per radionuclide in the package.
.radionuclideIdstringe.g. Cs-137. Full list: GET /api/radionuclides. Unknown IDs return suggestions.
.activitynumberPositive.
.unitenumTBq GBq MBq kBq Bq Ci mCi uCi nCi g — grams converts via specific activity.
.physicalStateenumSolid | Liquid | Gas
.materialFormenumNormal Form | Special Form
.massInGramsnumber | nullTotal material mass (material + matrix) for the exempt-concentration check. Optional when unit is g.
maxSurfaceDoseRateMsvHrnumberOptional 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.
packageCharacterizationenumnone | instruments_articles | empty_packaging | du_thorium_articles | sco | lsa
lsaProfileenumRequired 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.
lsaAttestationsstring[]Shipper attestation statements for the chosen profile (exact strings; a missing-attestation response lists the required ones).
fissileInputsobjectOptional — enrichment %, fissile/nonfissile/moderator masses for the 49 CFR 173.453 evaluation.
airTransportobjectOptional — adds an IATA / 49 CFR 175.700 air-eligibility assessment (transportMode, aircraftType, intendedUse, transportIndex, attestations).
decayobjectOptional — { 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.
transportobjectOptional — 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.

Response

{
  "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.

Quickstart (Python)

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.009

GET /api/radionuclides

Returns the supported radionuclide IDs — entries verified against 49 CFR 173.435, plus DOT Table 7/8 default entries — for autocomplete and pre-validation.

Errors

HTTPCodeMeaning
401UNAUTHORIZEDMissing or invalid API key.
400INVALID_JSONBody is not valid JSON.
400UNKNOWN_RADIONUCLIDEID not in database — response includes suggestions.
400MISSING_SPECIFIC_ACTIVITYGrams unit used for a nuclide with no specific activity on file.
400INVALID_INPUTSchema validation failed — details list each field with regulatory context.
400INVALID_AIR_INPUTAir-transport overlay input invalid.
400INVALID_TRANSPORT_INPUTTransport overlay input invalid (or packageCategory underivable for a non-transportable result).
400INVALID_DECAY_INPUTDecay overlay input invalid (dates malformed or ship date before assay date).
429RATE_LIMITEDPer-key request rate exceeded — retry with backoff.
500INTERNAL_ERRORUnexpected failure — contact support.

Important notes