KeepMyNumber
Home Sign in

Getting started

Port your first number in five steps. Everything on this platform is API-first: anything you can do, you can do with an HTTP call and your API key.

1. Get your API key

Your account and first API key are issued by the platform team. The key looks like pk_live_… and is shown once — store it in a secret manager. Pass it on every request:

curl https://api.example.com/v2/account \
  -H "Authorization: Bearer pk_live_YOUR_KEY"

You can create additional keys (e.g. one per environment) with POST /v2/api_keys and revoke them with DELETE /v2/api_keys/{id}.

2. Register a webhook URL

Porting is asynchronous — orders progress over hours or days. Register a URL so we can push you every status change instead of you polling:

curl -X POST https://api.example.com/v2/webhook_endpoints \
  -H "Authorization: Bearer pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://yourapp.com/hooks/porting"}'

The response contains a secret (shown once). Use it to verify the Porting-Signature header on every delivery — see the Webhooks guide.

3. Check portability

Always check before ordering. The response tells you, per number: whether it can be ported, its country and type, the current carrier, and which provider will handle it.

curl -X POST https://api.example.com/v2/portability_checks \
  -H "Authorization: Bearer pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone_numbers": ["+14155552671", "+447912345678"]}'

Numbers must be in E.164 format (+ followed by country code and number).

Want to know what porting a number will require — before opening anything? Ask with the number itself; the response is the full checklist (fields, documents, LOA text) for its route:

curl "https://api.example.com/v2/porting/requirements?phone_number=%2B447912345678" \
  -H "Authorization: Bearer pk_live_YOUR_KEY"

4. Open an order, fill it in, submit

Create a draft order — the phone numbers are all it takes. The response carries the order's requirements: one array with everything you need to provide — account holder name, service address, account number, plus the documents legally required for its country and number type. Each has a slug and a field_type (textual, address, document or signature):

curl -X POST https://api.example.com/v2/porting_orders \
  -H "Authorization: Bearer pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone_numbers": ["+447912345678"]}'

The response is an array of draft orders — one request can split into several (see Port-in orders). Fulfill each requirement at your own pace with PATCH …/requirements/{slug} (e.g. …/requirements/auth_person_name): text fields take the value directly, the service address (…/requirements/location) takes an address object, documents take the file itself (multipart — or the id of a file uploaded earlier via POST /v2/documents), and the LOA (…/requirements/loa) takes the end user's drawn signature as a base64 PNG — you never write, render or upload an LOA; the localized LOA text to display ships on the requirement itself. Sign the LOA last: the platform renders it from the other fields.

When you think you are done, ask the platform what (if anything) is still missing, then submit:

curl "https://api.example.com/v2/porting_orders/{id}/readiness" \
  -H "Authorization: Bearer pk_live_YOUR_KEY"
curl -X POST "https://api.example.com/v2/porting_orders/{id}/submit" \
  -H "Authorization: Bearer pk_live_YOUR_KEY"

Every request and response of this flow is shown in the Porting walkthrough; the endpoint list lives in the Porting endpoint reference.

Try it without writing code: the dashboard's Test Client runs this exact flow with your account — every API call logged with its request, response and status — so you can see where a document upload or field fails before you integrate. Keep the test order at the end and our team can review it, approving or rejecting individual fields, and you'll see the rejection reason appear on the order.

5. Watch it complete

From submission on, we push webhooks: porting_order.status_changed at every step, and number.activated when a number goes live. Your numbers then appear in the registry:

curl https://api.example.com/v2/numbers -H "Authorization: Bearer pk_live_YOUR_KEY"

What next