Porting
API Call Flow
To create a porting request you'll need to call the Get Networks endpoint which returns a list of available Target and Source Networks. You can then select a target network and use that to call Get Provisioning Orders and Get Tariffs, once you have selected a tariff you can call Get BoltOns and Get Services with that Tariff Number. Having gained all the information you can then put together a Create Port request to start porting.
Status Flow
Created
– Porting / Migration has been requested for the MSISDNs, any matched stock will be put into status ‘Port-In Started’Pac Check Failed
– one or more PACs are invalid,Update Port
must be called to either change the PAC or cancel the line or call Cancel Port to cancel all lines at once.Cancelled
– Porting / Migration cancelled, MSISDNs will not be ported.Submitted
– Porting / Migration requested with provider, MSISDNs will port if not cancelled before the port is locked.Locked
– Porting locked, MSISDNs will port the next working day.Ported
– MSISDN porting has completed, the system will now begin provisioning on the target network.Awaiting Serial
– Only valid if doing a 'Migrate In Keep Sim' (available on limited networks), waiting on the network to provide the current serial number the MSISDN is on.Create RA
– Port In / Migrate In submission awaiting creation.Awaiting RA
– Port In / Migrate In submission queued, waiting for completion.Create Configuration
– Bar Service Config submission awaiting creation (only valid if there are services to configure).Awaiting Configuration
– Bar Service Config submission queued, waiting for completion.Complete
– Porting is complete
Error States
In these states the Cellhire team will be automatically informed, investigate and resolve the issue
SubmittedWithErrors
– Something went wrong with provider.Error
– Something went wrong.
Get Porting Networks
This endpoint returns a list of Porting Types (Port, MigrateIn, MigrateInKeep) and for each type it returns a list of available networks (Target Networks)
Name | Type | Description |
---|---|---|
portTypeName | string | Porting Type (can be Port , MigrateIn or MigrateInKeep ) |
portType | int | Id of the Porting Type |
targetNetworks | array of TargetNetworks | List of available networks for this type |
Target Networks
Name | Type | Description |
---|---|---|
id | int | Id of the Target Network |
name | string | Name of the Target Network |
maxPortDays | int | Maximum days from now before which a Port / Migration can be booked |
minPortDays | int | Minimum days from now after which a Port / Migration can be booked |
allowEsim | bool | Whether this network allows eSims |
networkNumber | int | Cellhire network number (used for subsequent calls e.g. GetTariff and GetProvisioningOrders ) |
sourceNetworks | array of SourceNetworks | List of available networks the MSISDN(s) can come from |
upcomingHolidays | array of Dates | List of dates when Port / Migration is unavailable. None working days which fall between the minPortDays and maxPortDays |
Source Networks
Name | Type | Description |
---|---|---|
id | int | Id of the Source Network |
name | string | Name of the Source Network |
Request
curl --location 'https://api.cellhire.com/api/porting/{accountId}/networks' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjRBMDlENTFBMDhEOEUxMTU0OTkyODFDN...'
Response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
[
{
"portTypeName": "Port",
"portType": 2,
"targetNetworks": [
{
"id": 1,
"name": "Vodafone",
"maxPortDays": 30,
"minPortDays": 1,
"allowEsim": true,
"networkNumber": 200,
"sourceNetworks": [
{
"id": 5,
"name": "O2"
},
{
"id": 10,
"name": "Virgin Media"
}
],
"upcomingHolidays": [
"2025-05-05T00:00:00",
"2025-05-26T00:00:00"
]
}
]
}
]
Tariffs / BoltOns / Provisioning Orders
Additional commands needed for provisioning can be found on on the Provision Extras page.
Services
Command available on Get available Services for Network and Tariff page.
List Ports
This endpoint returns a paged list of all Port / Migration requests for an account.
Request
Name | Type | Description |
---|---|---|
accountId | int | Cellhire account number |
x-pagenumber | int | Page number to return |
x-pagesize | int | Number of records to return per page (Max 50) |
curl --location 'https://api.cellhire.com/api/porting/{accountId}' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'x-pagenumber: 1' \
--header 'x-pagesize: 10' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjRBMDlENTFBMDhEOEUxMTU0OTkyODFDN...'
Response
Name | Type | Description |
---|---|---|
total | int | Total number of requests |
totalPages | int | Total number of pages |
data | array of Requests | List of requests |
Requests
Name | Type | Description |
---|---|---|
id | guid | Request Id |
name | string | Name of Port / Migration |
connectionDate | date | Date of Port / Migration |
portType | int | Id of the Port Type (see Porting Networks) |
portTypeName | string | Name of Port Type |
rowCount | int | Number of rows on this Port / Migration |
status | int | Id of the Port Status |
statusName | string | Name of Port Status (see Status Flow) |
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"total": 10,
"totalPages": 1,
"data": [
{
"id": "bb8c7f95-a406-41bd-140e-08dca4c4f4e2",
"name": "Sample Port",
"connectionDate": "2024-07-18T00:00:00",
"portType": 2,
"portTypeName": "PortIn",
"rowCount": 1,
"status": 16,
"statusName": "Complete"
}
]
}
Get Port Details
Get extra details of a specific port.
Request
Name | Type | Description |
---|---|---|
accountId | int | Cellhire account number |
portId | guid | Id of the Port / Migration |
curl --location 'https://api.cellhire.com/api/porting/{accountId}/port/{portId}' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjRBMDlENTFBMDhEOEUxMTU0OTkyODFDN...'
Response
Name | Type | Description |
---|---|---|
id | guid | Request Id |
status | int | Id of the Port Status |
statusName | string | Name of Port Status (see Status Flow) |
name | string | Name of Port / Migration |
targetNetworkId | int | Id of the Target Network (see Porting Networks) |
targetNetworkName | string | Name of Target Network |
sourceNetworkId | int | Id of the Source Network (see Porting Networks) |
sourceNetworkName | string | Name of Source Network |
connectionDate | date | Date of Port / Migration |
portType | int | Id of the Port Type (see Porting Networks) |
portTypeName | string | Name of Port Type |
rowCount | int | Number of rows on this Port / Migration |
rows | array of PortRows | List of rows on this Port / Migration |
Port Rows
Name | Type | Description |
---|---|---|
id | guid | Id of the Port Row |
msisdn | string | Mobile number |
serialNo | string | SIM serial number |
pac | string | See Terminology |
status | int | Id of the Port Row Status |
statusName | string | Name of the Port Row Status |
message | string or null | Message associated with this row (if any) |
groupName | string | Name of the group this row belongs to |
boltOns | array of int | List of bolt-on IDs applied to this SIM |
tariffId | int | Id for the tariff (see Tariffs / BoltOns / Provisioning Orders) |
tariffName | string | Name of the tariff |
esim | bool | Whether the SIM is an eSIM |
provisioningOrderName | string or null | Name of the provisioning order (when creating a new one) |
provisioningOrder | int or null | ID of the provisioning order (when using an existing one) |
services | array of Services or null | List of services to configure (see Services) |
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"id": "93949676-932c-4c43-140f-08dca4c4f4e2",
"status": 11,
"statusName": "Complete",
"name": "Example Port",
"targetNetworkId": 4,
"targetNetworkName": "Orange (France) LMVNO",
"sourceNetworkId": 34,
"sourceNetworkName": "Bouygues",
"connectionDate": "2024-07-18T00:00:00",
"portType": 2,
"portTypeName": "PortIn",
"rowCount": 1,
"rows": [
{
"id": "8f16f79a-cd5a-40a5-0938-08dca4c4f4ff",
"msisdn": "070000000000",
"serialNo": "2358880040200",
"pac": "84E046866KO2",
"status": 15,
"statusName": "Complete",
"message": null,
"groupName": "Group1",
"boltOns": [
502102
],
"tariffId": 102295,
"tariffName": "Bundle V+D Silver",
"esim": false,
"provisioningOrderName": null,
"provisioningOrder": 9569,
"services": [
{
"name": "admin",
"value": "true"
}
]
}
]
}
Create Port
This method is used to create the initial Port / Migration request.
Request
Name | Type | Description |
---|---|---|
accountId | int | Cellhire account number |
name | string (255) | Name of the Port / Migration |
targetNetworkId | int | Id of the Target Network (see Porting Networks) |
sourceNetworkId | int | Id of the Source Network (see Porting Networks) |
connectionDate | date | Date of the Port / Migration |
portType | string | Type of Port (see Porting Networks) |
rows | array of CreatePortRow | List of rows in this Port / Migration |
Create Port Row
Name | Type | Description |
---|---|---|
groupName | string (255) | Name of the group this row belongs to, should be unique per Tariff + BoltOn + Services configuration |
esim | bool | Whether the SIM is an eSIM |
msisdn | string | Mobile number |
serialNo | string | SIM serial number |
provisioningOrder 1 | int or null | Id of the provisioning order (if using an existing one) (see Tariffs / BoltOns / Provisioning Orders) |
provisioningOrderName 1 | string (255) or null | Name of the provisioning order (if creating new one) |
pac | string | Porting Authorization Code |
tariffId | int | Id of the tariff |
boltOns | array of int | List of bolt-on Ids (see Tariffs / BoltOns / Provisioning Orders) |
services | array of Services or null | List of services (see Services) |
1 - At least one field must be provided.
curl --location 'https://api.cellhire.com/api/porting/{accountId}' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjRBMDlENTFBMDhEOEUxMTU0OTkyODFDN...' \
--data '{
"name": "Example Port",
"targetNetworkId": 2,
"sourceNetworkId": 23,
"connectionDate": "2025-05-02T00:00:00.000Z",
"portType": "PortIn",
"rows": [{
"groupName": "Group1",
"esim": false,
"msisdn": "07000000000",
"serialNo": "1234567890",
"provisioningOrder": 3630,
"provisioningOrderName": null,
"pac": "12345",
"tariffId": 102344,
"boltOns": [502248],
"services": [{
"name": "voice",
"value": "true"
}, {
"name": "voiceRoaming",
"value": "true"
}]
}]
}'
Response
Name | Type | Description |
---|---|---|
portId | guid | Id of the Port / Migration that has been created |
HTTP/1.1 201 Created
Content-Type: application/json
"550e8400-e29b-41d4-a716-446655440000"
Update Port
This method can be used to both update the PAC of a row in the status of PacInvalid
or PacInvalidDate
and also cancel any lines in the status of PacInvalid
, PacInvalidDate
or Submitted
.
If you wish to cancel all lines please use Cancel Port.
Request
Name | Type | Description |
---|---|---|
accountId | int | Cellhire account number |
portId | guid | Id of the Port / Migration |
Rows | array of UpdatePortRow | List of rows to modify |
Update Port Row
Name | Type | Description |
---|---|---|
Msisdn | string | Mobile number being updated or cancelled |
Pac | string or null | Updated PAC (if updating) |
PortRowStatus | string | New status for the port row (Amended or CancellationRequested ) |
curl --request PATCH 'https://api.cellhire.com/api/porting/{accountId}/port/{portId}' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjRBMDlENTFBMDhEOEUxMTU0OTkyODFDN...' \
--data '{
"Rows": [
{
"Msisdn": "07000000000",
"Pac": "PAC12345",
"PortRowStatus": "Amended"
},
{
"Msisdn": "070000000123",
"PortRowStatus": "CancellationRequested"
}
]
}'
Response
HTTP/1.1 202 Accepted
Cancel Port
This method is used to cancel the entire Port / Migration. This can only be done before the port is Locked
.
If the Port / Migration is in status PacCheckFailed
this cancellation will happen immediately.
If the Port / Migration is in the status of Submitted
this will take some time.
Once cancellation has completed the Port / Migration status will become Cancelled
.
Request
Name | Type | Description |
---|---|---|
accountId | int | Cellhire account number |
portId | guid | Id of the Port / Migration |
curl --request DELETE 'https://api.cellhire.com/api/porting/{accountId}/port/{portId}' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjRBMDlENTFBMDhEOEUxMTU0OTkyODFDN...'
Response
HTTP/1.1 202 Accepted
Terminology
- PAC - "Porting Authorisation Code", also known as RIO or "Relevé d'Identité Opérateur" in France, the unique code that allows porting between mobile networks.
- Working Days - Monday to Friday.
FAQ
Why has the Port / Migration has gone from Submitted
, to Cancelled
without a request to process a cancellation?
In some circumstances, a source network provider may reject the request, which can then no longer be processed and will be automatically cancelled. This reason can be seen in the Message
field on the PortRow response of Get Port Details request.
Why do I recieve "The following MSISDN's already exists on our stock records" when calling CreatePort?
When an MSISDN has previously been with Cellhire (and has Ported or Migrated away), our system may need updating to allow the MSISDN to Port / Migrate back in. Please contact your Account Manager to resolve this.
I previously booked a Port / Migration with an invalid PAC. Why can't I book a new Port with the correct PAC?
You will need to cancel the original port before a new Port / Migration can be created for that MSISDN.
I need to change the tariff details, how can I do this?
Either cancel the requested Port / Migration and rebook it - which will need to allow for the minPortDays
. Or, wait until the Port / Migration has completed, and then submit a Change Provision submission.
How long does it take for the Port / Migration to complete on the port date?
Please allow up to 24 hours for all actions to be completed, which will include some loss of connectivity.
How do I add additional rows to an existing Port / Migration?
This is not possible, please create a new Port / Migration for the additional rows.
Why haven't the PacValid
lines on my Port / Migration been submitted to the Network?
Only when all lines on a Port / Migration are in the status of PacValid
or Cancelled
can the request progress. Leaving some lines in any other status will prevent any lines being submitted.