Howto: zipcode() and order_connection()

This API is designed to make the order process as simple and fail-safe as possible.

Ordering a connection should not take more than two function calls. You first call zipcode() and you use its output to find the parameters for order_connection().

In between your application should allow the customer to make a selection of the products they wish to order. How to present the products and how you let the customer choose is of no concern to this tutorial. It simply assumes that the customer has made a choice.

But what parameters do you select from the zipcode() output and why? This how-to tries to answer that.

Getting data

Note

This tutorial focusses on the KPN WBA provider as this is most commonly ordered. For the other providers the process is identical but you will probably have less data to copy.

So with the zipcode and house number provided by the customer you can call zipcode():

curl -s -u 'user:pass' https://api.nextpertise.nl/broadband/v1 -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "zipcode",
    "params": {
        "zipcode": "0000??",
        "housenr": 1
    }
}' | jq .

For brevity I only show the relevant portions of the output as it relates to the parameters of order_connection().

order_connection() requires these parameters:

{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "order_connection",
    "params": {
        "zipcode": "0000??",
        "housenr": 1,

        "company": "",
        "contact_name": "",
        "contact_phonenumber": "",

        "custwishdate": "",

        "isra": "",
        "carrier": ,
        "sla": ,
        "cpe": [],
        "circuit": [{"circuit": , "vlan": }],

        "confirm": {
            "Terminate Voice": false
        },

        "requested_phonenumber": "",
        "serviceid": ""
    }
}

Clearly zipcode and housenr (and housenrext where relevant) should not pose a problem. They are identical to the parameters used in zipcode().

Likewise the fields company, contact_name and contact_phonenumber should specify the contact details at the location. custwishdate is the preferred service delivery date, when left blank that will be as soon as possible.

With the isra field it gets more interesting. order_connection()’s isra field must be set to one of the available connection points in the zipcode() output:

{
    "result": {
        "available": {
            "KPNWBA": {
                "connectionpoint": {
                    "001//WKL/WKL": {
                        "nl2lines": 0,
                        "nl1lines_available": 0,
                        "BVDSL": [137, 136],
                        "available_technology": ["ADSL", "VDSL", "BVDSL", "SDSL"],
                        "nl1lines": 2,
                        "VDSL": [121, 126, 120, 124, 118, 119, 127],
                        "available_service": [
                            {"phonenumber": "048......0", "service": "0000??000010100"},
                            {"phonenumber": "048......1", "service": null}
                        ],
                        "SDSL": [132, 129, 131, 128],
                        "ADSL": [613, 618, 612, 616, 610, 611, 619]
                    }
                }
            }
        }
    }
}

As there is only one connection point at this location the isra field should be set to 001//WKL/WKL.

The fields nl1lines, nl1lines_available and nl2lines tell you:

  • the total number of available lines;

  • the number of unallocated lines;

  • the number of lines that can be made available in reasonable time and limited costs.

The field available_service tells you something about the assigned lines (the difference between nl1lines and nl1lines_available). These lines may be used by telephone service, data service or both. A line with a telephone number is still usable to add a data service; this requires a ‘shared’ carrier as in the following example. A line with a data service can be taken (if the current owner permits it), these are the ‘migration’ carriers you can select. By which you acquire ownership and control of the line.

Let’s assume the customer wants a VDSL type connection there are several candidate carriers. The customer wants a shared, NLS1 line with Test & Labeling:

{
    "result": {
        "available": {
            "KPNWBA": {
                "carrier": {
                    "121": {
                        "terminate_voice": false,
                        "area": "",
                        "product_id": 121,
                        "name": "VDSL (shared line, NLS1 TL)",
                        "carrier_type": "Copper_shared",
                        "circuits": [267, 268, 272, 313, 332, 652, 249, 253, 255],
                        "data_technology": "VDSL",
                        "extrainfo": null,
                        "distance": "NLS1;TL",
                        "cpe": [651],
                        "actions": {},
                        "upload": 8750,
                        "download": 55000,
                        "prices": {},
                        "sla": [606, 607, 608],
                        "description": null
                    }
                }
            }
        }
    }
}

So order_connection()’s carrier field can be set to 121. Additionally the SLA and CPE products can be selected from the data provided by this carrier. Selecting an SLA is required and the customer can choose from the list of SLAs in the carrier declaration. The customer chose the Best Effort SLA. So the sla field is set to 606.

{
    "result": {
        "available": {
            "KPNWBA": {
                "sla": {
                    "606": {
                        "name": "Best Effort SLA",
                        "description": null,
                        "extrainfo": null,
                        "actions": {},
                        "prices": {},
                        "product_id": 606
                    }
                }
            }
        }
    }
}

The CPE is optional and the customer doesn’t need a wall outlet (currently the only available cpe). So the cpe can be left out or set to an empty list.

The selected carrier also lists the circuits that can be ordered in combination with this carrier. To make a succesful order one of these must be selected.

{
    "result": {
        "available": {
            "KPNWBA": {
                "EVC": {
                    "313": {
                        "max_upload": 20480,
                        "product_id": 313,
                        "overbooking": 0,
                        "extrainfo": null,
                        "actions": {},
                        "name": "Regular Circuit 100Mb/20Mb",
                        "max_download": 102400,
                        "prices": {},
                        "min_upload": 0,
                        "min_download": 0,
                        "quality": "regular",
                        "description": null
                    }
                }
            }
        }
    }
}

It is possible to select multiple circuits for a carrier from the list of allowable circuits. Therefore the circuit field in order_connection() is an array allowing you to enter multiple circuits.

You are restricted in the combinations you are allowed to make. These are currently not validated when you enter your order but the backend provider may refuse to implement the order when the restrictions are violated.

So let’s start creating the order based on all data collected so far:

{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "order_connection",
    "params": {
        "zipcode": "0000??",
        "housenr": 1,

        "company": "....",
        "contact_name": "....",
        "contact_phonenumber": "....",

        "isra": "001//WKL/WKL",
        "carrier": 121,
        "sla": 606,
        "cpe": [],
        "circuit": [{"circuit": 313, "vlan": 6}],

        "confirm": {
            "Terminate Voice": false
        },

        "requested_phonenumber": "048......1",
        "serviceid": null
    }
}

The company, contact_name and contact_phonenumber are needed by the provider to know who to contact on-premise in case this is necessary. Generally, you do not want to put your own contact information here.

There are two kinds of circuits:

  • Fiber and (bonded) VDSL: these need a vlan number;

  • ADSL and SDSL: these need vpi/vci numbers.

Each circuit in this connection should have its own vlan of vpi/vci number. We usually start numbering vlans at 6 and number consecutively from there but you are free to implement your own number scheme.

The confirm field is used as a safeguard. On a shared line, as is the case here, it is possible that your order terminates the voice telephone connection. To do that you would have to order a non-shared line carrier, not the case here, and set the Terminate Voice field to True.

Finally since this is a shared line you must provide the telephone number to identify the specific connection that is going to share the data connections that you are ordering.

If you were migrating an existing connection you should provide its service id in the serviceid field. Migrating a shared line therefore requires that you provide both the telephone number and the service id.