curl --request POST \
--url https://api.isnap.ai/v1/chats/{chat_id}/share-contact-card \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"first_name": "<string>",
"last_name": "<string>",
"avatar_url": "<string>",
"phone_numbers": [
"<string>"
],
"emails": [
"jsmith@example.com"
],
"organization": "<string>",
"note": "<string>",
"ignore_quiet_hours": true
}
'import requests
url = "https://api.isnap.ai/v1/chats/{chat_id}/share-contact-card"
payload = {
"first_name": "<string>",
"last_name": "<string>",
"avatar_url": "<string>",
"phone_numbers": ["<string>"],
"emails": ["jsmith@example.com"],
"organization": "<string>",
"note": "<string>",
"ignore_quiet_hours": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
first_name: '<string>',
last_name: '<string>',
avatar_url: '<string>',
phone_numbers: ['<string>'],
emails: ['jsmith@example.com'],
organization: '<string>',
note: '<string>',
ignore_quiet_hours: true
})
};
fetch('https://api.isnap.ai/v1/chats/{chat_id}/share-contact-card', 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.isnap.ai/v1/chats/{chat_id}/share-contact-card",
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([
'first_name' => '<string>',
'last_name' => '<string>',
'avatar_url' => '<string>',
'phone_numbers' => [
'<string>'
],
'emails' => [
'jsmith@example.com'
],
'organization' => '<string>',
'note' => '<string>',
'ignore_quiet_hours' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/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.isnap.ai/v1/chats/{chat_id}/share-contact-card"
payload := strings.NewReader("{\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"avatar_url\": \"<string>\",\n \"phone_numbers\": [\n \"<string>\"\n ],\n \"emails\": [\n \"jsmith@example.com\"\n ],\n \"organization\": \"<string>\",\n \"note\": \"<string>\",\n \"ignore_quiet_hours\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/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.isnap.ai/v1/chats/{chat_id}/share-contact-card")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"avatar_url\": \"<string>\",\n \"phone_numbers\": [\n \"<string>\"\n ],\n \"emails\": [\n \"jsmith@example.com\"\n ],\n \"organization\": \"<string>\",\n \"note\": \"<string>\",\n \"ignore_quiet_hours\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.isnap.ai/v1/chats/{chat_id}/share-contact-card")
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/json'
request.body = "{\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"avatar_url\": \"<string>\",\n \"phone_numbers\": [\n \"<string>\"\n ],\n \"emails\": [\n \"jsmith@example.com\"\n ],\n \"organization\": \"<string>\",\n \"note\": \"<string>\",\n \"ignore_quiet_hours\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"message_id": "<string>",
"chat_id": "<string>",
"attachment_id": "<string>",
"status": "queued"
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}Send a contact card
Builds a contact card from the fields of the request and sends it to the contact of a chat as a message.
curl --request POST \
--url https://api.isnap.ai/v1/chats/{chat_id}/share-contact-card \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"first_name": "<string>",
"last_name": "<string>",
"avatar_url": "<string>",
"phone_numbers": [
"<string>"
],
"emails": [
"jsmith@example.com"
],
"organization": "<string>",
"note": "<string>",
"ignore_quiet_hours": true
}
'import requests
url = "https://api.isnap.ai/v1/chats/{chat_id}/share-contact-card"
payload = {
"first_name": "<string>",
"last_name": "<string>",
"avatar_url": "<string>",
"phone_numbers": ["<string>"],
"emails": ["jsmith@example.com"],
"organization": "<string>",
"note": "<string>",
"ignore_quiet_hours": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
first_name: '<string>',
last_name: '<string>',
avatar_url: '<string>',
phone_numbers: ['<string>'],
emails: ['jsmith@example.com'],
organization: '<string>',
note: '<string>',
ignore_quiet_hours: true
})
};
fetch('https://api.isnap.ai/v1/chats/{chat_id}/share-contact-card', 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.isnap.ai/v1/chats/{chat_id}/share-contact-card",
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([
'first_name' => '<string>',
'last_name' => '<string>',
'avatar_url' => '<string>',
'phone_numbers' => [
'<string>'
],
'emails' => [
'jsmith@example.com'
],
'organization' => '<string>',
'note' => '<string>',
'ignore_quiet_hours' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/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.isnap.ai/v1/chats/{chat_id}/share-contact-card"
payload := strings.NewReader("{\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"avatar_url\": \"<string>\",\n \"phone_numbers\": [\n \"<string>\"\n ],\n \"emails\": [\n \"jsmith@example.com\"\n ],\n \"organization\": \"<string>\",\n \"note\": \"<string>\",\n \"ignore_quiet_hours\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/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.isnap.ai/v1/chats/{chat_id}/share-contact-card")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"avatar_url\": \"<string>\",\n \"phone_numbers\": [\n \"<string>\"\n ],\n \"emails\": [\n \"jsmith@example.com\"\n ],\n \"organization\": \"<string>\",\n \"note\": \"<string>\",\n \"ignore_quiet_hours\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.isnap.ai/v1/chats/{chat_id}/share-contact-card")
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/json'
request.body = "{\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"avatar_url\": \"<string>\",\n \"phone_numbers\": [\n \"<string>\"\n ],\n \"emails\": [\n \"jsmith@example.com\"\n ],\n \"organization\": \"<string>\",\n \"note\": \"<string>\",\n \"ignore_quiet_hours\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"message_id": "<string>",
"chat_id": "<string>",
"attachment_id": "<string>",
"status": "queued"
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}- Credential: an API key. A trial key returns
401 unauthorized. See Contact cards. - Line-scoped keys: a line-scoped key gets
403 forbiddenwhen the chat’s line is outside its list. - Test keys: a card sent with an
isnap_test_account key reaches the real contact: see Test keys. Idempotency-Key: read, and never replayed. Once a call has created the card’s message, a repeat with the same key returns409 idempotency_conflict. When no message was created, the repeat sends the card, and so does every repeat without a key: send a key with every call. A key that a reaction already used on the chat’s line is not refused: the call returns202with the id of the reaction entry inmessage_id, and sends nothing. Use a new key for every call. Do not retry this call blindly: when you did not receive the response, look for the message withGET /v1/messagesbefore you resend the card. See Messages, reactions and contact cards for the scope and the lifetime of the key.- Events: the events of a send, from
message.queuedormessage.scheduledon. - Personal data: the card holds a person’s name, phone numbers, email addresses, organization, note and photo, and its file name holds the name. Request it only when needed, do not copy it into logs, tickets or other tools, and refer to a contact by an id of your own.
- A message: the card is a message with one attachment. The sending limits, the holds, the events and the errors of
POST /v1/messagesapply. One difference: on an iMessage line the card always asks for the typing indicator, whatever the line’sdefault_use_typing_indicator.ignore_quiet_hoursworks as onPOST /v1/messages: see Sending during quiet hours. See Sending messages. - Response:
statusalways readsqueued, even when iSnap holds the message: read the message withGET /v1/messages/{id}. The response carries noX-iSnap-Quota-header.
Errors
| Status | error.code | When |
|---|---|---|
| 400 | validation_failed | first_name is missing, a phone number is not in E.164, an email address is invalid, avatar_url is not an HTTPS URL, or none of phone_numbers, emails and organization is given. |
| 400 | bad_request | The chat’s contact is not a phone number. |
| 403 | forbidden | The request uses a line-scoped key, and the chat’s line is not in its list. |
| 404 | not_found | The chat is unknown, or its line is not yours. |
| 409 | idempotency_conflict | The Idempotency-Key was already used on the chat’s line, by an earlier call of this operation that created the card’s message or by a POST /v1/messages. |
| 502 | avatar_fetch_failed | iSnap fetches avatar_url once without following a redirect. The fetch failed: the host does not resolve to a public address, the response is not a 2xx with a Content-Type of image/png or image/jpeg, the image is over 2,097,152 bytes (2 MiB), or the download did not finish within 5 seconds. Nothing is sent. |
POST /v1/messages also apply: the line errors, the 429 codes of the sending limits, and the 503 codes of a shared line. The errors that every operation shares are in Errors.Authorizations
An API key created in the iSnap dashboard, or a trial key, sent as Authorization: Bearer <key>. An API key starts with isnap_live_ or isnap_test_; both act on the same account, lines and billing. A trial key acts on its trial only.
Path Parameters
Chat id: chat_ followed by 25 letters or digits.
^chat_[0-9A-Za-z]{25}$Body
The contact card. first_name is required, with at least one of phone_numbers, emails or a non-empty organization.
First name on the card, 1 to 255 characters.
1 - 255Last name on the card, at most 255 characters.
255HTTPS URL of the photo of the card: a PNG or JPEG image of at most 2 MiB (2,097,152 bytes). A URL that is not an HTTPS URL returns 400 validation_failed. iSnap fetches the URL once, without following a redirect: the host must resolve to a public address, the response must have a 2xx status and a Content-Type of image/png or image/jpeg, and the download must finish within 5 seconds. Otherwise the API returns 502 avatar_fetch_failed and nothing is sent.
Phone numbers on the card, in E.164: at most 10.
10A phone number in E.164.
^\+[1-9]\d{1,14}$Email addresses on the card: at most 10.
10An email address.
Organization on the card, at most 255 characters.
255Free text on the card, at most 2,000 characters.
2000true to let the message that carries the card leave during the quiet hours of the line, as ignore_quiet_hours of POST /v1/messages. The default is false. No effect on a shared line.
Response
The contact card, accepted as a message.
Always true on a success response.
true The message created by POST /v1/chats/{chat_id}/share-contact-card.
Show child attributes
Show child attributes
Trace id of the request that produced this response: 32 lowercase hexadecimal characters. Quote it when you report a problem to iSnap.
Id of the request that produced this response: req_ followed by 25 letters or digits.