openapi: 3.2.0 info: title: Phasio Shipments API description: This is the API documentation for the Phasio application. version: '1.0' servers: - url: https://m-api.eu.phas.io description: Generated server url security: - Phasio API Bearer Token: [] tags: - name: Shipments description: Create, replace, and progress shipments on an order paths: /api/manufacturer/v1/order/{orderId}/shipments/{shipmentId}: get: tags: - Shipments summary: Get a shipment description: Retrieves a single shipment on the order by ID operationId: get parameters: - name: orderId in: path description: ID of the order the shipment belongs to required: true schema: type: integer format: int64 example: 1 - name: shipmentId in: path description: ID of the shipment to retrieve required: true schema: type: string format: uuid responses: '200': description: Shipment retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ShipmentDto' '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Shipment not found; error code: SHIPMENT_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' put: tags: - Shipments summary: Replace a prepared shipment description: Replaces a prepared shipment operationId: replace parameters: - name: orderId in: path description: ID of the order the shipment belongs to required: true schema: type: integer format: int64 example: 1 - name: shipmentId in: path description: ID of the prepared shipment to replace required: true schema: type: string format: uuid - name: release in: query description: If true, the shipment is released after replace required: false schema: type: boolean default: false requestBody: content: application/json: schema: oneOf: - $ref: '#/components/schemas/CollectionShipmentDto' - $ref: '#/components/schemas/CourierShipmentDto' required: true responses: '200': description: Shipment replaced successfully content: application/json: schema: $ref: '#/components/schemas/ShipmentDto' '400': description: 'Invalid shipment; error codes: SHIPMENT_STRUCTURE_FROZEN, SHIPMENT_ADDRESS_REQUIRED, SHIPMENT_PACKING_INVALID, SHIPMENT_OVER_ALLOCATED, SHIPMENT_INCOTERM_INVALID, SHIPMENT_TYPE_INVALID' content: application/json: schema: $ref: '#/components/schemas/ApiError' '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Shipment not found; error code: SHIPMENT_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' delete: tags: - Shipments summary: Delete a shipment description: Deletes a shipment that has not been fulfilled. operationId: delete parameters: - name: orderId in: path description: ID of the order the shipment belongs to required: true schema: type: integer format: int64 example: 1 - name: shipmentId in: path description: ID of the shipment to delete required: true schema: type: string format: uuid responses: '204': description: Shipment deleted successfully '400': description: 'Fulfilled shipments cannot be deleted; error code: SHIPMENT_DELETE_FORBIDDEN' content: application/json: schema: $ref: '#/components/schemas/ApiError' '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Shipment not found; error code: SHIPMENT_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' /api/manufacturer/v1/order/{orderId}/shipments/{shipmentId}/tracking: put: tags: - Shipments summary: Update courier tracking description: Sets or clears tracking on a courier shipment operationId: updateTracking parameters: - name: orderId in: path description: ID of the order the shipment belongs to required: true schema: type: integer format: int64 example: 1 - name: shipmentId in: path description: ID of the courier shipment to update required: true schema: type: string format: uuid requestBody: content: application/json: schema: $ref: '#/components/schemas/UpdateShipmentTrackingDto' required: true responses: '200': description: Tracking updated successfully content: application/json: schema: $ref: '#/components/schemas/ShipmentDto' '400': description: 'Tracking is only allowed on courier shipments; error code: SHIPMENT_TRACKING_FORBIDDEN' content: application/json: schema: $ref: '#/components/schemas/ApiError' '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Shipment not found; error code: SHIPMENT_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' /api/manufacturer/v1/order/{orderId}/shipments: get: tags: - Shipments summary: List shipments on an order description: Returns every shipment currently attached to the order, including parcel allocations and tracking where present. operationId: list_1 parameters: - name: orderId in: path description: ID of the order to list shipments for required: true schema: type: integer format: int64 example: 1 responses: '200': description: Shipments retrieved successfully content: application/json: schema: type: array items: $ref: '#/components/schemas/ShipmentDto' '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' post: tags: - Shipments summary: Create a shipment description: Creates a PREPARED courier or collection shipment on the order. Courier shipments require a destination address snapshot. Pass `release=true` to release immediately after create. operationId: create_3 parameters: - name: orderId in: path description: ID of the order to attach the shipment to required: true schema: type: integer format: int64 example: 1 - name: release in: query description: If true, the shipment is created in RELEASED status required: false schema: type: boolean default: false requestBody: content: application/json: schema: oneOf: - $ref: '#/components/schemas/CollectionShipmentDto' - $ref: '#/components/schemas/CourierShipmentDto' required: true responses: '200': description: Shipment created successfully content: application/json: schema: $ref: '#/components/schemas/ShipmentDto' '400': description: 'Invalid shipment; error codes: SHIPMENT_QUOTE_FORBIDDEN, SHIPMENT_ADDRESS_REQUIRED, SHIPMENT_PACKING_INVALID, SHIPMENT_OVER_ALLOCATED, SHIPMENT_INCOTERM_INVALID, SHIPMENT_TYPE_INVALID' content: application/json: schema: $ref: '#/components/schemas/ApiError' '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Order not found; error code: ORDER_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' /api/manufacturer/v1/order/{orderId}/shipments/{shipmentId}/release: post: tags: - Shipments summary: Release a prepared shipment description: Moves a prepared shipment to released. operationId: release parameters: - name: orderId in: path description: ID of the order the shipment belongs to required: true schema: type: integer format: int64 example: 1 - name: shipmentId in: path description: ID of the prepared shipment to release required: true schema: type: string format: uuid responses: '200': description: Shipment released successfully content: application/json: schema: $ref: '#/components/schemas/ShipmentDto' '400': description: 'Shipment is not PREPARED; error code: SHIPMENT_STATUS_INVALID' content: application/json: schema: $ref: '#/components/schemas/ApiError' '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Shipment not found; error code: SHIPMENT_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' /api/manufacturer/v1/order/{orderId}/shipments/{shipmentId}/fulfil: post: tags: - Shipments summary: Fulfil a released shipment description: Moves a RELEASED shipment to FULFILLED. Courier shipments must already have tracking. operationId: fulfil parameters: - name: orderId in: path description: ID of the order the shipment belongs to required: true schema: type: integer format: int64 example: 1 - name: shipmentId in: path description: ID of the released shipment to fulfil required: true schema: type: string format: uuid responses: '200': description: Shipment fulfilled successfully content: application/json: schema: $ref: '#/components/schemas/ShipmentDto' '400': description: 'Shipment cannot be fulfilled; error codes: SHIPMENT_STATUS_INVALID, SHIPMENT_TRACKING_REQUIRED' content: application/json: schema: $ref: '#/components/schemas/ApiError' '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Shipment not found; error code: SHIPMENT_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' /api/manufacturer/v1/order/{orderId}/shipments/{shipmentId}/documents: post: tags: - Shipments summary: Attach a shipment document description: Attaches a file to a shipment. Files larger than 25 MB are rejected. operationId: uploadDocument parameters: - name: orderId in: path description: ID of the order the shipment belongs to required: true schema: type: integer format: int64 example: 1 - name: shipmentId in: path description: ID of the shipment to attach the document to required: true schema: type: string format: uuid requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: File to upload required: - file responses: '200': description: Document uploaded successfully content: application/json: schema: $ref: '#/components/schemas/ShipmentDocumentDto' '400': description: 'File exceeds 25 MB; error code: SHIPMENT_DOCUMENT_TOO_LARGE' content: application/json: schema: $ref: '#/components/schemas/ApiError' '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Shipment not found; error code: SHIPMENT_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' /api/manufacturer/v1/order/{orderId}/shipments/{shipmentId}/documents/{documentId}: get: tags: - Shipments summary: Download a shipment document description: Returns the decrypted file bytes with the stored content type. operationId: downloadDocument parameters: - name: orderId in: path description: ID of the order the shipment belongs to required: true schema: type: integer format: int64 example: 1 - name: shipmentId in: path description: ID of the shipment the document belongs to required: true schema: type: string format: uuid - name: documentId in: path description: ID of the document to download required: true schema: type: string format: uuid responses: '200': description: Document downloaded successfully content: application/octet-stream: {} '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Document not found; error code: SHIPMENT_DOCUMENT_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' delete: tags: - Shipments summary: Delete a shipment document description: Deletes a file attached to a shipment. operationId: deleteDocument parameters: - name: orderId in: path description: ID of the order the shipment belongs to required: true schema: type: integer format: int64 example: 1 - name: shipmentId in: path description: ID of the shipment the document belongs to required: true schema: type: string format: uuid - name: documentId in: path description: ID of the document to delete required: true schema: type: string format: uuid responses: '204': description: Document deleted successfully '401': description: Unauthorized - missing operator context content: application/json: schema: $ref: '#/components/schemas/ApiError' '404': description: 'Document not found; error code: SHIPMENT_DOCUMENT_NOT_FOUND' content: application/json: schema: $ref: '#/components/schemas/ApiError' components: schemas: ShipmentDocumentDto: type: object properties: id: type: string format: uuid name: type: string contentType: type: string size: type: integer format: int64 uploadedBy: $ref: '#/components/schemas/ShipmentUserDto' createdAt: type: string format: date-time required: - contentType - createdAt - id - name - size - uploadedBy ParcelAllocationDto: type: object properties: requisitionId: type: integer format: int64 quantity: type: integer required: - quantity - requisitionId CollectionShipmentDto: allOf: - $ref: '#/components/schemas/ShipmentDto' description: Collection shipment with no destination address or tracking required: - documents - fromAddress - parcels - type ShipmentAddressDto: type: object description: Address snapshot stored on the shipment. Do not send an address-book ID. properties: street1: type: string street2: type: string city: type: string state: type: string country: type: string zip: type: string name: type: string company: type: string phone: type: string email: type: string jurisdictionIsoCode: type: string residential: type: boolean taxId: type: string required: - city - country - email - name - phone - residential - street1 - street2 - zip ShipmentUserDto: type: object properties: id: type: string format: uuid firstName: type: string lastName: type: string displayName: type: string required: - firstName - id - lastName ShipmentDto: type: object description: A concrete shipment on an order. Discriminated by `type`. discriminator: propertyName: type mapping: COURIER: '#/components/schemas/CourierShipmentDto' COLLECTION: '#/components/schemas/CollectionShipmentDto' properties: id: type: string format: uuid type: type: string enum: - COURIER - COLLECTION status: type: string enum: - PREPARED - RELEASED - FULFILLED incoterm: type: string enum: - EXW - FCA - CPT - CIP - DAP - DPU - DDP - FAS - FOB - CFR - CIF fromAddress: $ref: '#/components/schemas/ShipmentAddressDto' parcels: type: array items: $ref: '#/components/schemas/ParcelDto' preparedAt: type: string format: date-time preparedBy: $ref: '#/components/schemas/ShipmentUserDto' releasedAt: type: string format: date-time releasedBy: $ref: '#/components/schemas/ShipmentUserDto' fulfilledAt: type: string format: date-time fulfilledBy: $ref: '#/components/schemas/ShipmentUserDto' documents: type: array items: $ref: '#/components/schemas/ShipmentDocumentDto' required: - documents - fromAddress - parcels - type CourierShipmentDto: allOf: - $ref: '#/components/schemas/ShipmentDto' description: Courier shipment with a destination address and optional tracking required: - documents - fromAddress - parcels - toAddress - type ShipmentTrackingDto: type: object properties: provider: type: string providerService: type: string trackingNumber: type: string trackingUrl: type: string required: - provider - providerService - trackingNumber ApiError: type: object additionalProperties: true description: Stable error contract. `error` is a SCREAMING_SNAKE code that clients match on; `message` is a human-readable sentence. Some errors add extra string fields (for example organisationId). properties: error: type: string example: ORDER_NOT_FOUND message: type: string example: Order not found required: - error - message ParcelDto: type: object description: Physical parcel on a shipment. Weights are grams; dimensions are millimetres; value is required. properties: id: type: string format: uuid grossWeightGrams: type: integer format: int32 netWeightGrams: type: integer format: int32 value: type: number width: type: integer format: int32 height: type: integer format: int32 length: type: integer format: int32 allocations: type: array items: $ref: '#/components/schemas/ParcelAllocationDto' required: - allocations - grossWeightGrams - height - length - netWeightGrams - value - width UpdateShipmentTrackingDto: type: object description: Tracking payload for a courier shipment. Omit or null `tracking` to clear it. properties: tracking: $ref: '#/components/schemas/ShipmentTrackingDto' securitySchemes: Phasio_API_Bearer_Token: type: http name: Authorization in: header scheme: bearer bearerFormat: JWT