Partner Capacity Exchange Protocol
Generated from
PROTOCOL.md. Edit the canonical source file, not this page.
Working name: OpenFreytProtocol / PCX
Status: Pre-alpha design, not an implementation contract
Language: Protocol names and schemas use English
1. Protocol objective
Section titled “1. Protocol objective”PCX provides the smallest interoperable contract required for mutually accepted logistics partners to discover compatible capacity and demand, tender transport work, create explicit commitments, transfer a bounded execution package and prove the operational outcome.
It is a full private exchange protocol, not a universal transport model. It deliberately avoids copying complete vendor-native orders, shipments, rides, routes, invoices, vehicles, customers or contracts. Connected systems retain their local records and link them through protocol identifiers and namespaced external references.
The normative execution-transfer behavior is defined by specification/private-exchange-profile.md.
2. Normative technology profile
Section titled “2. Normative technology profile”| Layer | Choice |
|---|---|
| Encoding | UTF-8 JSON |
| Payload semantics | JSON Schema 2020-12 |
| Synchronous transport | HTTPS using OpenAPI 3.1 |
| Event envelope | CloudEvents 1.x |
| Event channel description | AsyncAPI, optional |
| Authentication | OAuth 2.0 Client Credentials; OIDC for interactive users where applicable |
| Error payloads | RFC 9457 Problem Details |
| Time | RFC 3339 UTC timestamps; IANA time-zone identifier when local-time interpretation matters |
| Geometry | GeoJSON RFC 7946 |
| Countries | ISO 3166-1 alpha-2 |
| Currency | ISO 4217 |
| Locations | UN/LOCODE where available |
| Units | UNECE Recommendation 20/21 codes |
| Resource IDs | UUIDv7 preferred; opaque to consumers |
JSON Schema is the source of truth for shared payload structures. OpenAPI is normative for HTTP paths, authorization, status codes and headers, and references the schemas rather than redefining them.
3. Core invariants
Section titled “3. Core invariants”- Every resource belongs to exactly one owning organization.
- Visibility requires an active bilateral
PartnerRelationshipand matching scope. - An offer or request is not a legal or operational commitment.
- A proposal is explainable and non-binding.
- An award or commitment requires explicit authorized acceptance according to the configured decision policy.
- Retried commands are idempotent.
- Events can be delivered more than once; consumers deduplicate by event ID.
- Resources carry a monotonically increasing
resourceVersion. - State-changing events preserve causal order per resource.
- Historical decisions and execution outcomes cannot be silently overwritten.
- Exact addresses and customer identity are not required before acceptance.
- The public contract does not contain Freyt-specific identifiers or implementation details.
- Commercial acceptance and technical handover acknowledgement are separate facts.
- Duplicate handover delivery cannot create duplicate destination work.
- Accepted decision-relevant terms cannot change without a linked revision and required renewed acceptance.
- Payload fields cannot override the authenticated connector’s organization binding.
- Connected systems retain their local records; the exchange transfers only the bounded canonical execution package.
4. Common envelope
Section titled “4. Common envelope”Every resource includes:
{ "id": "0195d8d2-18c7-7b18-9b4e-06d26469c821", "resourceVersion": 1, "ownerOrganizationId": "org_carrier_a", "createdAt": "2026-09-15T08:00:00Z", "updatedAt": "2026-09-15T08:00:00Z", "externalReferences": [ { "system": "carrier-a-tms", "type": "trip", "value": "TRIP-4812" } ]}External references are namespaced and never treated as globally unique without system and type.
5. Resources
Section titled “5. Resources”5.1 PartnerRelationship
Section titled “5.1 PartnerRelationship”Represents bilateral authorization between two organizations.
Minimum fields:
idrequestingOrganizationIdacceptingOrganizationIdstatus:pending | active | suspended | terminatedscopes: allowed resource/action combinationsvisibilityPolicyeffectiveFromeffectiveUntil, optionalretentionPolicyRef, optional
A relationship becomes active only after authorized acceptance. Termination stops future sharing but does not erase required audit history.
5.2 CapacityOffer
Section titled “5.2 CapacityOffer”Represents available vehicle or trip capacity.
Minimum fields:
- common envelope;
status:draft | published | partiallyMatched | matched | withdrawn | expired | cancelled;availabilityWindow;originArea;destinationArea;direction, optional when areas imply direction;vehicleProfile;availableCapacity;constraints;maximumDetour, optional;expiresAt;visibility: explicit partner IDs or a relationship-defined group.
Capacity dimensions are explicit and independently optional:
{ "availableCapacity": { "weight": { "value": 12000, "unitCode": "KGM" }, "volume": { "value": 32, "unitCode": "MTQ" }, "loadingMetres": { "value": 7.2, "unitCode": "MTR" }, "palletSpaces": 18 }}A consumer must not infer an unspecified dimension.
5.3 LoadRequest
Section titled “5.3 LoadRequest”Represents demand for transport capacity, not a complete commercial order.
Minimum fields:
- common envelope;
status:draft | published | proposed | matched | withdrawn | expired | cancelled;pickupAreaandpickupWindow;deliveryAreaanddeliveryWindow;requiredCapacity;vehicleRequirements;handlingRequirements, optional;goodsProfilewith coarse, non-sensitive classification;expiresAt;visibility.
Customer identity, exact address, price and complete goods details are excluded unless policy explicitly permits disclosure.
5.4 MatchProposal
Section titled “5.4 MatchProposal”An immutable proposal connecting one compatible offer and request. A newer proposal supersedes rather than mutates an accepted rationale.
Minimum fields:
capacityOfferIdand observed version;loadRequestIdand observed version;status:open | accepted | rejected | expired | superseded | withdrawn;validUntil;compatibilityresults;routeCompatibility, including structured distance or detour estimates when available;capacityCompatibility, including the dimensions used for comparison;rationaleas structured reason codes plus human-readable summary;requiredDecisionPolicy;createdBy: broker, participant or authorized planner.
The proposal must never disclose protected fields merely because the broker found a potential match.
5.5 MatchDecision
Section titled “5.5 MatchDecision”An append-only decision made by an authorized organization.
Minimum fields:
proposalId;organizationId;decision:accept | reject | withdraw;decidedAt;decidedByas actor reference;reasonCode, optional;comment, optional and access-controlled;observedProposalVersion.
The decision policy defines whether both organizations must accept and which role may decide. A stale version returns a conflict; the server does not silently apply the decision to a changed proposal.
5.6 TransportTender
Section titled “5.6 TransportTender”A versioned request for a selected partner to execute a bounded transport movement. It freezes the decision-relevant terms shown to the recipient and references the originating proposal where applicable.
Minimum fields:
- issuing and intended executing organizations;
- movement scope:
fullTransport | routeLeg | collection | delivery; - expiry and required decision policy;
- cargo, equipment, stop and time-window requirements allowed at the current disclosure phase;
- commercial terms or a stable external terms reference;
- amendment and cancellation policy;
- source external references.
A counterproposal creates a new immutable revision. It never silently modifies terms already presented for decision.
5.7 TransportCommitment
Section titled “5.7 TransportCommitment”Immutable proof that every decision required by the tender policy was accepted before expiry or valid withdrawal.
Minimum fields:
- accepted tender revision;
- required decisions and actors;
- acceptance timestamps;
- deterministic digest of the accepted decision-relevant payload;
- relationship-policy version;
- resulting capacity reservation or consumption.
A commitment proves agreement. It does not prove that the executing system imported the work.
5.8 ExecutionHandover
Section titled “5.8 ExecutionHandover”A disclosure-controlled operational package containing only the stops, time windows, cargo facts, equipment constraints, references, instructions, documents and contact details required to execute the committed movement.
The source and executing systems retain their own local records. The handover links them through the commitment identifier and namespaced external references.
5.9 HandoverAcknowledgement
Section titled “5.9 HandoverAcknowledgement”Records whether the executing connector imported, linked, rejected or quarantined the handover. Successful acknowledgements include the destination external reference. Duplicate delivery must resolve to the same local record and acknowledgement.
Commercial acceptance and technical handover acknowledgement are separate transitions.
5.10 ExecutionReference
Section titled “5.10 ExecutionReference”Links a commitment and handover to local execution records without copying a complete connected-system object.
Minimum fields:
- commitment and handover references;
- participating organization references;
- source and destination external references;
- execution status;
- planned and actual time range;
- cancellation or exception reason where applicable.
5.11 ExecutionUpdate
Section titled “5.11 ExecutionUpdate”Communicates shared milestones and exceptions without replacing either participant’s detailed local state. Baseline milestones are assigned | atPickup | pickedUp | inTransit | delayed | atDelivery | delivered | failed | cancelled | disputed.
5.12 ExecutionOutcome
Section titled “5.12 ExecutionOutcome”Records whether and how a commitment was executed without copying the participants’ complete operational records.
Minimum fields:
- commitment, handover and execution reference;
status:planned | inProgress | completed | cancelled | failed | disputed;- planned and actual time range;
- participant confirmations;
- external execution references;
- operational deviations or exception reason, where applicable;
- optional capacity-utilization and route observations;
- deduplication key;
- correction/supersession reference.
Execution outcomes are append-only. A correction points to the superseded record and includes a reason.
6. Lifecycle and commands
Section titled “6. Lifecycle and commands”Prefer intent-revealing commands over arbitrary resource patching:
POST /partner-relationshipsPOST /partner-relationships/{id}/acceptPOST /partner-relationships/{id}/suspend
POST /capacity-offersPOST /capacity-offers/{id}/publishPOST /capacity-offers/{id}/withdraw
POST /load-requestsPOST /load-requests/{id}/publishPOST /load-requests/{id}/withdraw
GET /match-proposalsPOST /match-proposals/{id}/decisions
POST /transport-tendersPOST /transport-tenders/{id}/issuePOST /transport-tenders/{id}/decisionsPOST /transport-tenders/{id}/counterproposalsPOST /transport-tenders/{id}/withdrawPOST /transport-commitments/{id}/amendmentsPOST /transport-commitments/{id}/cancel
POST /execution-handoversPOST /execution-handovers/{id}/acknowledgementsPOST /execution-referencesPOST /execution-updatesPOST /execution-outcomesPOST /execution-outcomes/{id}/correctionsThe exact endpoint set remains to be specified in OpenAPI. Generic PATCH should be limited to non-decision draft data because it obscures lifecycle semantics and audit intent.
7. Idempotency and concurrency
Section titled “7. Idempotency and concurrency”- Every create or command operation accepts
Idempotency-Keyscoped to the authenticated organization and operation. - The same key and identical payload returns the original outcome.
- The same key with a different payload returns
409 Conflict. - State-changing commands include
If-Matchor an explicit observedresourceVersion. - Stale writes return
409 Conflictor412 Precondition Failedwith an RFC 9457 body. - Idempotency records must outlive the maximum client retry window.
8. Events
Section titled “8. Events”Example event types:
pcx.partner-relationship.activated.v1pcx.capacity-offer.published.v1pcx.capacity-offer.withdrawn.v1pcx.load-request.published.v1pcx.load-request.withdrawn.v1pcx.match-proposal.created.v1pcx.match-decision.recorded.v1pcx.match-proposal.accepted.v1pcx.transport-tender.issued.v1pcx.transport-tender.countered.v1pcx.transport-commitment.created.v1pcx.transport-commitment.amended.v1pcx.transport-commitment.cancelled.v1pcx.execution-handover.offered.v1pcx.execution-handover.acknowledged.v1pcx.execution.updated.v1pcx.execution.completed.v1pcx.execution-outcome.recorded.v1pcx.execution-outcome.corrected.v1CloudEvent requirements:
- globally unique
id; sourceidentifies the broker/producer;subjectidentifies the resource;typeuses the versioned event name;timeuses RFC 3339;dataschemapoints to an immutable schema version;- extension attributes include
organizationid,resourceversion,correlationidand, where applicable,causationid.
Delivery is at least once. Consumers must deduplicate and ignore an event with an older or equal applied resource version. Sensitive payload projection is audience-specific.
9. Authorization and privacy
Section titled “9. Authorization and privacy”Authorization evaluates:
- token validity and broker audience;
- active connector or interactive user registration;
- active organization;
- resource ownership or participation;
- active partner relationship;
- granted client scope;
- bilateral relationship policy;
- resource visibility policy;
- field disclosure phase;
- actor role for decisions;
- lifecycle preconditions;
- resource version and expiry.
API scope, bilateral policy and resource visibility are independent gates. Passing one does not bypass another. Connector credentials are bound to exactly one organization and environment; payload fields cannot override that binding.
Machine connectors use OAuth 2.0 Client Credentials and should use private_key_jwt or mutual TLS in production. Interactive users use OIDC Authorization Code with PKCE. Internal connected-system session tokens are not portable exchange credentials unless an explicit federation or token-exchange profile validates their issuer, audience, organization and actor semantics.
Recommended scopes:
relationships:managecapacity:publishcapacity:readloads:publishloads:readmatches:readmatches:decidetenders:publishtenders:readtenders:decidecommitments:readhandovers:writehandovers:readhandovers:acknowledgeexecution:updateoutcomes:writeoutcomes:reviewconnectors:manageA 404 may be preferable to 403 when revealing resource existence would leak partner activity. Broker logs must redact exact locations, customer identity and goods details by default.
10. Error model
Section titled “10. Error model”Errors use RFC 9457 and stable protocol codes:
{ "type": "https://openfreytprotocol.example/problems/stale-resource-version", "title": "Stale resource version", "status": 409, "code": "STALE_RESOURCE_VERSION", "detail": "The proposal changed after it was read.", "correlationId": "corr_019..."}Initial codes should cover validation, authentication, authorization, hidden resource, inactive relationship, stale version, idempotency conflict, invalid transition, expired resource and incompatible decision policy.
11. Versioning
Section titled “11. Versioning”- Protocol releases use semantic versioning.
- JSON schemas have immutable versioned identifiers.
- Additive optional fields and new event types are minor changes.
- Changed meaning, removed fields or stricter existing validation require a major version.
- Consumers ignore unknown optional fields but never unknown enum values in decision-critical fields unless the schema explicitly provides an
otherextension mechanism. - During the pilot, prefer additive evolution and publish deprecation windows.
- Every proposal and execution outcome stores the schema version used.
12. Extensions
Section titled “12. Extensions”Extensions are namespaced:
{ "extensions": { "com.example.carrier.temperatureClass": "chilled" }}An extension cannot change core semantics, authorization or lifecycle behaviour. If multiple participants need the same extension, promote it through protocol governance after conformance examples exist.
13. Conformance
Section titled “13. Conformance”A conformant implementation must pass tests for:
- JSON Schema validation;
- lifecycle transitions;
- idempotent retries;
- stale-write rejection;
- bilateral visibility isolation;
- field-level disclosure;
- duplicate and out-of-order events;
- proposal expiry and withdrawal;
- explicit decision policy;
- execution-outcome deduplication and correction history;
- RFC 9457 error responses.
Conformance profiles:
- Publisher: capacity offers and/or load requests;
- Consumer: discovers and decides;
- Broker: authorization, matching, lifecycle and events;
- Outcome provider: submits execution status and references;
- Full reference client: implements publisher, consumer and evidence flows.
14. Adapter strategy
Section titled “14. Adapter strategy”Adapters map external formats at the edge:
External TMS/EDI/UBL/EPCIS ↓ Adapter layer ↓ PCX contract ↓ Reference brokerRules:
- do not expose adapter-specific fields in core schemas without a cross-participant use case;
- preserve source and destination external references for traceability;
- bind connector processing to the authenticated organization, never to an inbound tenant field;
- document lossy mappings;
- quarantine invalid, ambiguous or unsafe inbound messages;
- include adapter and supported-profile versions in diagnostics;
- do not silently invent required values;
- process commands and events idempotently with durable inbox, outbox and mapping state;
- reconcile authoritative resources after missed delivery or downtime;
- expose health, lag, dead letters and mapping failures;
- test tenant/organization isolation independently for every adapter;
- avoid direct writes to a connected system’s internal database unless it documents that interface as supported.
15. Items requiring validation before v0.1
Section titled “15. Items requiring validation before v0.1”- canonical execution handover schema and movement boundaries;
- tender counterproposal, amendment and cancellation semantics;
- OAuth/OIDC client authentication, claims, rotation and revocation profile;
- organization verification and connector registration model;
- event signing, replay resistance and reconciliation profile;
- exact vehicle/body-type vocabulary;
- area representation: circle, polygon, administrative region or combinations;
- recurrence model for fixed corridors;
- bilateral decision policy and commitment semantics;
- retention and withdrawal rules;
- webhook signing method;
- legal organization identifier strategy;
- price inclusion or complete exclusion;
- dangerous goods and temperature-control minimum fields;
- kilometer baseline calculation specification;
- license, trademark and governance owner.