Skip to main content

Number Porting

Number porting lets you transfer existing phone numbers from another carrier to DialStack. This guide walks through the full port-in workflow: checking eligibility, creating a port order, approving the order, and tracking it through completion.

Overview

Porting follows a draft-based workflow:

  1. Check eligibility — verify numbers can be ported
  2. Create a draft — provide subscriber details and your requested date and time
  3. Approve — customer approves the port order with their electronic signature
  4. Submit — send the order to the carrier for processing
  5. Track status — monitor until the port completes
draft → approved → submitted → foc (scheduled) → complete
→ exception → (fix + resubmit) → submitted

Prerequisites

  • DialStack API key (sk_live_*)
  • Phone numbers currently active with another US carrier
  • Subscriber details matching the losing carrier's records (name, service address, account number, and PIN as listed on the current carrier's records)

Step 1: Check Eligibility

Before creating a port order, verify that the numbers can be ported. This endpoint is platform-scoped — no DialStack-Account header is needed.

curl -X POST https://api.dialstack.ai/v1/port-in-eligibility \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_numbers": ["+12025551234", "+12025555678"]
}'

Response:

{
"portable_numbers": [
{
"phone_number": "+12025551234",
"losing_carrier_name": "Verizon Wireless",
"losing_carrier_spid": "6006",
"is_wireless": true,
"account_number_required": true
}
],
"non_portable_numbers": [
{
"phone_number": "+12025555678",
"rate_center": "WASHINGT DC",
"city": "Washington",
"state": "DC"
}
]
}

Only numbers listed in portable_numbers can be included in a port order. Check account_number_required — when true, you'll need to include the subscriber's account_number and pin in the port order.

Step 2: Create a Draft Port Order

Create a draft with the subscriber details, phone numbers, and your requested porting date and time. You can control exactly when your numbers transfer by setting requested_foc_date and optionally requested_foc_time (Eastern Time, between 08:00 and 20:00). The date must be at least 5 business days and no more than 30 calendar days from today.

Once the carrier confirms the order, the port will complete at the date and time you requested — so you can plan your cutover with confidence.

curl -X POST https://api.dialstack.ai/v1/port-orders \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41" \
-H "Content-Type: application/json" \
-d '{
"phone_numbers": ["+12025551234"],
"subscriber": {
"btn": "+12025551234",
"business_name": "Smith Consulting",
"approver_name": "Jane Smith",
"account_number": "123456789",
"pin": "1234",
"address": {
"house_number": "123",
"street_name": "Main St",
"city": "Washington",
"state": "DC",
"zip": "20001"
}
},
"requested_foc_date": "2026-03-15",
"requested_foc_time": "10:00"
}'

Response:

{
"id": "port_01jkx...",
"status": "draft",
"details": {
"phone_numbers": ["+12025551234"],
"subscriber": {
"btn": "+12025551234",
"business_name": "Smith Consulting",
"approver_name": "Jane Smith",
"account_number": "123456789",
"pin": "1234",
"address": {
"house_number": "123",
"street_name": "Main St",
"city": "Washington",
"state": "DC",
"zip": "20001"
}
},
"requested_foc_date": "2026-03-15",
"requested_foc_time": "10:00"
},
"submitted_at": null,
"created_at": "2026-02-11T14:00:00Z",
"updated_at": "2026-02-11T14:00:00Z"
}
Subscriber Details

All subscriber fields must match the records on file with the losing carrier. Mismatches are the most common reason for port rejections.

  • BTN (Billing Telephone Number) — the main number on the account
  • Approver name — the name of the person authorized to approve the port
  • Service address — split into house_number and street_name to match the carrier's format
  • Account number and PIN — required for wireless ports (check account_number_required in the eligibility response)

Step 3: Approve the Port Order

Have the customer approve the port order by providing their electronic signature and IP address. This authorizes the transfer of their phone numbers.

curl -X POST https://api.dialstack.ai/v1/port-orders/port_01jkx.../approve \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41" \
-H "Content-Type: application/json" \
-d '{
"signature": "Jane Smith",
"ip": "203.0.113.42"
}'

Response:

{
"id": "port_01jkx...",
"status": "approved",
"details": {
"phone_numbers": ["+12025551234"],
"subscriber": { "...": "..." },
"approval": {
"signature": "Jane Smith",
"ip": "203.0.113.42",
"timestamp": "2026-02-11T14:02:00Z"
},
"requested_foc_date": "2026-03-15",
"requested_foc_time": "10:00"
},
"submitted_at": null,
"created_at": "2026-02-11T14:00:00Z",
"updated_at": "2026-02-11T14:02:00Z"
}

The status transitions from draft to approved. If the order details are updated after approval, the approval is cleared and the status reverts to draft — the customer must approve again.

Step 4: Submit the Order

Once the order is approved, submit it to begin the porting process:

curl -X POST https://api.dialstack.ai/v1/port-orders/port_01jkx.../submit \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41"

Response:

{
"id": "port_01jkx...",
"status": "submitted",
"details": { "...": "..." },
"submitted_at": "2026-02-11T14:05:00Z",
"created_at": "2026-02-11T14:00:00Z",
"updated_at": "2026-02-11T14:05:00Z"
}

The status transitions from approved to submitted. The necessary authorization documents are generated and forwarded to the carrier automatically.

Step 5: Track the Order

Poll the order to check its status. Non-terminal orders are automatically refreshed from the carrier:

curl https://api.dialstack.ai/v1/port-orders/port_01jkx... \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41"

You can also list all port orders, optionally filtering by status:

curl "https://api.dialstack.ai/v1/port-orders?status=submitted" \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41"

Status Reference

StatusDescription
draftOrder created, not yet approved
approvedCustomer has approved the order, ready to submit
submittedSent to the carrier, awaiting processing
exceptionRejected by the carrier — can be corrected and resubmitted
focScheduled — the carrier has confirmed a completion date and time (in telecom, this confirmation is called a Firm Order Commitment, abbreviated FOC). Your numbers will port at the confirmed date and time.
completeNumbers successfully ported and active in DialStack
cancelledOrder was cancelled

Viewing the Audit Trail

Every status change is recorded. View the full history:

curl https://api.dialstack.ai/v1/port-orders/port_01jkx.../events \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41"

Handling Rejections

If the carrier rejects the port (status becomes exception), the rejection details appear in the order:

{
"status": "exception",
"details": {
"rejection": {
"code": "address_mismatch",
"message": "Service address mismatch"
}
}
}

To fix and resubmit, update the order with corrected information:

curl -X POST https://api.dialstack.ai/v1/port-orders/port_01jkx... \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41" \
-H "Content-Type: application/json" \
-d '{
"subscriber": {
"btn": "+12025551234",
"business_name": "Smith Consulting",
"approver_name": "Jane Smith",
"address": {
"house_number": "456",
"street_name": "Oak Ave",
"city": "Washington",
"state": "DC",
"zip": "20002"
}
}
}'

Cancelling an Order

Cancel a port order that hasn't reached a terminal state:

curl -X POST https://api.dialstack.ai/v1/port-orders/port_01jkx.../cancel \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "DialStack-Account: acct_01h2xcejqtf2nbrexx3vqjhp41"

Orders in complete or cancelled status cannot be cancelled.

Common Rejection Reasons

CodeReasonHow to Fix
address_mismatchService address mismatchUpdate the address to match the losing carrier's records
account_number_invalidAccount number requiredContact the losing carrier for your account number
name_mismatchApprover name mismatchUse the exact name on file with the losing carrier
business_name_mismatchBusiness name mismatchUse the business name from the carrier's Customer Service Record (CSR), which may differ from the name on the bill
btn_mismatchBTN mismatchVerify the billing telephone number with the losing carrier
pin_requiredPIN requiredContact the losing carrier to get the PIN or passcode for the account, then include it in the pin field
pin_invalidPIN invalidThe PIN provided doesn't match the carrier's records — contact the losing carrier to verify the correct PIN and update the order

Error Handling

StatusErrorDescription
400Validation errorsInvalid phone numbers, bad date format, etc.
404Port order not foundOrder doesn't exist or belongs to a different account
409Invalid stateOperation not allowed in the order's current status
422Approval requiredMust approve the order before submitting