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:
- Check eligibility — verify numbers can be ported
- Create a draft — provide subscriber details and your requested date and time
- Approve — customer approves the port order with their electronic signature
- Submit — send the order to the carrier for processing
- 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"
}
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_numberandstreet_nameto match the carrier's format - Account number and PIN — required for wireless ports (check
account_number_requiredin 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
| Status | Description |
|---|---|
draft | Order created, not yet approved |
approved | Customer has approved the order, ready to submit |
submitted | Sent to the carrier, awaiting processing |
exception | Rejected by the carrier — can be corrected and resubmitted |
foc | Scheduled — 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. |
complete | Numbers successfully ported and active in DialStack |
cancelled | Order 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
| Code | Reason | How to Fix |
|---|---|---|
address_mismatch | Service address mismatch | Update the address to match the losing carrier's records |
account_number_invalid | Account number required | Contact the losing carrier for your account number |
name_mismatch | Approver name mismatch | Use the exact name on file with the losing carrier |
business_name_mismatch | Business name mismatch | Use the business name from the carrier's Customer Service Record (CSR), which may differ from the name on the bill |
btn_mismatch | BTN mismatch | Verify the billing telephone number with the losing carrier |
pin_required | PIN required | Contact the losing carrier to get the PIN or passcode for the account, then include it in the pin field |
pin_invalid | PIN invalid | The PIN provided doesn't match the carrier's records — contact the losing carrier to verify the correct PIN and update the order |
Error Handling
| Status | Error | Description |
|---|---|---|
| 400 | Validation errors | Invalid phone numbers, bad date format, etc. |
| 404 | Port order not found | Order doesn't exist or belongs to a different account |
| 409 | Invalid state | Operation not allowed in the order's current status |
| 422 | Approval required | Must approve the order before submitting |
Related Resources
- API Reference — Number Porting — Complete endpoint documentation
- Phone Numbers — Managing active phone numbers