Public Carrier Protocol (PCP)
Introduction
The Public Carrier Protocol provides a way for any carrier to integrate with the delivery platform. As an integrator you will provide information shipment data to the platform. You will also receive information back to your systems when different events occur, i.e. a parcel has been delivered. Ingrid will provide you with the necessary credentials to connect to the platform. These are the steps involved in a typical delivery journey When the carrier receives a shipment booking, the carrier pre-advice the platform with shipment data. The parcel is arrival scanned at the store and the platform notifies the carrier that a parcel has been received and is ready to be picked up by consumer The carrier notifies the consumer that the parcel is ready to be picked up The consumer identifies themselves with a pre-authenticated QR code or an identity document. The platform requests validation from the carrier. If everything is ok, the parcel is handed out to the consumer. The platform notifies the carrier that the parcel has been delivered.
Sequence diagrams
Pre Advise
sequenceDiagram participant carrier as Carrier participant pcp as Ingrid PCP participant locker as Service Point / Locker carrier->>pcp: UpsertParcel pcp->>locker: UpsertParcel
Ingestion
sequenceDiagram participant locker as Service Point / Locker participant pcp as Ingrid PCP participant carrier as Carrier locker->>locker: Scan code locker->>pcp: Query(code) pcp->>pcp: Search pre-advised parcel alt Pre advised parcel not found pcp->>carrier: Query(code) carrier-->>pcp: Parcel data end pcp-->>locker: Parcel data locker->>locker: Accept parcel locker->>pcp: Ingested(parcel) pcp->>carrier: Ingested(parcel) carrier->>carrier: Notify recipient
Delivery
sequenceDiagram participant locker as Service Point / Locker participant pcp as Ingrid PCP participant carrier as Carrier locker->>locker: Scan receive code locker->>pcp:Query(receive code) pcp->>carrier:Query(receive code) carrier-->>pcp: OK pcp-->>locker: OK alt Parcel accpeted by recipient locker->>locker: Hand out parcel locker->>pcp: Delivered pcp->>carrier: Delivered else Parcle refused by customer locker->>pcp: Refused reason pcp->>carrier: Refused reason end
1st mile (Send / Customer return)
sequenceDiagram participant locker as Service Point / Locker participant pcp as Ingrid PCP participant carrier as Carrier locker->>locker: Scan drop off code locker->>pcp: Query(code) pcp->>carrier: Query(code) carrier-->>pcp: Parcel data pcp-->>locker: Parcel data locker->>locker: Accept parcel locker->>pcp: Accepted(parcel) pcp->>carrier: Accepted(parcel)
Overdue returns
sequenceDiagram participant locker as Service Point / Locker participant pcp as Ingrid PCP participant carrier as Carrier locker->>locker: List pending returns locker->>pcp: HandleReturns(tracking numbers) loop Loop over returns pcp->>carrier: /parcel/returned carrier-->>pcp: Parcel data end pcp-->>locker: Parcel data
API
Ingrid-side endpoints
Upsert parcel 🔗
Pre-advise parcel or to update already stored parcel/ For Ingrid to work as efficiently as possible it is required by the carrier to keep the Ingrid service point system up-to-date with current parcel information. This includes pre-advicing parcel, that is, provide information about parcels which has been booked for a certain location. It also includes updating parcels already at location, i.e. if a parcel should be recalled to the merchant ahead of time.
Carrier side endpoints
Query a parcel
Query parcel by a given code. This endpoint is used for gathering more information about a parcel given for example a tracking number, a receive code or a drop-off code.
Request
GET /api/v1/parcel/query?code=997123123&location_id=123 HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
Response
{
"parcel_id": "9971231233",
"tracking_id": "string",
"receive_code": "1234",
"product_code": "instr-dummyproduct",
"journey_stage": "JOURNEY_STAGE_LAST_MILE",
"sender": {
"name": "John Test",
"phone": "987654321",
"email": "john@test.com",
"address": {
"street": "437 Lytton",
"city": "Palo Alto",
"state": "CA",
"country": "US",
"zip": "94301"
}
},
"recipient": {
"name": "John Test",
"phone": "987654321",
"email": "john@test.com",
"address": {
"street": "437 Lytton",
"city": "Palo Alto",
"state": "CA",
"country": "US",
"zip": "94301"
}
},
"dimensions": {
"height": 1000,
"width": 500,
"length": 500
},
"weight": 2000,
"is_identity_confirmed": false,
"delivery_requirements": [
{
"type": "DELIVERY_REQUIREMENT_TYPE_CASH_ON_DELIVERY",
"data": {
"amount": 200,
"currency": "USD"
}
}
],
"blocker": {
"blocked": true,
"reasons": [
{
"language": "en-GB",
"text": "Canceled by merchant."
}
]
}
}
Ingest a parcel 🔗
Acknowledge that a parcel is ingested so is dropped off by a courier in a given location. It concerns B2C parcels. It means that the parcel is physically stored in one of the locations either in a locker or on a shelf and from now on the parcel can be picked up by a customer. This is the time to notify the recipient that the parcel is ready to be picked up.
Request
POST /api/v1/parcel/ingested HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
{
"parcel_id": "9971231233",
"location_id": "9b6b047bfc1f4d06a2f5a567e5144345",
"delivery_module": "MODULE_TYPE_RACK",
"relocated": false
}
Response
{
"receive_code": "1234"
}
Refuse a parcel 🔗
Acknowledge that a parcel is refused by a customer. It means that the customer refused to pick up the parcel. Reasons for refusing picking up a parcel includes for example damaged parcel and parcel not ordered
Request
POST /api/v1/parcel/refused HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
{
"parcel_id": "9971231233",
"deviation": {
"comment": "Customer reports that a parcel is damaged.",
"type": "DEVIATION_TYPE_GOODS_DAMAGED"
}
}
Response
{
"digital_receipt_sent": true,
"receipt": {
"url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
"content_type": "PDF"
}
}
Deliver a parcel 🔗
Acknowledge that a parcel is successfully delivered to a customer.
Request
POST /api/v1/parcel/delivered HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
{
"parcel_id": "9971231233",
"recipient_identity_document": {
"number": "123456789",
"type": "DOCUMENT_TYPE_SWEDISH_DRIVING_LICENSE"
},
"proxy_identity_document": {
"number": "123456789",
"type": "DOCUMENT_TYPE_SWEDISH_DRIVING_LICENSE"
},
"deviation": {
"comment": "Customer reports that a parcel is damaged.",
"type": "DEVIATION_TYPE_GOODS_DAMAGED"
}
}
Response
{
"digital_receipt_sent": true,
"receipt": {
"url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
"content_type": "PDF"
}
}
Return a parcel 🔗
Acknowledge that a parcel is returned. It means that the parcel previously ingested in a location is now returned. It's used for all return types except a customer return. Common case is an overdue return.
Request
Request
POST /api/v1/parcel/returned HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
{
"parcel_id": "9971231233"
}
Response
{
"label": {
"url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
"content_type": "PDF"
}
}
Accept a parcel 🔗
Acknowledge that a parcel is delivered to a given location by a customer and accepted by a staff member. It means that a parcel is physically in the location and waits to be picked-up by a driver. It applies only to customer parcels so C2B (customer returns) and C2C (send) parcels.
Request
POST /api/v1/parcel/accepted HTTP/1.1
Host: api.ingrid.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer base64-encoded-api-token
{
"parcel_id": "9971231233",
"location_id": "9b6b047bfc1f4d06a2f5a567e5144345"
}
Response
{
"digital_receipt_sent": true,
"document": {
"url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
"content_type": "PDF"
}
}