curl --request POST \
--url https://api.member.dev/api/v1/contact-auth/handoff/launches \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/vnd.api+json' \
--data '
{
"data": {
"attributes": {
"destination_path": "<string>",
"hub_id": "<string>",
"purpose": "view"
},
"type": "hub_handoff_launches"
}
}
'import requests
url = "https://api.member.dev/api/v1/contact-auth/handoff/launches"
payload = { "data": {
"attributes": {
"destination_path": "<string>",
"hub_id": "<string>",
"purpose": "view"
},
"type": "hub_handoff_launches"
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/vnd.api+json'},
body: JSON.stringify({
data: {
attributes: {destination_path: '<string>', hub_id: '<string>', purpose: 'view'},
type: 'hub_handoff_launches'
}
})
};
fetch('https://api.member.dev/api/v1/contact-auth/handoff/launches', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.member.dev/api/v1/contact-auth/handoff/launches",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
'attributes' => [
'destination_path' => '<string>',
'hub_id' => '<string>',
'purpose' => 'view'
],
'type' => 'hub_handoff_launches'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/vnd.api+json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.member.dev/api/v1/contact-auth/handoff/launches"
payload := strings.NewReader("{\n \"data\": {\n \"attributes\": {\n \"destination_path\": \"<string>\",\n \"hub_id\": \"<string>\",\n \"purpose\": \"view\"\n },\n \"type\": \"hub_handoff_launches\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/vnd.api+json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.member.dev/api/v1/contact-auth/handoff/launches")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.body("{\n \"data\": {\n \"attributes\": {\n \"destination_path\": \"<string>\",\n \"hub_id\": \"<string>\",\n \"purpose\": \"view\"\n },\n \"type\": \"hub_handoff_launches\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.member.dev/api/v1/contact-auth/handoff/launches")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/vnd.api+json'
request.body = "{\n \"data\": {\n \"attributes\": {\n \"destination_path\": \"<string>\",\n \"hub_id\": \"<string>\",\n \"purpose\": \"view\"\n },\n \"type\": \"hub_handoff_launches\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"attributes": {
"deadline": "2023-11-07T05:31:56Z",
"expires_at": "2023-11-07T05:31:56Z",
"launch_id": "<string>",
"purpose": "view",
"start_url": "<string>",
"target_origin": "<string>"
},
"id": "<string>",
"type": "hub_handoff_launches"
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"ctx": {},
"input": "<unknown>"
}
]
}Launch Hub Handoff
Start a hub handoff for a verified User whose hub Contact link is proven.
Writes a one-use launch that snapshots the User, hub, destination and purpose. The hub page registers its browser against it before any code exists.
A team owner with no link yet is linked here to the hub’s owner or admin Contact when both emails are verified and identical and the User’s email proof is newer than any proof on the Contact. When only that last rule fails, the answer is 403 contact_identity_confirmation_sent: a one-time link is emailed to the shared address. meta.email_sent is false when this hub’s launch in the last 5 minutes already answered with one; meta.expires_at is when the live link expires and meta.resend_available_at is when opening the hub again can send a new one. An address gets at most 3 of these emails in 15 minutes across all Users and hubs; a launch over that limit sends nothing, but it and the launches after it answer exactly as a send would (the same email_sent and times), so the answer never reveals other accounts’ emails. The wording is conditional for that reason. The signed-in User completes it with POST /api/contact-auth/identity-link-confirmations. Every other refusal, including an account already linked elsewhere, is 403 contact_identity_link_required, with no email.
curl --request POST \
--url https://api.member.dev/api/v1/contact-auth/handoff/launches \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/vnd.api+json' \
--data '
{
"data": {
"attributes": {
"destination_path": "<string>",
"hub_id": "<string>",
"purpose": "view"
},
"type": "hub_handoff_launches"
}
}
'import requests
url = "https://api.member.dev/api/v1/contact-auth/handoff/launches"
payload = { "data": {
"attributes": {
"destination_path": "<string>",
"hub_id": "<string>",
"purpose": "view"
},
"type": "hub_handoff_launches"
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/vnd.api+json'},
body: JSON.stringify({
data: {
attributes: {destination_path: '<string>', hub_id: '<string>', purpose: 'view'},
type: 'hub_handoff_launches'
}
})
};
fetch('https://api.member.dev/api/v1/contact-auth/handoff/launches', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.member.dev/api/v1/contact-auth/handoff/launches",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
'attributes' => [
'destination_path' => '<string>',
'hub_id' => '<string>',
'purpose' => 'view'
],
'type' => 'hub_handoff_launches'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/vnd.api+json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.member.dev/api/v1/contact-auth/handoff/launches"
payload := strings.NewReader("{\n \"data\": {\n \"attributes\": {\n \"destination_path\": \"<string>\",\n \"hub_id\": \"<string>\",\n \"purpose\": \"view\"\n },\n \"type\": \"hub_handoff_launches\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/vnd.api+json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.member.dev/api/v1/contact-auth/handoff/launches")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.body("{\n \"data\": {\n \"attributes\": {\n \"destination_path\": \"<string>\",\n \"hub_id\": \"<string>\",\n \"purpose\": \"view\"\n },\n \"type\": \"hub_handoff_launches\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.member.dev/api/v1/contact-auth/handoff/launches")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/vnd.api+json'
request.body = "{\n \"data\": {\n \"attributes\": {\n \"destination_path\": \"<string>\",\n \"hub_id\": \"<string>\",\n \"purpose\": \"view\"\n },\n \"type\": \"hub_handoff_launches\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"attributes": {
"deadline": "2023-11-07T05:31:56Z",
"expires_at": "2023-11-07T05:31:56Z",
"launch_id": "<string>",
"purpose": "view",
"start_url": "<string>",
"target_origin": "<string>"
},
"id": "<string>",
"type": "hub_handoff_launches"
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"ctx": {},
"input": "<unknown>"
}
]
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Show child attributes
Show child attributes
Response
Successful Response
Show child attributes
Show child attributes