# OIT/PacketDial Client Onboarding Checklist (reusable template)

Reusable runbook for onboarding a new client to VoIP on the **OIT/PacketDial (NetSapiens)**
platform with **Yealink YMCS** device management. Structured on the NetSapiens 17-step
white-label onboarding flow (voipdocs.io/onboarding-recommendations), annotated with the
ACG/OIT specifics and gotchas learned in the field.

**How to use:** copy this file to `clients/<slug>/voip/ONBOARDING-CHECKLIST.md`, fill the
placeholders, and work the boxes. Keep client-specific detail in the client copy; keep this
template generic.

Legend: `[x]` done · `[ ]` not started · `[~]` in progress · `[?]` verify

---

## Key references (fill per client)

| Item | Value |
|---|---|
| Client / slug | `<name>` / `<slug>` |
| PacketDial domain | `<domain>.<reseller>.service` |
| Reseller | `91912.service` (ACG) |
| Main number | `<E.164 / 10-digit>` |
| Timezone / dial policy | `America/Phoenix` / `US and Canada` |
| **RPS provisioning URL** | `http://ndp.ucaasnetwork.com/cfg` (OIT/PacketDial) |
| YMCS site / site ID | `<site name>` / `<site id>` |
| E911 address ID | `<a-...>` |
| Credentials | vault `msp-tools/oitvoip-provisioning.sops.yaml` (Prov_Admin) + `msp-tools/oitvoip.sops.yaml` (reseller API key) |

---

## Client intake / prep (steps 1-8)

- [ ] **1. Welcome correspondence** sent to the client.
- [ ] **2. Payment authorization (CC/ACH)** on file — NetSapiens flags this as the prerequisite for every step after. Do not go live without it.
- [ ] **3. Service start timing** decided — port-dependent (wait for numbers) or immediate with temporary numbers.
- [ ] **4. Recent billing docs** collected from the current carrier (bill copy / CSR) for the port.
- [ ] **5. Numbers-to-port list** — every DID + its intended purpose (main line, fax, direct dials).
- [ ] **6. User roster** — names, contact info, desired extensions, voicemail-to-email preference. Match to the client's M365 tenant where possible (emails drive vmail delivery).
- [ ] **7. Equipment source + MAC addresses** — who supplies phones (ACG vs client), models, tracking, and **MACs** (Yealink RPS + YMCS bind key on the MAC).
- [ ] **8. Client orientation call** scheduled/held.

## Platform build-out (steps 9-17)

- [ ] **9. Billing account / domain** created under the ACG reseller (`<domain>.<reseller>.service`), timezone + dial policy set.
- [ ] **10. Port application** submitted (after steps 4-5); track FOC date.
- [ ] **11. Domain infrastructure** configured — domain settings, dial plan, main caller ID.
- [ ] **12. DID numbers** created and ready to route.
- [ ] **13. User accounts** registered. For >5 users use the **CSV bulk import** (PacketDial: Domains → `<domain>` → Users → Import). Create **users only, no devices** — assign devices later as phones are physically distributed.
- [ ] **14. Auto-attendants + call queues** built (reception queue, main AA; add dept queues as needed).
- [ ] **15. Number routing** configured — point DIDs at the AA/queue; add business-hours vs after-hours **timeframes** for time-based routing.
- [ ] **16. E911 / emergency services** activated — register the physical service address, capture the E911 address ID, confirm each device/extension maps to a valid address.
- [ ] **17. Hardware deployed** — provision + register each phone (device-assignment workflow below).

---

## Per-phone device-assignment workflow (step 17 detail)

Users are created without SIP devices; bind a device to a user when the physical phone is handed out.

1. **User provides the last 4 of the phone's MAC.**
2. **Create the SIP device in PacketDial** (auto-generates the SIP registration password):
   ```bash
   bash .claude/scripts/py.sh ns.py create-device <domain> <ext> \
     --body '{"device": "sip:<ext>a@<domain>"}' --confirm
   ```
3. **Read the SIP password** back from the device (`device-sip-registration-password`).
4. **Create the YMCS SIP account** with that password, pointing `sipServer1.host` at `pbx.packetdial.com:5060` and `siteId` at the client's YMCS site.
5. **Find the physical phone** in YMCS by the last-4 MAC (`ymcs.py devices | grep <last4>`).
6. **Bind** the account to the phone (`/v2/dm/devices/{id}/bindAccounts`) and **reboot** to apply.

Detailed commands: copy the client's `DEVICE-ASSIGNMENT-COMMANDS.md` (see the VWP example).

---

## Gotchas learned in the field

- **TWO whitelabel accounts — use the right RPS URL.** ACG has both Whitelabel Communication (WLC, `ftp://p.packetdials.net`) and OIT/PacketDial (`http://ndp.ucaasnetwork.com/cfg`). A phone provisioned against the wrong RPS URL stays **unregistered** with otherwise-correct SIP creds. OIT clients MUST use `http://ndp.ucaasnetwork.com/cfg`. (Root cause of the VWP registration failure, 2026-07-09.)
- **YMCS `sipServer1` schema is strict.** The SIP-account create expects `sipServer1` as an object (`{"host": ..., "port": 5060}`), not a string; a bad shape returns HTTP 412 "Parameter error". Confirm against `.claude/skills/yealink-ymcs/docs/SIPSERVER_SCHEMA.md`.
- **Match extensions to M365 by email** so voicemail-to-email lands correctly; park unmatched/shared extensions (kitchen, conference, warehouse) and confirm names with the client before creating accounts.
- **Bulk import = users only.** Import creates users without devices by design; devices are bound per-phone at hand-out. This keeps unassigned phones from registering to the wrong person.

## Tooling & support

- **Skills:** `.claude/skills/packetdial/` (PacketDial/NetSapiens API — `ns.py`), `.claude/skills/yealink-ymcs/` (YMCS — `ymcs.py`)
- **Credentials:** vault `msp-tools/oitvoip*.sops.yaml`
- **PacketDial UI:** https://pbx.packetdial.com/ · **API:** `https://pbx.packetdial.com/ns-api/v2` (fallback `https://api.ucaasnetwork.com/ns-api/v2`) · **docs:** https://docs.ns-api.com
- **YMCS UI:** https://us.ymcs.yealink.com/
- **OIT support:** support@oitvoip.com · **Onboarding best-practices:** https://voipdocs.io/onboarding-recommendations
- **Worked example:** `clients/valleywide/voip/` (Valley Wide Plastering)
