{"openapi":"3.1.0","info":{"title":"inportr API","version":"0.1.0","summary":"US tariff screening against the pinned engine release.","description":"A screening aid, not legal advice or a CBP ruling. Every answer names the engine release that produced it and is signed. /v1 only ever adds fields; a breaking change would be /v2. During the pilot the API is used through a signed-in browser session; API keys come later.","x-engine":{"release":null,"commit":"66a21eaf651913c3619b739182d6963c1a81dff4","html_sha256":"b4f9242695404c2485480f6377d4247a635fb26f22d37e45f4168aa22aea3f0b"},"x-data-edition":{"name":"2026 HTS Rev 20","start":"2026-09-28"}},"servers":[{"url":"/"}],"components":{"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"A stable, machine-readable code, e.g. unknown_origin, plan_cap_reached."},"message":{"type":"string","description":"A sentence for a person."},"field":{"type":"string","description":"The request field at fault, when there is one."},"suggestions":{"type":"array","items":{"type":"string"},"description":"For unknown_origin: the nearest origins the engine holds. Never applied automatically."},"used":{"type":"integer","description":"plan_cap_reached: screens used this month."},"cap":{"type":"integer","description":"plan_cap_reached: the monthly allowance."},"resets_at":{"type":"string","format":"date-time","description":"plan_cap_reached: when the allowance resets (UTC)."}}}}},"EngineRelease":{"type":"object","required":["release","commit","html_sha256"],"description":"The engine release that produced an answer.","properties":{"release":{"anyOf":[{"type":"string","description":"The release tag; null until the first tagged release."},{"type":"null"}]},"commit":{"type":"string","description":"The engine repository commit."},"html_sha256":{"type":"string","description":"SHA-256 of the engine file the service checked before starting."}}},"DataEdition":{"type":"object","required":["name","start"],"properties":{"name":{"type":"string","description":"e.g. \"2026 HTS Rev 20\"."},"start":{"type":"string","format":"date"}}},"Signature":{"type":"object","required":["alg","key_id","value"],"description":"Ed25519 over the canonical JSON (keys sorted at every level, no whitespace) of the response body without this field. Check it with the key from /v1/signing-keys.","properties":{"alg":{"const":"Ed25519"},"key_id":{"type":"string"},"value":{"type":"string","description":"base64"}}},"ScreenRequest":{"type":"object","required":["code","origin","entry_date"],"additionalProperties":false,"properties":{"code":{"type":"string","pattern":"^[0-9.\\s]+$","description":"An 8- or 10-digit HTS number; dots and spaces are allowed.","examples":["8479.89.9510"]},"stat_suffix":{"type":["string","integer","null"],"description":"The two statistical digits, when code has 8."},"origin":{"type":"string","enum":["OTHER","Belarus","Cuba","North Korea","Algeria","Angola","Argentina","Australia","Austria","Bahamas","Bahrain","Bangladesh","Belgium","Brazil","Bulgaria","Cambodia","Canada","Chile","China","Colombia","Costa Rica","Croatia","Cyprus","Czechia","Denmark","Dominican Republic","Ecuador","Egypt","El Salvador","Estonia","European Union","Finland","France","Germany","Greece","Guatemala","Guyana","Honduras","Hong Kong, China","Hungary","India","Indonesia","Iraq","Ireland","Israel","Italy","Japan","Jordan","Kazakhstan","Kuwait","Latvia","Libya","Liechtenstein","Lithuania","Luxembourg","Malaysia","Malta","Mexico","Morocco","Netherlands","New Zealand","Nicaragua","Nigeria","Norway","Oman","Pakistan","Peru","Philippines","Poland","Portugal","Qatar","Romania","Russia","Saudi Arabia","Singapore","Slovakia","Slovenia","South Africa","South Korea","Spain","Sri Lanka","Sweden","Switzerland","Taiwan","Thailand","Trinidad and Tobago","Turkiye","United Arab Emirates","United Kingdom","Uruguay","Venezuela","Vietnam","Afghanistan","Bolivia","Bosnia and Herzegovina","Botswana","Brunei","Cameroon","Chad","Côte d'Ivoire","Democratic Republic of the Congo","Equatorial Guinea","Falkland Islands","Fiji","Ghana","Iceland","Laos","Lesotho","Macau","Madagascar","Malawi","Mauritius","Moldova","Mozambique","Myanmar (Burma)","Namibia","Nauru","North Macedonia","Papua New Guinea","Serbia","Syria","Tunisia","Turkey","Uganda","Vanuatu","Zambia","Zimbabwe","Ukraine","Panama","United States"],"description":"Country of origin, one of the values from /v1/origins. An unknown origin is refused, never mapped."},"entry_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"YYYY-MM-DD. Entries before 2025-01-01 are not screened."},"facts":{"anyOf":[{"type":"object","properties":{"metal_weight":{"type":"string","enum":["atleast","under","none","skip"],"description":"Outside chapters 72, 73, 74 and 76: what share of the article's weight is the applicable metal ({metal})?"},"us_content":{"type":"string","enum":["yes","no","skip"],"description":"Was at least {pct} percent of the {metal} content of the article {test}?"},"uk_content":{"type":"string","enum":["yes","no","skip"],"description":"Was at least 95 percent of the aluminum smelted or most recently cast, or of the steel melted and poured, in the United Kingdom?"},"russia_aluminum":{"type":"string","enum":["yes","no","skip"],"description":"Was any primary aluminum used in the article smelted in Russia, or was the article cast in Russia?"},"motorcycle_parts":{"type":"string","enum":["yes","no","skip"],"description":"Is the article a motorcycle part of chapter 84, 85 or 87 for use in the manufacturing of motorcycles in the United States?"},"equipment_parts":{"type":"string","enum":["yes","no","skip"],"description":"Will the part be used exclusively in the manufacturing of agricultural equipment or fixed industrial equipment of note 16(c)(ix)–(x), or mobile industrial equipment of note 16(c)(xi)?"},"commerce_quantity":{"type":"string","enum":["yes","no","skip"],"description":"Is this entered under a quantity the Secretary of Commerce authorized for a tariff reduction under Proclamation 10984 (metal melted and poured or smelted and cast in Canada or Mexico, USMCA-qualifying)?"},"usmca":{"type":"string","enum":["yes","no","skip"],"description":"Are the goods entered free of duty under the USMCA (general note 11)?"},"civil_aircraft":{"type":"string","enum":["yes","no","skip"],"description":"Is the article a civil aircraft article meeting general note 6 — a civil aircraft (all aircraft other than military aircraft), its engines, parts and components, its other parts, components and subassemblies, or a ground flight simulator or its parts and components?"},"covered232":{"type":"string","enum":["yes","no","skip"],"description":"Is the good subject to a Section 232 duty heading on this entry?"},"pharma_kind":{"type":"string","enum":["patented","generic","neither","not_pharma","skip"],"description":"Which is the article: a patented pharmaceutical article (or an ingredient for one), a generic pharmaceutical article, a pharmaceutical article that is neither, or not a pharmaceutical article at all?"},"pharma_noncommercial":{"type":"string","enum":["yes","no","skip"],"description":"Is the article solely for use in clinical trials, research and development, or other non-commercial applications?"},"pharma_us_api":{"type":"string","enum":["yes","no","skip"],"description":"Is the active pharmaceutical ingredient, packaged in dosage form, a product of the United States?"},"pharma_annex_iii":{"type":"string","enum":["yes","no","skip"],"description":"Is the importer one of the companies the Secretary identified in Annex III to Proclamation 11020 (AbbVie Inc.; Amgen Inc.; AstraZeneca Pharmaceuticals, LP; Bristol Myers Squibb; Boehringer Ingelheim Pharmaceuticals, Inc.; Eli Lilly and Company; EMD Serono, Inc.; Genentech, Inc.; Gilead Sciences, Inc.; GlaxoSmithKline LLC and ViiV Healthcare Company; Johnson & Johnson; Merck Sharp & Dohme LLC; Novartis Pharmaceuticals Corporation; Novo Nordisk Inc.; Pfizer Inc.; Regeneron Pharmaceuticals, Inc.; Sanofi S.A.)?"},"pharma_designated":{"type":"string","enum":["yes","no","skip"],"description":"Is the article one of the specialty products note 40(h)(iii) names — a drug whose approved indications are all designated orphan, a nuclear medicine, a plasma-derived therapy, a fertility drug, a cell or gene therapy product, an antibody drug conjugate, a CBRN medical countermeasure, an animal healthcare product, or another specialty product the Secretary of Commerce identifies?"},"pharma_urgent_need":{"type":"string","enum":["yes","no","skip"],"description":"Has Commerce approved this product, for this company, as meeting an urgent U.S. health need?"},"pharma_onshoring":{"type":"string","enum":["yes","no","skip"],"description":"Is the article imported for a company subject to an onshoring plan approved by the Secretary of Commerce (note 40(h)(i))?"},"pharma_mfn":{"type":"string","enum":["yes","no","skip"],"description":"Has that company also entered a Most-Favored-Nation pharmaceutical pricing agreement with the Secretary of Health and Human Services?"},"uas_use":{"type":"string","enum":["yes","no","skip"],"description":"Is the article for use in or with an unmanned aircraft system?"},"uas_thermal":{"type":"string","enum":["yes","no","skip"],"description":"Does the unmanned aircraft have thermal imaging?"},"uas_parts_over25":{"type":"string","enum":["yes","no","skip"],"description":"Is the part or component for use in or with a system with a maximum take-off weight of more than 25 kg, other than a system for retail delivery use, agricultural use or sale to the Department of War?"},"uas_partner_content":{"type":"string","enum":["yes","no","skip"],"description":"Are substantially all the critical components and technology of the article the product of the United States, Japan, Korea, Taiwan, Switzerland, Liechtenstein, an EU member or the United Kingdom?"},"uas_onshoring_dhs":{"type":"string","enum":["yes","no","skip"],"description":"Is the article imported for a company subject to an onshoring plan approved by the Department of Homeland Security or the Department of War?"},"uas_onshoring_commerce":{"type":"string","enum":["yes","no","skip"],"description":"Is the article imported subject to an onshoring plan approved by the Secretary of Commerce?"},"semi_spec":{"type":"string","enum":["yes","no","skip"],"description":"Is the article, or does it contain, a logic integrated circuit meeting the note 39(b) technical parameters?"},"semi_end_use":{"type":"string","enum":["none","use_03","use_04","use_05","use_06","use_07","use_08","use_09","skip"],"description":"Is the article for one of the uses note 39(d) excludes from the duty?"},"vehicle_part":{"type":"string","enum":["yes","no","skip"],"description":"Is the article a part of a passenger vehicle (sedan, sport utility vehicle, crossover utility vehicle, minivan or cargo van) or of a light truck?"},"knockdown_kit":{"type":"string","enum":["yes","no","skip"],"description":"Is the article an automobile knock-down kit or a parts compilation?"},"uk_parts_certification":{"type":"string","enum":["yes","no","skip"],"description":"Does the importer of record certify that the parts will be used in automobiles that are products of the United Kingdom (note 33(q))?"},"quota_within":{"type":"string","enum":["yes","no","skip"],"description":"Is the entry within the aggregate quantity the safeguard's tariff-rate quota allows for the period (annual for solar cells and UK vehicles; quarterly for washers)?"},"annex_ex_122":{"type":"string","enum":["yes","no","skip"],"description":"Is the article “{desc}” — the only part of this subheading the Section 122 Annex II lists?"},"pharma_use":{"type":"string","enum":["yes","no","skip"],"description":"Is the article for use in pharmaceutical applications?"},"us_content_20":{"type":"string","enum":["yes","no","skip"],"description":"Is at least 20 percent of the customs value of the article U.S.-originating content?"},"pharma_patented":{"type":"string","enum":["yes","no","skip"],"description":"Is the article patented in the United States for use in pharmaceutical applications?"},"deal_particular":{"type":"string","enum":["yes","no","skip"],"description":"Is the article “{desc}” — the only article of this subheading the exception names?"},"in_transit_aug7":{"type":"string","enum":["yes","no","skip"],"description":"Were the goods loaded onto a vessel at the port of loading and in transit on the final mode of transit before 12:01 a.m. EDT on 7 August 2025, and entered for consumption (or withdrawn from warehouse) before 12:01 a.m. EDT on 5 October 2025?"},"fl_particular":{"type":"string","enum":["yes","no","skip"],"description":"Is the article “{desc}” — the particular article U.S. note 52 names in this subheading?"},"cafta_claim":{"type":"string","enum":["yes","no","skip"],"description":"Is this a textile or apparel good (general note 29(d)(v)) for which entry is claimed free of duty under the Dominican Republic-Central America-United States Free Trade Agreement (CAFTA-DR)?"},"hdv_part":{"type":"string","enum":["yes","no","skip"],"description":"Is the article a part of a medium- or heavy-duty vehicle?"},"hdv_knockdown_kit":{"type":"string","enum":["yes","no","skip"],"description":"Is the article a medium- or heavy-duty vehicle knock-down kit or a parts compilation?"},"sts_crane":{"type":"string","enum":["yes","no","skip"],"description":"Is the article a ship-to-shore gantry crane, configured as a high- or low-profile steel superstructure and designed to unload intermodal containers from vessels with coupling devices for containers, including spreaders or twist-locks?"},"sts_contract_2024":{"type":"string","enum":["yes","no","skip"],"description":"Is the crane fulfilling, in whole or in part, an executed contract for sale dated before 14 May 2024?"},"sts_cn_components":{"type":"string","enum":["yes","no","skip"],"description":"Does the crane contain any of these components, assemblies or subassemblies that are products of China: the boom, the trolley, the spreader, the cabin, the legs, the cable reel, the power supply, the bogie set and wheels, or any information technology equipment used to operate or control the crane?"},"sts_cn_owned":{"type":"string","enum":["yes","no","skip"],"description":"Is the crane manufactured by a company or other entity owned or controlled by a Chinese person or legal entity (U.S. note 31(l)(v): including 25 percent or more of board seats, voting rights or equity held directly or indirectly)?"},"sts_contract_2025":{"type":"string","enum":["yes","no","skip"],"description":"Will the importer attest that the crane fulfils, in whole or in part, an executed contract for sale dated before 17 April 2025?"},"intermodal_chassis":{"type":"string","enum":["yes","no","skip"],"description":"Is the article an intermodal chassis, a subassembly of one, or a part of one, as U.S. note 31(k)(i) describes?"},"enteral_syringe":{"type":"string","enum":["yes","no","skip"],"description":"Is the article an enteral syringe?"},"vehicle_25yr":{"type":"string","enum":["yes","no","skip"],"description":"Was the vehicle manufactured in a year at least 25 years before the year of the date of entry?"},"parts_offset":{"type":"string","enum":["yes","no","skip"],"description":"Will you claim a Department of Commerce import adjustment offset license on this line?"},"wood_cabinet":{"type":"string","enum":["yes","no","skip"],"description":"Is the article a completed wooden kitchen cabinet or vanity, or a part of one?"},"passenger_vehicle":{"type":"string","enum":["yes","no","skip"],"description":"Is the article a passenger vehicle (sedan, sport utility vehicle, crossover utility vehicle, minivan or cargo van) or a light truck?"},"mhdv_vehicle":{"type":"string","enum":["yes","no","skip"],"description":"Is the article a medium- or heavy-duty vehicle?"},"metals_quota_within":{"type":"string","enum":["yes","no","skip"],"description":"Was the entry within the quota for its product category and period (the quantity not yet filled when the entry was presented)?"},"eu_steel_melt":{"type":"string","enum":["eu","uk","ukraine","other","skip"],"description":"Where was the steel melted and poured?"},"mx_steel_melt_outside":{"type":"string","enum":["yes","no","skip"],"description":"Was the steel melted and poured in a country other than the United States, Mexico or Canada?"},"mx_alu_smelt_listed":{"type":"string","enum":["yes","no","skip"],"description":"Is the primary country of smelt, the secondary country of smelt or the country of most recent cast of the aluminum China, Russia, Belarus or Iran?"},"fta_claim":{"type":"string","enum":["yes","no","skip"],"description":"Does the good qualify under the {program}, and is the preference claimed on the entry (special program indicator {sym})?"},"sg_25m":{"type":"string","enum":["yes","no","skip"],"description":"Were the goods imported from Singapore, whatever their origin, and is the U.S.-Singapore FTA claimed for them as goods general note 25(m) lists ({desc})?"},"ukraine_coo":{"type":"string","enum":["yes","no","skip"],"description":"Is the entry accompanied by a certificate of origin?"},"ch98":{"type":"string","enum":["none","9801.00.10","9802.00.40","9802.00.50","9802.00.60","9802.00.80","skip"],"description":"Is the entry claimed under a chapter 98 provision?"},"br301_particular":{"type":"string","enum":["yes","no","skip"],"description":"Is the article \"{desc}\" (U.S. note 50(a)(iii))?"},"br301_pharma":{"type":"string","enum":["yes","no","skip"],"description":"Is the article for use in pharmaceutical applications (U.S. note 50(a)(v))?"},"br301_in_transit":{"type":"string","enum":["yes","no","skip"],"description":"Were the goods loaded onto a vessel at the port of loading and in transit on the final mode of transit before 12:01 a.m. eastern time on July 22, 2026?"},"fl_in_transit":{"type":"string","enum":["yes","no","skip"],"description":"Were the goods loaded onto a vessel at the port of loading and in transit on the final mode of transit before 12:01 a.m. eastern time on July 24, 2026?"},"us_goods_position":{"type":"string","enum":["charge","not_subject","skip"],"description":"For a U.S.-origin product entered without a chapter 98 claim: does the entry report the reciprocal / Section 122 duty?"}},"additionalProperties":false,"description":"Answers to the fact questions a screen asks; \"skip\" leaves one open. See /v1/facts."},{"type":"null"}]},"declared_stack":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"The Chapter 99 headings (9903.xx.xx), 9999.00.xx numbers or chapter 98 provisions declared on the entry, to be identified against it."},"programmes":{"anyOf":[{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string","enum":["338","301","301fl","232","232v","232w","232s","232p","232u","122","ieepa","201"]},"description":"The programmes to screen, by id from /v1/meta (the tool's switches). Absent or null: every programme. The others are left out of the result and named under programmes.off."},{"type":"null"}]}}},"Layer":{"type":"object","required":["tag","rate","on"],"properties":{"tag":{"type":"string"},"rate":{"type":"string"},"on":{"type":"boolean"},"heading":{"anyOf":[{"type":"string"},{"type":"null"}]},"note":{"type":"string"},"desc":{"type":"string"},"range":{"type":"string"},"claim":{"type":"boolean","description":"Charges nothing but is a line on the entry: relief claimed with its heading (\"no duty · declare to claim\")."},"asks":{"type":"array","items":{"type":"string"},"description":"The fact ids (see /v1/facts) whose answer settles this row's range."},"exclusions":{"type":"array","description":"Section 301 exclusions in force for this code on the entry date: declare the exclusion heading instead if the product meets the exclusion description.","items":{"type":"object","required":["heading","note","entries"],"properties":{"heading":{"type":"string"},"note":{"type":"string"},"entries":{"type":"integer"},"ends":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]}}}}}},"CandidateGroup":{"type":"object","required":["prog","title","rows"],"properties":{"prog":{"type":"string","description":"The programme."},"title":{"type":"string"},"definitive":{"type":["string","boolean"]},"rows":{"type":"array","items":{"type":"object","required":["heading","rate","role"],"properties":{"heading":{"type":"string"},"rate":{"type":"string"},"role":{"type":"string"},"lead":{"type":"string"},"cond":{"type":"string"}}}}}},"Question":{"type":"object","required":["id","q","options"],"properties":{"id":{"type":"string","description":"The fact id to answer in facts."},"q":{"type":"string"},"cite":{"type":"string"},"help":{"type":"string"},"group":{"type":"string"},"state":{"type":"string"},"options":{"type":"array","items":{"type":"object","required":["v","label"],"properties":{"v":{"type":"string"},"label":{"type":"string"}}}}}},"ScreenResponse":{"type":"object","required":["request_id","screened_at","engine","changelog_url","data_edition","input","code_status","estimate","layers","assumptions","candidates","questions","decoded","card_html","disclaimer","signature"],"description":"The engine's own screen() result, plus the fields the service adds (request_id, screened_at, engine, changelog_url, signature). The service never computes, reorders or rewords a result.","properties":{"request_id":{"type":"string"},"screened_at":{"type":"string","format":"date-time"},"engine":{"$ref":"#/components/schemas/EngineRelease"},"changelog_url":{"type":"string"},"data_edition":{"$ref":"#/components/schemas/DataEdition"},"input":{"type":"object","required":["code8","stat10","origin","entry_date","facts"],"properties":{"code8":{"type":"string"},"stat10":{"anyOf":[{"type":"string"},{"type":"null"}]},"origin":{"type":"object","required":["v","label"],"properties":{"v":{"type":"string"},"label":{"type":"string"}}},"entry_date":{"type":"string","format":"date"},"facts":{"type":"object"}}},"programmes":{"type":"object","required":["on","off"],"description":"The programmes screened and those left out by the request. A duty of a programme left out is in no figure.","properties":{"on":{"type":"array","items":{"type":"string"}},"off":{"type":"array","items":{"type":"string"}}}},"code_status":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"},"stat":{"type":"string"},"statOk":{"type":"boolean"},"suffixes":{"type":"array","items":{"type":"string"}}}},"estimate":{"type":"object","required":["total","totalHi","spread","allIn","base"],"description":"A range when the answer depends on a fact not yet given: total to totalHi.","properties":{"total":{"type":"number"},"totalHi":{"type":"number"},"spread":{"type":"boolean"},"allIn":{"type":"object","required":["lo","hi"],"properties":{"lo":{"type":"number"},"hi":{"type":"number"}}},"base":{"type":"object"}}},"layers":{"type":"array","items":{"$ref":"#/components/schemas/Layer"}},"assumptions":{"type":"array","items":{"type":"string"}},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/CandidateGroup"}},"questions":{"type":"array","items":{"$ref":"#/components/schemas/Question"}},"decoded":{"anyOf":[{"type":"object","required":["rows","missing"],"properties":{"rows":{"type":"array","items":{"type":"object"}},"missing":{"type":"array","items":{"type":"string"}},"labels":{"type":"object"}}},{"type":"null"}]},"card_html":{"type":"string","description":"The engine's result card, as HTML."},"citations":{"anyOf":[{"type":"object","description":"The text behind each heading a row charges, claims, offers or names as an exclusion: the heading's own words and the U.S. note subdivisions that name this code, from the pinned HTS edition.","properties":{"edition":{"type":"string"},"edition_start":{"type":"string","format":"date"},"earlier_entry":{"type":"boolean","description":"The entry date is before the edition took effect; the note may have read differently then."},"headings":{"type":"array","items":{"type":"object","required":["heading"],"properties":{"heading":{"type":"string"},"role":{"type":"string"},"heading_text":{"anyOf":[{"type":"string"},{"type":"null"}]},"notes":{"type":"array","items":{"type":"object","properties":{"ref":{"type":"string"},"located":{"type":"boolean"},"text":{"type":"string"},"list_size":{"type":"integer"},"listed":{"type":"boolean"},"entry":{"anyOf":[{"type":"string"},{"type":"null"}]},"printed_as":{"anyOf":[{"type":"string"},{"type":"null"}]},"refers_to":{"type":"object"}}}}}}}}},{"type":"null"}]},"disclaimer":{"type":"string"},"signature":{"$ref":"#/components/schemas/Signature"}}},"Meta":{"type":"object","required":["engine","data_edition","date_bounds","disclaimer","signing_key_id"],"properties":{"engine":{"$ref":"#/components/schemas/EngineRelease"},"data_edition":{"$ref":"#/components/schemas/DataEdition"},"date_bounds":{"type":"object","required":["min","max"],"properties":{"min":{"type":"string","format":"date"},"max":{"type":"string","format":"date"}}},"disclaimer":{"type":"string"},"signing_key_id":{"type":"string"},"programmes":{"type":"array","description":"The programmes a request may switch, as the tool names them.","items":{"type":"object","required":["id","name","scope"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"scope":{"type":"string"}}}}}},"BatchLineError":{"type":"object","required":["line","code","message"],"properties":{"line":{"type":"integer","description":"The line in the file, the header being line 1."},"reference":{"type":["string","null"]},"code":{"type":"string","description":"The same error code POST /v1/screen gives for the input."},"message":{"type":"string"},"field":{"type":"string"},"suggestions":{"type":"array","items":{"type":"string"}}}},"Me":{"type":"object","required":["user","organisation"],"properties":{"user":{"type":"object","required":["email"],"properties":{"id":{"type":"string"},"email":{"anyOf":[{"type":"string"},{"type":"null"}]}}},"organisation":{"anyOf":[{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}},{"type":"null"}]},"usage":{"type":"object","required":["screens_this_month","cap","resets_at"],"properties":{"screens_this_month":{"type":"integer"},"cap":{"type":["integer","null"],"description":"Screens allowed this month: the default, or the person's own. null for an unlimited (testing) account."},"unlimited":{"type":"boolean","description":"true for a testing account with no cap; its screens are still counted."},"resets_at":{"type":"string","format":"date-time"},"batch":{"type":"object","description":"Batch lines, a separate allowance from screens.","properties":{"lines_this_month":{"type":"integer"},"cap":{"type":["integer","null"]},"unlimited":{"type":"boolean"}}}}},"mode":{"type":"string","description":"\"development\" on a local server with sign-in off."}}}},"securitySchemes":{"session":{"type":"apiKey","in":"cookie","name":"caliper_session","description":"The session cookie set by signing in at /auth/sign-in (invite-only)."}}},"paths":{"/healthz":{"get":{"summary":"Liveness","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}}}}}}}}},"/v1/meta":{"get":{"summary":"The engine release, data edition, date bounds, disclaimer and signing key","responses":{"200":{"description":"OK","headers":{"Screen-Engine":{"description":"The engine release tag, or its short commit until the first tag.","schema":{"type":"string"}},"Screen-Edition":{"description":"The HTS edition the engine reads.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Meta"}}}}}}},"/v1/signing-keys":{"get":{"summary":"The Ed25519 public keys that verify response signatures, retired ones included","responses":{"200":{"description":"OK","headers":{"Screen-Engine":{"description":"The engine release tag, or its short commit until the first tag.","schema":{"type":"string"}},"Screen-Edition":{"description":"The HTS edition the engine reads.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["keys"],"properties":{"keys":{"type":"array","items":{"type":"object","required":["key_id","alg","status","public_key_pem"],"properties":{"key_id":{"type":"string"},"alg":{"const":"Ed25519"},"status":{"enum":["current","retired","development"]},"public_key_pem":{"type":"string"}}}}}}}}}}}},"/v1/openapi.json":{"get":{"summary":"This document","responses":{"200":{"description":"OK","headers":{"Screen-Engine":{"description":"The engine release tag, or its short commit until the first tag.","schema":{"type":"string"}},"Screen-Edition":{"description":"The HTS edition the engine reads.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["openapi","paths"]}}}}}}},"/v1/me":{"get":{"summary":"Who is signed in, their organisation, and this month's screens","security":[{"session":[]}],"responses":{"200":{"description":"OK","headers":{"Screen-Engine":{"description":"The engine release tag, or its short commit until the first tag.","schema":{"type":"string"}},"Screen-Edition":{"description":"The HTS edition the engine reads.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/origins":{"get":{"summary":"The origins the engine holds; origin must be one of these values","security":[{"session":[]}],"responses":{"200":{"description":"OK","headers":{"Screen-Engine":{"description":"The engine release tag, or its short commit until the first tag.","schema":{"type":"string"}},"Screen-Edition":{"description":"The HTS edition the engine reads.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["origins"],"properties":{"origins":{"type":"array","items":{"type":"object","required":["v","label"],"properties":{"v":{"type":"string"},"label":{"type":"string"}}}}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/facts":{"get":{"summary":"The fact questions, keyed by fact id, with their answers and the note text they come from","security":[{"session":[]}],"responses":{"200":{"description":"OK","headers":{"Screen-Engine":{"description":"The engine release tag, or its short commit until the first tag.","schema":{"type":"string"}},"Screen-Edition":{"description":"The HTS edition the engine reads.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["facts"],"properties":{"facts":{"type":"object"}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/changelog":{"get":{"summary":"The engine changelog","security":[{"session":[]}],"responses":{"200":{"description":"OK","headers":{"Screen-Engine":{"description":"The engine release tag, or its short commit until the first tag.","schema":{"type":"string"}},"Screen-Edition":{"description":"The HTS edition the engine reads.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["format","text"],"properties":{"format":{"const":"markdown"},"text":{"type":"string"}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/screen":{"post":{"summary":"Screen one entry","description":"Runs the engine's screen() on one entry. Counts against the monthly allowance (50 per person during the pilot, unless the person has their own cap) before the engine runs; input the engine refuses is not counted.","security":[{"session":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional, 1–255 visible ASCII characters. A retry with the same key and body gets the identical signed response and is not counted again. Kept for 24 hours.","schema":{"type":"string","pattern":"^[\\x21-\\x7e]{1,255}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenRequest"}}}},"responses":{"200":{"description":"The screen, signed.","headers":{"Screen-Engine":{"description":"The engine release tag, or its short commit until the first tag.","schema":{"type":"string"}},"Screen-Edition":{"description":"The HTS edition the engine reads.","schema":{"type":"string"}},"Screen-Quota-Limit":{"description":"Screens this person may run per calendar month (UTC), or \"unlimited\" for a testing account.","schema":{"oneOf":[{"type":"integer"},{"const":"unlimited"}]}},"Screen-Quota-Remaining":{"description":"Screens left this month, or \"unlimited\".","schema":{"oneOf":[{"type":"integer"},{"const":"unlimited"}]}},"Screen-Quota-Used":{"description":"Screens counted this month, this one included.","schema":{"type":"integer"}},"Screen-Quota-Reset":{"description":"When the allowance resets.","schema":{"type":"string","format":"date-time"}},"Idempotent-Replayed":{"description":"\"true\" when this is the stored answer to a retried Idempotency-Key.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenResponse"}}}},"400":{"description":"Malformed JSON, or an invalid Idempotency-Key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"plan_cap_reached: this month's allowance is used up. Nothing was screened.","headers":{"Screen-Quota-Limit":{"description":"Screens this person may run per calendar month (UTC), or \"unlimited\" for a testing account.","schema":{"oneOf":[{"type":"integer"},{"const":"unlimited"}]}},"Screen-Quota-Remaining":{"description":"Screens left this month, or \"unlimited\".","schema":{"oneOf":[{"type":"integer"},{"const":"unlimited"}]}},"Screen-Quota-Used":{"description":"Screens counted this month, this one included.","schema":{"type":"integer"}},"Screen-Quota-Reset":{"description":"When the allowance resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_in_progress or idempotency_engine_changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The body is too large.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Send application/json.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The engine refused the input (e.g. unknown_origin, invalid_code, date_before_coverage), or idempotency_key_reused. Not counted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/batches/template.csv":{"get":{"summary":"The batch file template","security":[{"session":[]}],"responses":{"200":{"description":"A CSV with the columns and one example line.","content":{"text/csv":{"schema":{"type":"string"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/batches/check":{"post":{"summary":"Check a batch file","description":"Reads a CSV (comma or tab; a header row, or none: then reference, code, origin, entry_date) and checks every line the way POST /v1/screen does. Origins may be names in any case or ISO 3166-1 alpha-2 codes. Screens nothing and counts nothing; preview shows how the first lines were read.","security":[{"session":[]}],"parameters":[{"name":"date_order","in":"query","required":false,"schema":{"enum":["ymd","mdy"]},"description":"mdy: the file writes dates month/day/year (two-digit years are 20xx). Without it, only YYYY-MM-DD is read; a slashed date is refused, never guessed."},{"name":"programmes","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated programme ids from /v1/meta: screen every line for these only. Absent: every programme."}],"requestBody":{"required":true,"content":{"text/csv":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"The lines that can be screened, and the errors of those that cannot.","content":{"application/json":{"schema":{"type":"object","required":["lines_in_file","valid","errors","allowance"],"properties":{"lines_in_file":{"type":"integer"},"valid":{"type":"integer"},"errors":{"type":"array","items":{"$ref":"#/components/schemas/BatchLineError"}},"ignored_columns":{"type":"array","items":{"type":"string"},"description":"Header names the batch does not use; their cells are left out."},"allowance":{"type":"object"}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"batch_not_enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"csv_required: send text/csv.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The file cannot be read: missing_column, repeated_column, unknown_fact_column, unclosed_quote, too_many_lines, empty_file.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/batches/history":{"get":{"summary":"Saved batches (opt-in history)","security":[{"session":[]}],"description":"Whether batch history is available on this service, whether this person keeps it, the retention, and the saved batches (counts and dates; the name is decrypted for the owner only).","responses":{"200":{"description":"The history.","content":{"application/json":{"schema":{"type":"object","required":["available","keep","retention_days","batches"],"properties":{"available":{"type":"boolean"},"keep":{"type":"boolean"},"retention_days":{"type":"integer"},"batches":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete every saved batch","security":[{"session":[]}],"responses":{"200":{"description":"How many were deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"integer"}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"history_unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/batches/history/settings":{"put":{"summary":"Turn batch history on or off","security":[{"session":[]}],"description":"Opt-in (D7). Off by default. Turning it off can also delete what is saved (delete_existing: true).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["keep"],"properties":{"keep":{"type":"boolean"},"delete_existing":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The setting.","content":{"application/json":{"schema":{"type":"object","properties":{"keep":{"type":"boolean"},"deleted":{"type":"integer"},"retention_days":{"type":"integer"}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"invalid_request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"history_unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/batches/history/export":{"get":{"summary":"Export every saved batch","security":[{"session":[]}],"description":"Every saved batch: its signed responses (the batch and each re-run, as received) and the lines' current state. The page turns it into one CSV of all lines or a JSON file.","responses":{"200":{"description":"The export.","content":{"application/json":{"schema":{"type":"object","required":["exported_at","batches"],"properties":{"exported_at":{"type":"string","format":"date-time"},"retention_days":{"type":"integer"},"batches":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"history_unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/batches/history/{id}":{"get":{"summary":"One saved batch","security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Its signed responses and current state.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"history_unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete one saved batch","security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"How many were deleted (0 or 1).","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"integer"}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"history_unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/batches/rerun":{"post":{"summary":"Re-run batch lines with answers","description":"Lines of a batch sent back with answers to their open questions. Each line is sent as POST /v1/batches returned it (line, reference, input, expected_total, rerun_token) with answers: { question id: answer }, and is screened afresh with the answers added to its facts. A line re-run within 7 days of its batch, by the person who ran it, with its code, origin and date unchanged, is not counted again. Nothing is stored.","security":[{"session":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["lines"],"properties":{"lines":{"type":"array","items":{"type":"object","required":["line","input","rerun_token"],"properties":{"line":{"type":"integer"},"reference":{"type":["string","null"]},"input":{"type":"object"},"expected_total":{"type":["number","null"]},"answers":{"type":"object"},"rerun_token":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"The re-run lines, signed, each with a new rerun_token; and the lines refused (rerun_token_invalid, or an answer the question does not take).","content":{"application/json":{"schema":{"type":"object","required":["request_id","rerun_of","screened_at","engine","errors","lines","signature"],"properties":{"request_id":{"type":"string"},"rerun_of":{"type":["string","null"]},"screened_at":{"type":"string","format":"date-time"},"engine":{"type":"object"},"changelog_url":{"type":"string"},"errors":{"type":"array","items":{"$ref":"#/components/schemas/BatchLineError"}},"lines":{"type":"array","items":{"type":"object"}},"signature":{"type":"object"}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"batch_not_enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"invalid_request or too_many_lines.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/batches":{"post":{"summary":"Run a batch","description":"Screens every line of a CSV, each exactly as POST /v1/screen would (the engine's api/batch.js over screen()). Every line is checked first: a file with any line that cannot be screened is refused unless skip_invalid=true. Each screened line counts as one batch line, a separate allowance from screens. Synchronous; nothing is stored, so the response is the only copy.","security":[{"session":[]}],"parameters":[{"name":"name","in":"query","required":false,"schema":{"type":"string"},"description":"The file's name, kept with the batch when history is on."},{"name":"skip_invalid","in":"query","required":false,"schema":{"enum":["true","false"]},"description":"true: screen the lines that can be screened and report the others."},{"name":"date_order","in":"query","required":false,"schema":{"enum":["ymd","mdy"]},"description":"mdy: the file writes dates month/day/year (two-digit years are 20xx). Without it, only YYYY-MM-DD is read; a slashed date is refused, never guessed."},{"name":"programmes","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated programme ids from /v1/meta: screen every line for these only. Absent: every programme."}],"requestBody":{"required":true,"content":{"text/csv":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"The batch, signed: a summary, the lines not screened, and per line the screen response (less card_html and citations) with a summary row.","headers":{"Batch-Quota-Used":{"description":"Batch lines counted this month.","schema":{"type":"integer"}},"Batch-Quota-Limit":{"description":"Batch lines allowed this month, or \"unlimited\".","schema":{"type":"string"}},"Batch-Quota-Remaining":{"description":"Batch lines left, or \"unlimited\".","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["request_id","screened_at","engine","summary","errors","lines","signature"],"properties":{"request_id":{"type":"string"},"screened_at":{"type":"string","format":"date-time"},"engine":{"type":"object"},"changelog_url":{"type":"string"},"summary":{"type":"object"},"errors":{"type":"array","items":{"$ref":"#/components/schemas/BatchLineError"}},"lines":{"type":"array","items":{"type":"object","required":["line","result","summary"],"properties":{"line":{"type":"integer"},"reference":{"type":["string","null"]},"result":{"type":"object"},"summary":{"type":"object"}}}},"signature":{"type":"object"}}}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"batch_cap_reached: the batch is larger than the batch lines left this month. Nothing was screened.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"batch_not_enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"csv_required: send text/csv.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"batch_has_errors (with errors per line), no_lines, or a file that cannot be read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}