How it is set up
Test numbering list
Stands in for Ofcom's S1–S9 lists plus the PSTN2 Range Holder URL field.
Test CP A
The Range Holder for 07700 900 0xx. It has ported 07700 900003 out to Test CP B.
https://pstn2.org/testcp/a · keys
Test CP B
The Range Holder for 07700 900 1xx. It holds 07700 900003, which was ported in from A.
https://pstn2.org/testcp/b · keys
All numbers come from Ofcom's reserved drama range 07700 900xxx, so they never belong to real subscribers. This is a test list, not Ofcom data. The host is static, so only Number Discovery is available here. Authentication and routing are exercised against the local mock network in the test harness download.
Test numbers
| E.164 | National | Expected result |
|---|---|---|
+447700900001 | 07700 900001 | held by Test CP A (unported) |
+447700900002 | 07700 900002 | held by Test CP A (unported) |
+447700900003 | 07700 900003 | Test CP A redirects -> held by Test CP B (ported) |
+447700900004 | 07700 900004 | held by Test CP A; querying Test CP B directly returns not_held + invalidate (stale-cache test) |
+447700900101 | 07700 900101 | held by Test CP B (unported) |
+447700900099 | 07700 900099 | 404 from Test CP A (not in service) |
Try it
Query the Range Holder for a ported number. You get a redirect to Test CP B:
curl -A "pstn2-curl/1.1" https://pstn2.org/testcp/a/pstn2/v1/numbers/447700900003
Follow it:
curl -A "pstn2-curl/1.1" https://pstn2.org/testcp/b/pstn2/v1/numbers/447700900003
Always send a descriptive User-Agent. The host's firewall rejects the default curl/* and Go-http-client/* agents. The SDKs send pstn2-<language>-sdk/1.1.0.
With the SDKs
# TypeScript
cd code/typescript && npm install && PSTN2_NETWORK=live npm run example:05
# Python
cd code/python && pip install -e . && PSTN2_NETWORK=live python examples/05_number_discovery.py
# Go
cd code/go && PSTN2_NETWORK=live go run ./examples/05-number-discovery
The algorithm you are testing
- Cache: if you hold an unexpired answer for the number, query that CP directly.
- Numbering list: find the block by longest prefix. That gives you the Range Holder and its URL.
- Range Holder:
GET {url}/pstn2/v1/numbers/{digits}. The answer isheld, or aredirectto the CP the number was ported to. - Retry at the CP named in the redirect. Stop after 5 hops, and stop if you reach the same CP twice.
- Cache the answer for
cache.ttlseconds. If any later response saysnot_heldwithcache.invalidate, purge the entry and start again from step 2.
Signatures: every answer is signed with Ed25519 over the canonical JSON of the body without the signature field (keys sorted, no whitespace). Verify it with the key named by kid at {url}/pstn2/v1/keys. Full details are in the specification, §9 Number Discovery.