Skip to content

Open specification questions

Where the ONE Record specification is ambiguous or inconsistent, this page records the question, where it appears, what NE:ONE does, and what this package chose. Entries are added as they are met; none is removed, only resolved.

# Question Where NE:ONE Our choice
1 PATCH /logistics-objects/{id} success status: the 2.2 status table says 201 Created, its examples show 204 No Content. API 2.2 Update a Logistics Object; fixed to 201 in 2.3 201 201 with Location and Type
2 Denied access to a logistics object: 403 Forbidden per the access-control page, but 403 confirms the object exists. Access control, Get a Logistics Object 403 403 by default; an AccessPolicy may answer hide, which yields 404. Filed as IATA-Cargo/ONE-Record#457
3 Embedded-object identifiers: the spec recommends internal:<uuid5> but leaves the scheme to the implementor. Implementation guidelines, blank nodes neone:<n> internal:<uuid5>; the RDF comparer treats both prefixes as blank nodes. IATA-Cargo/ONE-Record#444 confirms embedded nodes must carry an @id. An id a client chose for an embedded node (https:, urn:, neone:) is replaced by the server-minted one when the object is stored; the client learns it from the next read
4 Changing embedded objects: new embedded objects are blank nodes in operations, existing ones are addressed by embedded id. Update a Logistics Object examples C2–C4 Supported Implemented as specified; earlier Lambda Twelve code refused such changes. worked through in IATA-Cargo/ONE-Record#355 (example C4 now uses the internal id)
5 Numeric literal forms: 20.0, "20.0"^^xsd:double and 2.0E1 are the same RDF value with different lexical forms. JSON-LD/RDF Stores lexical form as received Comparison normalises by datatype; storage keeps the lexical form as received
6 ?at= and audit-trail timestamps use YYYYMMDDThhmmssZ while bodies use RFC 3339. Retrieve a historical Logistics Object Basic ISO format Accept both forms on input; emit the spec's basic format in links
7 The audit-trail example uses api:REQUEST_STATUS_ACCEPTED, which does not exist in the ontology. Get Audit Trail example D1 api:REQUEST_ACCEPTED Ontology names (api:REQUEST_ACCEPTED)
8 hasSupportedOntology must be unversioned IRIs per the guidelines, but the server-information example lists versioned ones. Server information example A1 vs Versioning Versioned Unversioned in hasSupportedOntology, versioned in hasSupportedOntologyVersion. open as IATA-Cargo/ONE-Record#403; IATA leans towards dropping the split and keeping versioned IRIs in hasSupportedOntology. Our comment states what we emit and asks for a deprecation rather than a removal
9 Access delegation isRequestedFor: a list in 2.2, exactly one organisation in 2.3; yet the 2.3 example still writes a one-element list. Access delegations, example List Read as list or single value at either version; written as a list, as both editions' examples do
10 Content-Type version parameter: the spec requires echoing the negotiated version; NE:ONE ignores the parameter and answers ;charset=UTF-8. Versioning Ignores Echo the negotiated version; accept partners that do not
11 Data-model mapping questions for forwarders: unit IRIs (code-lists/MeasurementUnitCode#KGM vs UN/CEFACT), currency IRIs on the open CurrencyCode list, countries and airports as CodeListElement, party placement (shipment vs waybill), booking reference (shippingRefNo vs Booking), pieces vs piece groups. Data model 3.2/3.3 n/a Left to the mapping layer in wrappers; the SDK supports every form
12 IATA's release tags (2025-07, 2026-07) carry release-candidate ontologies (3.2-rc2, 3.3.0 RC1); the <edition>-standard folders were corrected on master after tagging. Repository tags vs master Builds from its own copy Ontologies pinned to master commit ad5f40d5… (versionInfo 3.2 / 3.3.0); specification text and examples pinned to the tags. Filed as IATA-Cargo/ONE-Record#458
13 Several published example documents are defective: AuditTrail*.json (2025-07) are not JSON (placeholder text), AuditTrail*.json (2026-07) carry a _comment key, Piece_with_id*.json and Shipment_with_Piece.embedded.json have a leading space in @id, ChangeRequest_with_error.json (2025-07) writes api#errors for api:hasError, Subscriptions_example2.json types the object with a bare Subscription and no @vocab, VerificationRequest.json uses xsd:anyURI without declaring xsd. A general JSON-LD processor silently drops most of these; this package rejects them. Documentation_website/docs/API-Security/examples/ at both tags n/a Listed as known defects in tests/Unit/JsonLd/SpecExamplesTest.php so an upstream fix is noticed; every other example round-trips. Worth reporting to IATA.. the AuditTrail and ChangeRequest examples were reported as IATA-Cargo/ONE-Record#423 (one fixed, the two placeholders still open)
14 What api:hasRevision on a Change means: the ontology says "starting with 0 for changing the initial revision", the examples carry the current revision of the object. API ontology api:hasRevision; Update a Logistics Object examples C1–C5 Requires it to equal the object's current revision; the result is revision + 1 Same as NE:ONE. IATA-Cargo/ONE-Record#325 settled that objects start at revision 1, which supports the examples' reading
15 Adding a value that is already present, or deleting one that is absent, is not specified. Update a Logistics Object Rejects the change Rejected with code 422 on the ChangeRequest, so a stale diff cannot be half-applied silently
16 Who may PATCH /logistics-objects/{id}: the endpoint table lists no permission, the permission model names PATCH_LOGISTICS_OBJECT. Update a Logistics Object vs Access control Requires the permission The permission is required; a change request from an unknown party would otherwise be a free write queue
17 GET /subscriptions?topicType&topic answers one api:Subscription; what if the host has several interests (with and without the body, say)? Get Subscription information as Publisher One One offer is answered as an api:Subscription; none or several as an api:Collection of subscriptions
18 The response to an illegal action-request transition: 2.3 specifies 422 for a revocation that is not possible; 2.2 says nothing, and the same question arises for PATCH ?status= on a final request. Action requests 400 422 at 2.3.0, 400 at 2.2.0, for every impossible transition. IATA-Cargo/ONE-Record#373 proposes 422 for DELETE in a non-revocable state, matching this choice
19 Visibility of action requests: the spec says the requestor and the holder may read one; nothing about the delegate of an access delegation or the subscriber of a subscription set up by the holder. Action requests Requestor and holder Parties a request is about may read it too; anyone else is answered 404 so existence is not leaked
20 api:hasChangedProperty in an update notification when the change edited an embedded node (a cargo:Value inside grossWeight). Notifications Operation predicates The object's own property the embedded node hangs off (cargo:grossWeight), so a subscriber can act on it. Filed as IATA-Cargo/ONE-Record#453
21 NE:ONE lists every superclass in @type (a Piece is also PhysicalLogisticsObject and LogisticsObject); the spec's examples declare the one class. Logistics objects examples; NE:ONE changelog #248 Adds superclasses Declared classes are kept as given; comparisons use the most specific classes; ChangeBuilder never emits type operations, so a diff against a NE:ONE object does not try to delete inferred types. resolved by IATA-Cargo/ONE-Record#331 (approved 2026-06-08): @type may list the superclasses, the Type header carries only the most specific class
22 Which properties a server sets on a received logistics event: NE:ONE writes cargo:creationDate, cargo:eventFor and cargo:recordingOrganization itself. Logistics events Sets all three eventFor is implied by the path and written on read; creationDate is kept as posted (the server's receipt time is created on the model); recordingOrganization is the poster's business, not the server's
23 Whether PATCH /action-requests/{id}?status= takes effect within the request. NE:ONE answers 204 and applies the decision on its evaluation timer, so a GET right after may still say pending. Action requests Asynchronous Applied within the request; clients of other servers should poll, which the interop suite does
24 Response bodies as flattened JSON-LD: NE:ONE answers with a top-level @graph whenever an object has embedded nodes, and @vocab for the cargo namespace. The spec's examples are nested. JSON-LD examples; NE:ONE jsonld.mode Flattened Nested bodies written; a top-level @graph accepted on read and rooted at the object asked for
25 Does an accepted subscription with sendLogisticsObjectBody keep authorising disclosure of the body after the subscriber's read permission is revoked? The access-control and subscription sections each define their own grant and say nothing about the interaction. Access Control, Subscriptions Sends the body while the subscription is accepted Settled. IATA (2026-10-05): the notification is subject to the access policy and the body is shared only with a recipient that has access to the object; a clarifying sentence will be added. Our behaviour already matches: the access policy is consulted per recipient at fan-out time; without read permission the notification carries the URI only, under a hiding policy nothing is sent. A host that wants push authorisation independent of read access must say so in its policy. Filed as IATA-Cargo/ONE-Record#454
26 Does api:isTriggeredBy on a notification name the event's cause (the ChangeRequest) or the subscription the recipient can revoke (the SubscriptionRequest)? The unsubscribe text wants a revocable locator; the model says ActionRequest. Notifications, Subscriptions: Unsubscribe ChangeRequest for updates Open. Interim: updates name the change request, creations and events name the subscription request; a subscriber may not be able to read the change request it is pointed at (question 19). raised from the other side in IATA-Cargo/ONE-Record#401, which also wants isTriggeredBy to be the revocable locator. Our comment asks whether isTriggeredBy is the cause or the subscription
27 Which JSON-LD representations must every ONE Record implementation accept: only the nested shape of the examples, flattened @graph (NE:ONE), expanded arrays, @set, scoped contexts? No normative profile exists. JSON-LD examples; JSON-LD 1.1 Flattened Open. This package reads nested documents and a top-level @graph, writes nested, and refuses the rest with a precise error (subset). Filed as IATA-Cargo/ONE-Record#451. IATA's answer (2026-10-05): JSON-LD 1.1 at the specification level, while every implementation they have seen uses the two shapes we accept, nested compacted and flattened @graph; a written profile was suggested again; IATA's current reading is full JSON-LD 1.1 and the question goes to the working group. We keep the documented subset and refuse other serialisations with an explicit error until there is a ruling
28 What identifies a notification across retries, and what must a receiver deduplicate on? The model has no notification id and the delivery text no retry rule. Notifications None Open. Interim: an Idempotency-Key header carrying the sender's outbox id; receivers see it on NotificationReceived. Filed as IATA-Cargo/ONE-Record#452. IATA's answer (2026-10-05): the receiver stores the notification under its own id and duplicates are considered harmless; after the lost-response case was laid out, the proposed rule (one delivery identifier for every attempt of the same notification) was put on IATA's backlog for the working group
29 How are language-tagged strings and non-XSD datatypes represented in an api:Operation? api:hasDatatype names one IRI and api:hasValue one string; there is no place for a language tag. API ontology OperationObject Writes xsd:string Open. This package refuses to build a change for a language-tagged literal rather than drop the tag silently. Filed as IATA-Cargo/ONE-Record#456 (labelled enhancement, api by IATA on 2026-10-05: taken as a change to the API rather than a clarification)
30 Who may revoke a SubscriptionRequest a third party created? The subscriptions section tells the subscriber to revoke its request to unsubscribe; the action-request section restricts revocation to the requestor and the holder. Subscriptions with 3rd parties, Action Requests: using Requestor and holder IATA (2026-10-05) agrees the point is worth raising: whether the subscriber may revoke when it differs from the creator is to be put to the working group. Interim: the subscriber of a SubscriptionRequest may revoke it, as the only direct way to stop notifications it never asked for; delegates of a shared AccessDelegationRequest get no such right (question 19, AR-028). adjacent to IATA-Cargo/ONE-Record#381 (role wording), #401 and #449 (the subscriber learns the request's location only from isTriggeredBy). Filed as IATA-Cargo/ONE-Record#455
31 Does a subscription on a type (topicType TYPE) match objects of its subclasses, or only objects that list that class in @type? The spec does not say; a holder that writes only the most specific class and a subscriber asking for cargo:Shipment disagree silently when the object is a subclass. Subscriptions; IATA-Cargo/ONE-Record#412 Declared types only Declared @type values only, IATA's current reading in #412. Holders that want hierarchy matching list the superclasses in @type (question 21 allows it). Our comment records the declared-types reading and the access-first fan-out
32 A status-change notification for an AccessDelegationRequest over several objects: api:hasLogisticsObject is at most one. Which, if any? API ontology Notification; IATA-Cargo/ONE-Record#437 First object None when the request concerns more than one object; the request in isTriggeredBy lists them all. IATA considers raising the cardinality. Our comment describes this choice and two workable shapes
33 A POST body may nest a logistics object inside another (example A2 posts a Company with a Person): the text says logistics objects are never embedded, and IATA says a server should recognise the nested object and give it a URI of its own (IATA-Cargo/ONE-Record#444). Create a Logistics Object example A2; IATA-Cargo/ONE-Record#444 Keeps it embedded Interim: creation over HTTP accepts the nested object and keeps it embedded with an internal id, as before; a change or an event may not introduce one, and a change to anything else leaves it in place. Splitting a nested logistics object into an object of its own is not implemented
34 A client may give an embedded object an @id of its own (https:, urn:, NE:ONE's neone:). The spec says embedded objects get server-assigned ids (internal: recommended) but not what a server does with a client-supplied one: keep it, replace it, or refuse the document. Implementation guidelines, embedded objects; Create a Logistics Object; IATA-Cargo/ONE-Record#459 Keeps the id as given Replaces it with a server-minted internal: id when the object is first stored, since the id is addressable afterwards and must be stable and the server's own; the client learns it from the next read. Asked in IATA-Cargo/ONE-Record#459
35 A node that states only @id and @type ({"@id": "…/piece-2", "@type": "cargo:Piece"}) is not defined: a typed reference to another object, or an embedded object with no properties yet? The examples use both bare {"@id"} references and embedded objects with properties, never this shape. Data model embedded vs. referenced objects; Create a Logistics Object examples; IATA-Cargo/ONE-Record#460 Stores what it is given A reference whatever its class: the class must exist (data model class or code list) and fit the property's range, the node keeps its id, and a change cannot describe it in place. Asked in IATA-Cargo/ONE-Record#460