2026-08-08 22:36:41 +08:00
openapi : 3.0.3
info :
title : Phase 3 Customs Collaboration API
version : 1.0.0
description : Immutable checklist and file versions, supplement requests, frozen agent batches, receipts and history.
paths :
/api/platform/v1/customs/checklist-versions :
post :
summary : Create an immutable customs document checklist version
parameters : [ {$ref : '#/components/parameters/IdempotencyKey' }]
responses : {'200' : {description : Checklist version}}
/api/platform/v1/customs/cases :
get :
summary : Page customs cases
responses : {'200' : {description : Page result}}
post :
summary : Create a customer/order/inbound/container scoped customs case
parameters : [ {$ref : '#/components/parameters/IdempotencyKey' }]
responses : {'200' : {description : Customs case detail}}
/api/platform/v1/customs/cases/{caseId}:
parameters : [ {$ref : '#/components/parameters/CaseId' }]
get :
summary : Query complete customs detail and stable history
responses : {'200' : {description : Detail}}
/api/platform/v1/customs/cases/{caseId}/documents:
parameters : [ {$ref : '#/components/parameters/CaseId' }, {$ref : '#/components/parameters/IdempotencyKey' }]
post :
summary : Reference a file validated against customer, CUSTOMS_DOCUMENT and case ID
responses : {'200' : {description : New document version}}
/api/platform/v1/customs/cases/{caseId}/documents/upload:
parameters : [ {$ref : '#/components/parameters/CaseId' }, {$ref : '#/components/parameters/IdempotencyKey' }]
post :
summary : Upload a document and create a new immutable version
requestBody :
required : true
content :
multipart/form-data :
schema :
type : object
required : [ itemCode, expectedVersion, file]
properties :
itemCode : {type : string}
expectedVersion : {type : integer, minimum : 0 }
file : {type : string, format : binary}
responses : {'200' : {description : New document version}}
/api/platform/v1/customs/cases/{caseId}/documents/{documentId}/review:
parameters :
- {$ref : '#/components/parameters/CaseId' }
- {name : documentId, in : path, required : true, schema : {type : string, pattern : '^[1-9][0-9]*$' }}
- {$ref : '#/components/parameters/IdempotencyKey' }
post :
summary : Approve a current file version or return it with a supplement task
responses : {'200' : {description : Updated detail}}
/api/platform/v1/customs/cases/{caseId}/submission-batches:
parameters : [ {$ref : '#/components/parameters/CaseId' }, {$ref : '#/components/parameters/IdempotencyKey' }]
post :
summary : Submit to customs agent and freeze approved file versions in a batch snapshot
2026-08-15 10:35:54 +08:00
description : customsAgentId must identify an ACTIVE Warehouse supplier in category CUSTOMS; the persisted agent name is resolved server-side and free text cannot bypass supplier validation.
requestBody : {required : true, content : {application/json : {schema : {$ref : '#/components/schemas/SubmitBatchRequest' }}}}
2026-08-15 11:12:19 +08:00
responses :
'200' :
description : Submission batch
content :
application/json :
schema : {$ref : '#/components/schemas/CustomsSubmissionBatch' }
2026-08-08 22:36:41 +08:00
/api/platform/v1/customs/submission-batches/{batchId}/receipts:
parameters :
- {name : batchId, in : path, required : true, schema : {type : string, pattern : '^[1-9][0-9]*$' }}
- {$ref : '#/components/parameters/IdempotencyKey' }
post :
summary : Reference a customer-owned receipt file with explicit visibility
responses : {'200' : {description : Receipt version}}
/api/platform/v1/customs/submission-batches/{batchId}/receipts/upload:
post :
summary : Upload a receipt version; RELEASED closes the customs dispatch gate
responses : {'200' : {description : Receipt version}}
/api/merchant/v1/customs/orders/{orderId}:
get :
summary : Query the authenticated customer's customs case by order
responses : {'200' : {description : Customer-filtered detail}}
/api/merchant/v1/customs/cases/{caseId}/documents/upload:
post :
summary : Upload or replace a checklist document within authenticated customer scope
responses : {'200' : {description : New document version}}
/api/merchant/v1/customs/cases/{caseId}/receipts/{receiptId}/download:
get :
summary : Download only CUSTOMER-visible receipts from the authenticated customer's case
responses : {'200' : {description : Authorized file stream}}
components :
parameters :
IdempotencyKey :
name : Idempotency-Key
in : header
required : true
schema : {type : string, minLength : 1, maxLength : 128 }
CaseId :
name : caseId
in : path
required : true
schema : {type : string, pattern : '^[1-9][0-9]*$' }
2026-08-15 10:35:54 +08:00
schemas :
SubmitBatchRequest :
type : object
required : [ customsAgentId, expectedVersion]
properties :
customsAgentId : {type : integer, format : int64, minimum : 1, description : ACTIVE Warehouse supplier ID validated as CUSTOMS.}
customsAgentName : {type : string, maxLength : 128, nullable : true, description : Optional consistency hint; persisted name always comes from Warehouse.}
externalReference : {type : string, maxLength : 128, nullable : true }
note : {type : string, maxLength : 500, nullable : true }
expectedVersion : {type : integer, minimum : 0 }
2026-08-15 11:12:19 +08:00
CustomsSubmissionBatch :
type : object
required : [ id, customsCaseId, batchNo, batchVersion, customsAgentName, status, submittedBy, submittedAt]
properties :
id : {type : string, pattern : '^[1-9][0-9]*$' }
customsCaseId : {type : string, pattern : '^[1-9][0-9]*$' }
batchNo : {type : string, maxLength : 40 }
batchVersion : {type : integer, minimum : 1 }
customsAgentId : {type : string, pattern : '^[1-9][0-9]*$', nullable : true, description : Server-validated CUSTOMS supplier ID snapshot; null only for non-migrated historical rows.}
customsAgentName : {type : string, maxLength : 128, description : Server-frozen Warehouse supplier name snapshot.}
externalReference : {type : string, maxLength : 128, nullable : true }
fileSnapshotJson : {type : string}
status : {type : string, enum : [ SUBMITTED, ACKNOWLEDGED, REJECTED, COMPLETED]}
note : {type : string, maxLength : 500, nullable : true }
submittedBy : {type : string, pattern : '^[1-9][0-9]*$' }
submittedByName : {type : string, maxLength : 64, nullable : true }
submittedAt : {type : string, format : date-time}