Planman API Documentation logo

Introduction Edit

This documentation provides a guide for integrating and working with the Planman REST API. After successful integration, you can utilize Planman’s on-demand delivery management system along with all its unique features.

Planman API provides you with the ability to request a delivery for your order and have that order delivered by one of our affiliated operators. To learn more about our rates and start the integration process, please contact one of our affiliated operators iFleet or Scooter.

All endpoints of the API use standard HTTP response codes and return JSON-encoded responses.

You’ll succeed if this happens.

Here’s some useful information.

Something bad will happen if you do this.

Getting Started Edit

To get you started, the Planman team will create a branch entity for each of your branches. Each branch will have a unique code that can be used for authentication. The branch codes will be provided to you by our affilated operator.

Furthermore, each branch serves a variety of zones based on different pricing rates.

The production API base URL will be provided to you by our team after successful integration.

You can test your integration with Planman on our staging environment before deploying to production.

  • Staging API Base URL: https://srvstg.virgingates.com

Authentication Edit

Authentication is required for all API requests. Planman API uses bearer access tokens to authenticate requests. To get an access token, you can sign in using your branch code through our sign in endpoint. The access token’s lifetime is 18 hours. Whenever it expires, you need to call the sign in endpoint to have a new one generated.

The access token should be added as a request header as shown below.

Apart from the sign in endpoint, none of the requests will succeed unless you include a correct access token in the request header.

Authorization: Bearer $ACCESS_TOKEN
curl -X POST https://srvstg.virgingates.com/business/api/v1/branches/sign-in -H "Content-type: application/json" -d '{"code": "1234567"}'

Main Flow Edit

Planman’s main delivery unit is a Trip. For every requested delivery, a new trip entity is created. Each trip can have multiple tasks, where each task represents an order from the branch by a different customer.

After you sign in using your branch code, you can list the served zones to identify which geographical zones are served by your branch. This can be done using the List Served Zones endpoint. To initiate a delivery, simply call the Request Pilot endpoint, which will create a new trip entity and request a pilot for delivery. Each branch can have a maximum of two concurrent trips.

You can view the trip’s information by calling the Retrieve Trip endpoint. Similarly, you can view multiple trips’ information through the List Trips endpoint.

Moreover, you can cancel the trip any time before the pilot starts collecting your order by calling the Cancel Trip endpoint. If you need to cancel a trip after that time, please contact our call center.

Planman supports multiple service types. Integrations use the service type “B2B”.

Trip status flow:

A trip’s status is REQUESTED when it’s first created. When a pilot is nominated for a trip and still hasn’t accepted, the trip’s status becomes PENDING. When it gets assigned to the pilot, the status is ASSIGNED. When the pilot starts collecting the tasks, the trip’s status becomes OPENED. The trip remains OPENED until all the tasks are delivered, when it then turns CLOSED. If at any time the trip is cancelled, its status becomes CANCELLED.

Task status flow:

A task’s status is REQUESTED when it’s first created. When a pilot is nominated for a trip and still hasn’t accepted, the status of the tasks in the trip is PENDING. When the trip gets assigned to the pilot, the task’s status is ASSIGNED. When the pilot reaches the branch, the task’s status becomes PENDING_COLLECTION. When the pilot collects the task, its status is updated to COLLECTED. While the pilot is on the way to the customer’s location, the task’s status is ON_DELIVERY. When the pilot reaches the customer’s location, the task’s status is REACHED. When the pilot delivers the order to the customer, the task’s status becomes DELIVERED. If at any time the task is cancelled or returned, the status becomes CANCELED or RETURNED, respectively.

Pilot status flow:

A pilot’s status is IN_HUB when the pilot is in the delivery hub waiting for requests. When the pilot is nominated for a trip, the pilot’s status is CANDIDATE. When the pilot accepts the trip request, his status becomes ASSIGNED. When the pilot reaches the branch, the status is WAITING. When the pilot starts collecting the tasks, his status becomes COLLECTING. After the pilot collects all the tasks in the trip, the status is updated to LOADED. When the pilot delivers all the tasks and he still hasn’t arrived to the hub, his status becomes AVAILABLE. If a pilot is manually assigned to a trip by one of our affiliated operators, his status becomes MANUALLY_ASSIGNED. If one pilot picks up the tasks from another pilot, the status of the former pilot is REACHED_PILOT. If a pilot is offline, his status is UNAVAILABLE.

Errors Edit

HTTP response codes

Code Name Description
200 OK Success
400 Bad Request The server could not process the request
401 Unauthorized The request did not include an access token or the access token was expired
404 Not Found The server could not find the requested resource
409 Conflict The request could not be processed due to a conflict in the current state of the resource
500 Internal Server Error The server encountered an unexpected condition

Exception Codes

Name Description
MissingParameterException A required request parameter is missing.
NotFoundException The requested resource is not found.
UnAuthorizedException The branch code used for sign in is not correct, or the bearer token is not valid.
InactiveVendorBranchException The branch is not active.
BranchExceedsTripsThresholdException The maximum number of concurrent trips per branch has been exceeded.
VendorTierConfigDoesNotExist The vendor has no current pricing configuration.
InsufficientBalanceException The vendor has insufficient balance to request pilot.
InvalidParameterException The value of the parameter is not supported.
InvalidTripStatusException The trip’s status is not as expected for this request to be completed.
InvalidPilotStatusException The pilot’s status is not as expected for this request to be completed.
InvalidServiceTypesException The service type is not as expected for this request to be completed. For example, it could be “B2B” while it’s required to be “B2C”.

All errors will return JSON in the following format:

{
  "stackTraceId": 2165529378315486700,
  "args": {
    "additionalProp1": {},
    "additionalProp2": {},
    "additionalProp3": {},
  },
  "devDetails": "",
  "propagated": false,
  "trace": {
    "exceptionClass": "",
    "message": "",
    "stackTrace": [
      ""
    ]
  },
  "code": "$EXCEPTION_CODE"
}

Core Resources Edit

Branch

Name Type Description
id Long The unique identifier of the branch.
label String The label (name) of the branch.
vendorId Long The unique identifier of the vendor.

Customer

Name Type Description
id Long The unique identifier of the customer.
addressId Long The unique identifier of the customer’s address.
mobileNo String The customer’s mobile number.

Location

Represents the standard GeoJSON object.

Name Type Description
type String A string indicating whether this location is a “Point” or a “Polygon”
coordinates Array An array containing the longitude and the latitude coordinates of a location of type “Point”, or containing multiple arrays of longitude and latitude coordinates of a location of type “Polygon”.

Trip

Name Type Description
id Long The unique identifier of the trip.
status TripStatus The updated status of the trip.
assignmentDate String The date the pilot was assigned to the trip.
creationDate String The date the trip was created.
pendingCollectionDate String The date the tasks of the trip were ready for collection.
lastUpdateDate String The date of the last trip update.
routeDataEnriched Boolean A flag indicating whether the route data was set in the trip.
eta Long The estimated time of arrival of the pilot to the branch.
slaTier SlaTier Refers to the time taken for the trip to be dispatched after it was created.
maxAllowedTasksCount Integer The maximum allowed number of tasks per trip.
requestedTasksCount Integer The number of tasks in the trip.
distanceInMeters Double The total distance of the route taken by the pilot from the branch’s location to the last customer’s location.
durationInSeconds Long The total duration of the trip in seconds.
TripStatus
PENDING
REQUESTED
OPENED
CLOSED
ASSIGNED
CANCELLED
NONE
SlaTier
LESS_THAN_5_MINUTES
MORE_THAN_20_MINUTES

Task

Name Type Description
id Long The unique identifier of the task.
sequence Integer Indicates the order of delivery of this task relative to the other tasks in the same trip.
distanceInMeters Double The total distance of the route taken by the pilot from the branch’s location to the customer’s location.
distanceFromLastTaskInMeters Double The distance between this task’s delivery location and the previous task in the same trip’s delivery location.
durationInSeconds Long The total duration between the task’s request date and delivery date.
durationSinceLastTask Integer The duration since the delivery date of the previous task in the same trip.
pinnedDestinationPoint Location The customer’s location where this task was/is being delivered.
reachedDestinationDate String The date that this task reached the customer location.
status TaskStatus The current status of the task.
linkStatus String Indicates whether the customer location was entered by the pilot and can be linked to this task or not.
customer Customer The customer for whom this task belongs.
TaskStatus
PENDING
REQUESTED
ASSIGNED
PENDING_COLLECTION
COLLECTED
REACHED
DELIVERED
RETURNED
CANCELED
RECALLED
ON_DELIVERY
UNKNOWN
NONE

Pilot

Name Type Description
id Long The unique identifier of the pilot.
mobileNo String The pilot’s mobile number.
fullName String The pilot’s full name.
lastKnownLocation Location The last location that was recorded for this pilot.
status PilotStatus The current status of the pilot.
PilotStatus
IN_HUB
CANDIDATE
ASSIGNED
WAITING
COLLECTING
LOADED
MANUALLY_ASSIGNED
REACHED_PILOT
UNAVAILABLE
AVAILABLE
NONE

MultilingualString

Name Type Description
en String String representation in English.
ar String String representation in Arabic.

MoneyWithCurrency

Name Type Description
amount Double The exact amount of money.
currency String The currency of the money, for example “EGP”.

/api/v1/branches/sign-in Edit

Allows you to sign in using your branch code and receive an access token, which is required for performing calls to other endpoints of the API.

Body Parameters

Name Type Required Description
code String true The unique sign in code defined for each branch.

Response Fields

Name Type Description
id Long The unique identifier of the branch.
label String The label (name) of the branch.
code String The unique sign in code defined for each branch.
vendorId Long The unique identifier of the vendor.
token String The bearer access token used for authenticating service calls made to other endpoints of the API.

You will be successfully authenticated and can perform calls to other endpoints.

curl -X POST https://srvstg.virgingates.com/business/api/v1/branches/sign-in -H "Content-type: application/json" -d '{"code": "1234567"}'
{
  "code": "147657930"
}
{
  "id": 2165529378315486700,
  "label": "Branch Label",
  "code": "147657930",
  "vendorId": 2165529378315486700,
  "token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.1KP0SsvENi7Uz1oQc07aXTL7kpQG5jBNIybqr60AlD4"
}
{
  "stackTraceId": 2165529378315486700,
  "args": {
      "additionalProp1": {}
  },
  "devDetails": "string",
  "propagated": false,
  "trace": {
      "exceptionClass": "string",
      "message": "string",
      "stackTrace": [
          "string"
      ]
  },
  "code": "WebClientOperationException"
}

/api/v1/branches/:id/sign-out Edit

Allows you to sign out using your branch ID.

Path Parameters

Name Type Required Description
id Long true The unique identifier of the branch.

Response Fields

Name Type Description
id Long The unique identifier of the branch.
curl -X POST https://srvstg.virgingates.com/business/api/v1/branches/2165529378315486700/sign-out -H "Authorization: Bearer $ACCESS_TOKEN" 
{
  "id": 2165529378315486700
}
{
   "stackTraceId": 2165529378315486700,
   "args": {
       "additionalProp1": {}
   },
   "devDetails": "string",
   "propagated": false,
   "trace": {
       "exceptionClass": "string",
       "message": "string",
       "stackTrace": [
           "string"
       ]
   },
   "code": "WebClientOperationException"
}

/api/v1/branches/:id/served-zones Edit

Retrieves a list of zones that are served by the branch specified by the requested ID.

Path Parameters

Name Type Required Description
id Long true The unique identifier of the branch.

Response Fields

Name Type Description
branchLocation Location The location of the requested branch, returned as a Location object of type Point.
hubLocation Location The location of the delivery hub that serves the requested branch, returned as a Location object of type Point.
zones Array An array of ZoneRateResponse objects.

ZoneRateResponse

Name Type Description
zoneId Long The unique identifier of the zone.
zoneName MultilingualString The name of the zone in english and arabic.
rateName String The name of the pricing rate assigned to this zone.
rateValue MoneyWithCurrency The value of the pricing rate assigned to this zone.
polygon Location The location of the zone, returned as a Location object of type Polygon.
curl "https://srvstg.virgingates.com/business/api/v1/branches/2165529378315486700/served-zones" -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "branchLocation": {
    "type": "Point",
    "coordinates": [
      -1.43,
      31.3
    ]
  },
  "hubLocation": {
    "type": "Point",
    "coordinates": [
      -1.43,
      31.3
    ]
  },
  "zones": [
    {
      "zoneId": 2165529378315486700,
      "zoneName": {
        "en": "El Merghany",
        "ar": "الميرغني"
      },
      "rateName": "rate1",
      "rateValue": {
        "amount": 31.01,
        "currency": "EGP"
      },
      "polygon": {
        "type": "Polygon",
        "coordinates": [
          [
            -1.43,
            31.3
          ]
        ]
      }
    }
  ]
}
{
  "stackTraceId": 2165529378315486700,
  "args": {
      "additionalProp1": {}
  },
  "devDetails": "string",
  "propagated": false,
  "trace": {
      "exceptionClass": "string",
      "message": "string",
      "stackTrace": [
          "string"
      ]
  },
  "code": "WebClientOperationException"
}

/api/v1/branches/:id/request-pilot Edit

Requests a pilot for the branch specified by the requested ID and creates a new trip.

Path Parameters

Name Type Required Description
id Long true The unique identifier of the branch.

Body Parameters

Name Type Required Description
deliveryLocation PickupLocation false The Delivery Location.
customerMobileNo String false Customer Mobile number.
value MoneyWithCurrency false task total amount.
vendorTaskId String false Vendor Order Id.
callbackURL String false URL for callback with status updates.

Response Fields

Name Type Description
tripId Long The unique identifier of the created trip.
taskId Long The unique identifier of the created task.
maxAllowedTasksCount Integer The maximum allowed number of tasks per trip.
curl -X POST https://srvstg.virgingates.com/business/api/v1/branches/2165529378315486700/request-pilot -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "deliveryLocation": {
    "description": "Point",
    "point": {
      "type" : "Point", 
      "coordinates" : [
        31.0, 
        32.0
      ]
    } 
  },
  "customerMobileNo": "123123123",
  "value": {
    "amount": 300.0,
    "currency": "EGP"
  },
  "vendorTaskId": "123",
  "callbackURL": "http://callback.com"
}
{
    "tripId": 9921381276774878,
    "taskId": 9921381276774878,
    "maxAllowedTasksCount": 3
}
{
  "stackTraceId": 2165529378315486700,
  "args": {
      "additionalProp1": {}
  },
  "devDetails": "string",
  "propagated": false,
  "trace": {
      "exceptionClass": "string",
      "message": "string",
      "stackTrace": [
          "string"
      ]
  },
  "code": "WebClientOperationException"
}

/api/v1/branches/:id/trips/:tripId/tasks Edit

Add new task to existing branch trip.

Path Parameters

Name Type Required Description
id Long true The unique identifier of the branch.
tripId Long true The unique identifier of the trip.

Body Parameters

Name Type Required Description
zoneName MultilingualString false The Delivery Location zonename.
deliveryLocation PickupLocation false The Delivery Location.
customerMobileNo String false Customer Mobile number.
value MoneyWithCurrency false task total amount.
vendorTaskId String false Vendor Order Id.
curl -X POST https://srvstg.virgingates.com/business/api/v1/branches/2165529378315486700/trips/2165529378315486700/tasks -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "zoneName": {
    "en": "$lastAddedZoneNameEn",
    "ar": "$lastAddedZoneNameAr"
    },
  "deliveryLocation": { 
    "description": "Point", 
    "point": {
      "type" : "Point", 
      "coordinates" : [
        31.0, 
        32.0
      ]
    } 
  },
  "customerMobileNo": "123123123",
  "value": {
    "amount": 300.0,
    "currency": "EGP"
  },
  "vendorTaskId": "123",
}
{
  "stackTraceId": 2165529378315486700,
  "args": {
      "additionalProp1": {}
  },
  "devDetails": "string",
  "propagated": false,
  "trace": {
      "exceptionClass": "string",
      "message": "string",
      "stackTrace": [
          "string"
      ]
  },
  "code": "WebClientOperationException"
}

/api/v1/trips/:id Edit

Returns various information about a single trip specified by the requested ID.

Path Parameters

Name Type Required Description
id Long true The unique identifier of the trip.

Response Fields

Name Type Description
id Long The unique identifier of the trip.
status TripStatus The current status of the trip.
assignmentDate String The date the pilot was assigned to the trip.
creationDate String The date the trip was created.
lastUpdateDate String The date of the last trip update.
routeDataEnriched Boolean A flag indicating whether the route data was set in the trip.
eta Long The estimated time of arrival of the pilot to the branch.
slaTier String Refers to the time taken for the trip to be dispatched after it was created.
maxAllowedTasksCount Integer The maximum allowed number of tasks per trip.
requestedTasksCount Integer The number of tasks in the trip.
distanceInMeters Double The total distance of the route taken by the pilot from the branch’s location to the customer location.
durationInSeconds Long The total duration of the trip in seconds.
vendorBranch Branch The branch from which the trip was initiated.
pilot Pilot The pilot assigned to the trip.
tasks Array An array containig all the tasks in the trip.
hasOnlineOrder Boolean A flag indicating whether this trip belongs to an order placed through Survv App.
curl "https://srvstg.virgingates.com/business/api/v1/trips/9921381276774878" -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "id": 9921381276774878,
  "vendorBranch": {
    "id": 2165529378315486700,
    "label": "Branch1",
    "vendorId": 2165529378315486700
  },
  "pilot": {
    "id": 2165529378315486700,
    "mobileNo": "0102312381",
    "fullName": "Name",
    "lastKnownLocation": {
      "type": "Point",
      "coordinates": [
        -1.43,
        31.3
      ]
    },
    "status": "UNAVAILABLE"
  },
  "status": "CANCELLED",
  "assignmentDate": "2018-09-01T18:04:53.178Z",
  "creationDate": "2018-09-01T18:04:53.178Z",
  "lastUpdateDate": "2018-09-01T18:05:23.178Z",
  "routeDataEnriched": true,
  "eta": 600,
  "slaTier": "LESS_THAN_5_MINUTES",
  "maxAllowedTasksCount": 4,
  "requestedTasksCount": 4,
  "distanceInMeters": 3350,
  "durationInSeconds": 90,
  "tasks": [
    {
      "id": 9921381276774878,
      "sequence": 12,
      "distanceInMeters": 3350,
      "distanceFromLastTaskInMeters": 3350,
      "durationInSeconds": 90,
      "durationSinceLastTask": 90,
      "pinnedDestinationPoint": {
        "type": "Point",
        "coordinates": [
          -1.43,
          31.3
        ]
      },
      "reachedDestinationDate": "2018-09-01T18:04:53.178Z",
      "status": "REACHED",
      "linkStatus": "UNDECIDED",
      "customer": {
        "id": 2165529378315486700,
        "addressId": 2165529378315486700,
        "mobileNo": "01061239214"
      }
    }
  ],
  "hasOnlineOrder": false
}
{
  "stackTraceId": 2165529378315486700,
  "args": {
      "additionalProp1": {}
  },
  "devDetails": "string",
  "propagated": false,
  "trace": {
      "exceptionClass": "string",
      "message": "string",
      "stackTrace": [
          "string"
      ]
  },
  "code": "WebClientOperationException"
}

/api/v1/trips Edit

Returns various information about multiple trips filtered by criteria and/or sorted by one of trips's properties in ascending/descending order.

Query Parameters

Name Type Required Description
criteria String true Used for filtering the trips returned, for example criteria={“status”:[“CANCELLED”]}
sortBy String true Used for sorting the trips returned based on one of the trip’s properties.
sortType String true Indicates whether sorting will be done in ascending or descending order.

Response Fields

Returns an array of trip objects with the following fields:

Name Type Description
id Long The unique identifier of the trip.
status TripStatus The current status of the trip.
assignmentDate String The date the pilot was assigned to the trip.
pendingCollectionDate String The date the tasks of the trip were ready for collection.
creationDate String The date the trip was created.
eta Long The estimated time of arrival of the pilot to the branch.
slaTier String Refers to the time taken for the trip to be dispatched after it was created.
maxAllowedTasksCount Integer The maximum allowed number of tasks per trip.
requestedTasksCount Integer The number of tasks in the trip.
vendorBranch Branch The branch from which the trip was initiated.
pilot Pilot The pilot assigned to the trip.

Returns a maximum of 800 trips.

curl "https://srvstg.virgingates.com/business/api/v1/trips?sortType=asc&criteria={"vendorBranchId":1440482015196672,"status":["CANCELLED"]}&sortBy="  -H "Authorization: Bearer $ACCESS_TOKEN"
[
  {
    "id": 9921381276774878,
    "vendorBranch": {
      "id": 2165529378315486700,
      "label": "Branch1",
      "vendorId": 2165529378315486700
    },
    "pilot": {
      "id": 2165529378315486700,
      "mobileNo": "0102312381",
      "fullName": "Name",
      "lastKnownLocation": {
        "type": "Point",
        "coordinates": [
          -1.43,
          31.3
        ]
      },
      "status": "UNAVAILABLE"
    },
    "status": "CANCELLED",
    "assignmentDate": "2018-09-01T18:04:53.178Z",
    "pendingCollectionDate": "2018-09-01T18:04:53.178Z",
    "creationDate": "2018-09-01T18:04:53.178Z",
    "eta": 600,
    "slaTier": "LESS_THAN_5_MINUTES",
    "maxAllowedTasksCount": 4,
    "requestedTasksCount": 4
  }
]
{
  "stackTraceId": 2165529378315486700,
  "args": {
      "additionalProp1": {}
  },
  "devDetails": "string",
  "propagated": false,
  "trace": {
      "exceptionClass": "string",
      "message": "string",
      "stackTrace": [
          "string"
      ]
  },
  "code": "WebClientOperationException"
}

/api/v1/trips/:id/cancel Edit

Cancels the trip specified by the requested ID. Trip status must not be "OPENED".

Path Parameters

Name Type Required Description
id Long true The unique identifier of the trip.

Body Parameters

Name Type Required Description
branchId Long true The unique identifier of the branch.
cancellationReason String true The reason for the trip cancellation.

Response Fields

Name Type Description
tripStatus TripStatus The updated status of the trip.
curl -X POST https://srvstg.virgingates.com/business/api/v1/trips/9921381276774878/cancel -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-type: application/json" -d '{"branchId": 2165529378315486700, "cancellationReason": "Order Taking Too Long"}'
{
    "branchId": 2165529378315486700,
    "cancellationReason": "Order Taking Too Long"
}
{
    "tripStatus": "CANCELLED"
}
{
  "stackTraceId": 2165529378315486700,
  "args": {
      "additionalProp1": {}
  },
  "devDetails": "string",
  "propagated": false,
  "trace": {
      "exceptionClass": "string",
      "message": "string",
      "stackTrace": [
          "string"
      ]
  },
  "code": "WebClientOperationException"
}

/Caller/Provided/URL Edit

Caller systems should implement an API with the below request body (request body have extra parameters then the below but the below are the caller system concern) and provide it's URL while requesting Pilot.

Body Parameters

Name Type Required Description
tripId Long true The unique identifier of the Trip.
tripStatus String true The Trip new Status.
taskStatuses List true List of the Tasks’ statuses inside the Trip.

Response Fields

Name Type Description
data Map Any data the could be used to assist the fleet operation.
{
    "tripId": 2165529378315486700,
    "tripStatus": "OPENED",
    "taskStatuses": [
      {
        "taskId": 2165529378315486700,
        "status": "COLLECTED"
      },
      {
        "taskId": 2165529378315486701,
        "status": "REACHED"
      }
    ]
}
{
    "data": {"example": {"ex1": 123}}
}
{
  "stackTraceId": 2165529378315486700,
  "args": {
      "additionalProp1": {}
  },
  "devDetails": "string",
  "propagated": false,
  "trace": {
      "exceptionClass": "string",
      "message": "string",
      "stackTrace": [
          "string"
      ]
  },
  "code": "WebClientOperationException"
}