MyComm docs
Menu

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.

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.completed with the link's purpose and line_id to the link's allowed_origins, and the widget fires mycomm-connect:completed (from widget 1.1.0 its detail carries purpose and lineId). Without allowed_origins nothing is posted.
  • Opened directly (you redirected the browser to url): with a return_url, the page offers Continue and goes back there after 3 seconds, adding mycomm_session=<id>&mycomm_status=completed to 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.