Phones
Hosted connect and the widget
Let your users pair their own phone from your page, without an API key in the browser.
If your product has users who each bring their own phone, send them to MyComm's hosted connect page instead of building a pairing screen. Your server asks for a hosted link for one of your lines; the browser only ever sees the link's URL.
1. Create a link on your server#
POST /v1/lines/{id}/links needs links:write and an account key that sees the line. A partner uses
POST /partner/v1/lines/{id}/links with its partner key (partners).
curl -sS -X POST "$MYCOMM_URL/v1/lines/$LINE_ID/links" \
-H "Authorization: Bearer $MYCOMM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"purpose": "add_channel",
"return_url": "https://app.example.com/settings/sms",
"allowed_origins": ["https://app.example.com"],
"ttl": 1800
}'
| Field | Meaning |
|---|---|
purpose |
What the page does: connect (the line's first phone), add_channel (one more SIM for the line), replace_device (a new phone for a lost one, named in replaces_device_id), manage, claim. |
allowed_origins |
The origins (https://host[:port], no path, up to five) that may frame the page and receive its outcome. null means no framing and no messages. |
return_url |
An https URL the page goes back to when it was opened directly, not by the widget. See how it ends. |
ttl |
Seconds until the link stops working: 300 to 3600, default 1800. |
locale |
Language of the page, a BCP 47 tag; defaults to the account's. ur (or ur-PK) shows the page in Urdu, right to left; ur-Latn in Roman Urdu; any other tag in English. |
replaces_device_id |
Only for replace_device: an active phone of the line's account. |
With the SDKs: $mycomm->lines->links->create($lineId, purpose: 'add_channel', return_url: ..., allowed_origins: [...])
(PHP; a partner uses $partner->partner->lines->links->create(...)), mycomm.lines.links.create(lineId, {...}) (Node).
In Laravel, <x-mycomm-connect :line="$lineId" purpose="add_channel" /> creates the link for the current page
(return_url the page, allowed_origins its origin) and renders the widget.
The answer includes url, which is only returned here. It is a bearer credential for one user: create a link per visit,
do not log the URL and do not put it in a URL of your own. At most 20 links are open per line
(422 CONNECT_SESSION_LIMIT_REACHED) and 60 are created per line per hour. A link works only for its own line: archiving or
detaching the line ends its links.
2. Show the page#
Either redirect the browser to url, or show it with the @mycomm/connect widget, which opens it in a popup or an iframe and
tells your page how it ended. Install and options are on the widget page.
On the page the user pairs a phone (or picks one the account already has), chooses its SIM and verifies the number. The number joins the link's line: as its sender when it has none, else as its last backup.
How it ends#
When the number is verified, the link becomes completed with its device_id and channel_id, and the page says the phone
is connected. A replace_device link completes once every number of the replaced phone on the line verified on the new phone.
Then:
- Opened by the widget (popup or iframe): the page posts
mycomm.connect.completedwith the link'spurposeandline_idto the link'sallowed_origins, and the widget firesmycomm-connect:completed(from widget 1.1.0 its detail carriespurposeandlineId). Withoutallowed_originsnothing is posted. - Opened directly (you redirected the browser to
url): with areturn_url, the page offers Continue and goes back there after 3 seconds, addingmycomm_session=<id>&mycomm_status=completedto its query (your own query and fragment are kept).
Cancel and go back on any step does the same with mycomm.connect.cancelled (or mycomm_status=cancelled). It is shown
only when the page has someone to tell or somewhere to go back to, and the link stays open, so it still works until it
expires or you revoke it.
3. Confirm on your server#
A browser event says what the user did; it is not proof. Confirm with GET /v1/links/{id}: status is open,
completed, revoked or expired (it reads expired once expires_at has passed), and a completed link carries the
device_id and channel_id that were connected. The device.paired and channel.connected webhook events tell you too.
In the SDKs: $mycomm->links->get($id) (PHP), mycomm.links.get(id) (Node); a partner uses partner->links->get($id).
Revoke a link you no longer want to be used with DELETE /v1/links/{id} (links->revoke($id) in the SDKs).
When the user does not finish#
A link that nobody completes just expires. Opening it after that, or after it was revoked or used, shows a page that
says the link has ended (410) and tells the widget why (expired, revoked or completed_elsewhere). If the page is shown in a frame that the browser blocks (some browsers refuse
third-party cookies), the hosted page asks for a popup instead, and the widget opens one.