curl \
-H "Authorization: Bearer API_KEY" \
-H 'Content-Type: application/json' \
-H 'Profile-Key: PROFILE_KEY' \
-d '{"expiresIn": 60}' \
-X POST https://api.ayrshare.com/api/profiles/link-sessions
const API_KEY = "API_KEY";
const PROFILE_KEY = "PROFILE_KEY";
fetch("https://api.ayrshare.com/api/profiles/link-sessions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${API_KEY}`,
"Profile-Key": PROFILE_KEY,
},
body: JSON.stringify({ expiresIn: 60 }),
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
payload = {'expiresIn': 60}
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY',
'Profile-Key': 'PROFILE_KEY'}
response = requests.post('https://api.ayrshare.com/api/profiles/link-sessions',
json=payload, headers=headers)
print(response.json())
<?php
require 'vendor/autoload.php'; // Composer auto-loader using Guzzle. See .../guzzlephp.org/en/stable/overview.html
$client = new GuzzleHttp\Client();
$res = $client->request(
'POST',
'https://api.ayrshare.com/api/profiles/link-sessions',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer API_KEY',
'Profile-Key' => 'PROFILE_KEY'
],
'json' => [
'expiresIn' => 60,
]
]
);
echo json_encode(json_decode($res->getBody()), JSON_PRETTY_PRINT);
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace CreateLinkSession_csharp
{
class CreateLinkSession
{
static async Task Main(string[] args)
{
string API_KEY = "API_KEY";
string PROFILE_KEY = "PROFILE_KEY";
string url = "https://api.ayrshare.com/api/profiles/link-sessions";
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + API_KEY);
client.DefaultRequestHeaders.Add("Profile-Key", PROFILE_KEY);
var sendData = new { expiresIn = 60 };
string jsonData = JsonConvert.SerializeObject(sendData);
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, content);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
catch (HttpRequestException e)
{
Console.WriteLine($"HTTP request error: {e.Message}");
}
}
}
}
{
"status": "success",
"sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8", // Identifier for this link. Use it with Get and Revoke a Link Session.
"url": "https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=YOUR_DOMAIN", // Send this to your user exactly as returned. The token exists only in here.
"expiresAt": "2026-09-02T08:03:26.838Z", // When the link stops working, as an ISO 8601 timestamp.
"emailSent": false, // Whether the connect-accounts email was sent. false means none was requested; a send failure returns code: 333 instead.
"title": "Acme Client" // The User Profile's title. Omitted when the profile has none.
}
{
"status": "success",
"sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
"url": "https://profile.ayrshare.com/connect?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu", // Open this in a popup. One network, no domain parameter.
"expiresAt": "2026-09-02T08:03:26.838Z",
"emailSent": false,
"title": "Acme Client"
}
{
"status": "success",
"sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
"token": "ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu", // No url: this shape returns the bare token instead. Treat it like a password.
"expiresAt": "2026-09-02T08:03:26.838Z",
"emailSent": false, // Always false here - email needs a link to send, so it returns code: 510.
"title": "Acme Client"
}
{
"action": "link session",
"status": "error",
"code": 504,
"message": "Connect mode requires the Max Pack. Activate it on your Account page: https://app.ayrshare.com/account"
}
{
"action": "JWT",
"status": "error",
"code": 188,
"message": "Missing or incorrect privateKey, profileKey, domain, email 'to', or expiresIn fields."
}
{
"action": "JWT",
"status": "error",
"code": 189,
"message": "Error generating JWT. Check the sent parameters.",
"details": "Missing or incorrect domain."
}
{
"action": "JWT",
"status": "error",
"code": 340,
"message": "Max Pack required. Go to your dashboard to add the Max Pack."
}
Profiles
Criar uma Link Session
Crie uma URL de vinculação social para um user profile, sem enviar uma chave privada.
POST
/
profiles
/
link-sessions
curl \
-H "Authorization: Bearer API_KEY" \
-H 'Content-Type: application/json' \
-H 'Profile-Key: PROFILE_KEY' \
-d '{"expiresIn": 60}' \
-X POST https://api.ayrshare.com/api/profiles/link-sessions
const API_KEY = "API_KEY";
const PROFILE_KEY = "PROFILE_KEY";
fetch("https://api.ayrshare.com/api/profiles/link-sessions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${API_KEY}`,
"Profile-Key": PROFILE_KEY,
},
body: JSON.stringify({ expiresIn: 60 }),
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
payload = {'expiresIn': 60}
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY',
'Profile-Key': 'PROFILE_KEY'}
response = requests.post('https://api.ayrshare.com/api/profiles/link-sessions',
json=payload, headers=headers)
print(response.json())
<?php
require 'vendor/autoload.php'; // Composer auto-loader using Guzzle. See .../guzzlephp.org/en/stable/overview.html
$client = new GuzzleHttp\Client();
$res = $client->request(
'POST',
'https://api.ayrshare.com/api/profiles/link-sessions',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer API_KEY',
'Profile-Key' => 'PROFILE_KEY'
],
'json' => [
'expiresIn' => 60,
]
]
);
echo json_encode(json_decode($res->getBody()), JSON_PRETTY_PRINT);
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace CreateLinkSession_csharp
{
class CreateLinkSession
{
static async Task Main(string[] args)
{
string API_KEY = "API_KEY";
string PROFILE_KEY = "PROFILE_KEY";
string url = "https://api.ayrshare.com/api/profiles/link-sessions";
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + API_KEY);
client.DefaultRequestHeaders.Add("Profile-Key", PROFILE_KEY);
var sendData = new { expiresIn = 60 };
string jsonData = JsonConvert.SerializeObject(sendData);
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, content);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
catch (HttpRequestException e)
{
Console.WriteLine($"HTTP request error: {e.Message}");
}
}
}
}
{
"status": "success",
"sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8", // Identifier for this link. Use it with Get and Revoke a Link Session.
"url": "https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=YOUR_DOMAIN", // Send this to your user exactly as returned. The token exists only in here.
"expiresAt": "2026-09-02T08:03:26.838Z", // When the link stops working, as an ISO 8601 timestamp.
"emailSent": false, // Whether the connect-accounts email was sent. false means none was requested; a send failure returns code: 333 instead.
"title": "Acme Client" // The User Profile's title. Omitted when the profile has none.
}
{
"status": "success",
"sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
"url": "https://profile.ayrshare.com/connect?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu", // Open this in a popup. One network, no domain parameter.
"expiresAt": "2026-09-02T08:03:26.838Z",
"emailSent": false,
"title": "Acme Client"
}
{
"status": "success",
"sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
"token": "ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu", // No url: this shape returns the bare token instead. Treat it like a password.
"expiresAt": "2026-09-02T08:03:26.838Z",
"emailSent": false, // Always false here - email needs a link to send, so it returns code: 510.
"title": "Acme Client"
}
{
"action": "link session",
"status": "error",
"code": 504,
"message": "Connect mode requires the Max Pack. Activate it on your Account page: https://app.ayrshare.com/account"
}
{
"action": "JWT",
"status": "error",
"code": 188,
"message": "Missing or incorrect privateKey, profileKey, domain, email 'to', or expiresIn fields."
}
{
"action": "JWT",
"status": "error",
"code": 189,
"message": "Error generating JWT. Check the sent parameters.",
"details": "Missing or incorrect domain."
}
{
"action": "JWT",
"status": "error",
"code": 340,
"message": "Max Pack required. Go to your dashboard to add the Max Pack."
}
Crie uma URL de vinculação social para um User Profile. Envie a
Cada código nomeado acima está na referência de Erros de Link Session.
url retornada ao seu usuário,
e ele a abre para conectar suas contas sociais.
Esta é a forma recomendada de criar uma URL de vinculação. Ela precisa apenas da sua API Key e de um
Profile-Key — não há chave privada a enviar e nada a assinar. Diferentemente de uma URL de
vinculação criada antes, uma link session é armazenada, então você pode verificar se ela foi usada
e revogá-la antes de expirar.
A url retornada autentica o seu usuário no perfil dele, então trate-a como uma senha e envie
cada uma a um único usuário. Consulte
Enviar a URL de vinculação.
A URL é válida por 5 minutos por padrão. Use
expiresIn para definir uma janela
diferente, de até 2880 minutos (48 horas).Gerar uma URL de vinculação realiza a mesma operação e continua
funcionando sem alteração. Ele aceita os parâmetros legados
privateKey, base64 e verify
e os ignora. domain não é ignorado em nenhum dos dois endpoints - ele continua opcional e
ainda é validado. Novas integrações devem usar este endpoint.Uma diferença na resposta: o generateJWT retorna um token de nível superior por
compatibilidade retroativa, e este endpoint não retorna um ao lado de uma url — o token em uma
url vive dentro dela. Se você está migrando e seu código lê token, leia url em vez disso.
(O modo connect para o widget incorporado é o único formato que retorna um token
puro, porque ele não retorna URL alguma para o token viver dentro.)Parâmetros do cabeçalho
O
Profile-Key é um cabeçalho neste endpoint — não há um parâmetro profileKey no
corpo. Se ele estiver ausente, você recebe code: 188, cuja mensagem lista privateKey,
profileKey e outros nomes de campos legados porque ela é compartilhada com
Gerar uma URL de vinculação. Leia-a como “o cabeçalho Profile-Key
está ausente ou incorreto”; nenhum dos outros nomes citados nela é um parâmetro deste endpoint.string
Sua X API Key (Consumer Key) do X Developer Portal. Quando fornecida, a URL de
vinculação usará seu próprio X Developer App para vinculação OAuth.
string
Seu X API Secret (Consumer Secret) do X Developer Portal. Obrigatório quando
X-Twitter-OAuth1-Api-Key for fornecido.Parâmetros do corpo
string
padrão:"grid"
Qual superfície de vinculação esta sessão alimenta.
grid— a página de vinculação hospedada, mostrando todas as redes que você permite. Este é o padrão, então uma requisição que omitemodecria uma.connect— uma rede de cada vez, aberta a partir do seu próprio dashboard. Consulte Modo Connect abaixo e Modo direto.
origin ou network não coloca você em modo connect, então uma sessão
grid não pode virar uma sessão com gate por acidente. Qualquer outro valor retorna code: 188 com
details nomeando os dois.number
padrão:5
Longevidade do link em minutos. Intervalo: 1 a 2880 minutos.Requer o Max Pack.Consulte Expiração do link para mais informações.
boolean
padrão:false
Fazer logout automático da sessão atual. Recomendamos não usar em produção, pois
afeta o desempenho.Consulte Logout automático de uma sessão de profile.
string
Uma URL para redirecionar quando o botão “Done” (Concluído) ou a imagem do logotipo forem
clicados. Adicione o parâmetro de consulta
origin=true para redirecionar a janela de origem.array
As redes sociais a serem exibidas na página de vinculação. Sobrescreve as redes configuradas
na página Social Networks.
Only display Facebook, X/Twitter, LinkedIn, and TikTok
{
"allowedSocial": ["facebook", "twitter", "linkedin", "tiktok"]
}
string
Apenas no modo connect. A única rede social que esta sessão conecta, que é o que a torna uma
sessão em modo direto. Omita-o para uma sessão que o seu próprio dashboard conduz por várias
redes.Um de
bluesky, facebook, gmb, instagram, instagramApi, linkedin, pinterest,
reddit, snapchat, telegram, threads, tiktok, twitter, whatsapp, x, youtube.
Qualquer outra coisa retorna code: 508 — incluindo fbg, que não é um alvo de vinculação aqui.Não pode ser combinado com allowedSocial (code: 507): uma sessão de rede única já é sua
própria allowlist. Uma rede que sua conta não habilitou retorna code: 509, que é uma resposta
diferente de 508 porque é corrigível na sua página
Social Networks.No modo grid ele é ignorado.string
Sobrescreve qual fluxo de vinculação do Instagram é usado para este link. Valores válidos:
instagram: Instagram Login direto, sem necessidade de Página do Facebook.facebook: Vincular o Instagram por meio de uma Página do Facebook conectada.
string
A origem exata da página que abriu a janela de vinculação, para que ela possa ser avisada quando
a vinculação termina.Quando definido, a página de vinculação envia eventos para essa origem com
window.postMessage conforme
seu usuário conecta cada conta, e sua página pode reagir sem polling. Os eventos são
enviados somente para esse valor exato, então ele deve corresponder à origem da sua página caractere por
caractere, incluindo o esquema e qualquer porta.Três formatos são aceitos: uma origem https (https://app.example.com),
http://localhost:3000 para desenvolvimento local, e um esquema personalizado nativo
(myapp://connected). Qualquer outra coisa — uma origem http:// simples que não seja localhost, ou
algo que não é uma origem de forma alguma — é ignorada nos links que este endpoint cria:
o link ainda funciona, ele simplesmente não envia eventos. Ele é opcional, então omiti-lo também não é um
erro.Dos três, apenas os dois primeiros recebem eventos. Um esquema personalizado é um alvo de retorno para
um app mobile e não pode recebê-los, porque não há janela de navegador para a qual enviar;
apps nativos fazem polling em Consultar uma Link Session em vez disso.Consulte Eventos de conclusão de vinculação.No modo connect, origin é obrigatório, e é verificado. A leniência acima é comportamento do
modo grid. Com mode: "connect", omiti-lo retorna code: 505 e um valor que não é um
dos três formatos aceitos retorna code: 506, cujo details repete o formato que você enviou.string
Opcional. Seu domínio de vinculação, quando sua conta tem mais de um. Quando omitido, o
domínio da sua própria conta é usado. Um domínio não registrado na sua conta é rejeitado.
object
Envie um e-mail Connect Accounts carregando o link, para que seu usuário possa acessar
diretamente sua página de vinculação. Requer um endereço
to.Requer o Max Pack. A resposta informa o resultado em emailSent, e uma falha no envio
retorna code: 333 em vez de uma resposta de sucesso.Consulte E-mail de conexão de contas.Modo Connect
mode: "connect" cria uma sessão para uma superfície de vinculação que você mesmo hospeda, em vez de para a
página de vinculação hospedada. Qual dos dois formatos connect você recebe depende de uma coisa — se você
passa network:
| Você envia | Você recebe de volta | O que fazer com isso |
|---|---|---|
mode: "connect" e um network | uma url apontando para uma página de conexão de rede única | abra-a em um popup — este é o modo direto |
mode: "connect" e nenhum network | um token, e nenhuma URL | entregue-o ao seu próprio front-end |
A resposta carrega o segredo exatamente uma vez. Uma resposta tem ou uma
url ou um token,
nunca os dois e nunca duas URLs. O token de uma sessão em modo direto vive dentro da url, da
mesma forma que no modo grid; uma sessão sem URL para carregá-lo retorna o token puro
em vez disso. Todo o resto é igual nos três modos: sessionId, expiresAt, emailSent
e title quando o User Profile tem um.O que o modo connect exige
Nenhum destes é um campo do corpo por si só — o primeiro é um direito da conta e o segundo é o parâmetroorigin acima, que o modo connect torna obrigatório.
O Max Pack. Sem ele a chamada retorna code: 504, verificado antes
dos parâmetros do modo connect, então corrigir origin ou network não mudará a resposta. Entre em contato com o suporte se você
precisar do modo connect habilitado em uma conta sem o Max Pack.
Um origin, em cada sessão. Não há allowlist nem etapa de registro — você o envia em
cada chamada e ele é armazenado na sessão, então um novo ambiente não precisa de configuração do nosso lado. Três
formatos são aceitos:
- uma origem
https—https://app.example.com - um esquema personalizado nativo —
myapp://connected http://localhostouhttp://localhost:3000, para desenvolvimento local
code: 505,
e qualquer coisa que não seja um dos três formatos retorna code: 506.
email não pode ser usado com uma sessão que não tem network, porque não há link para colocar no
e-mail — esse formato retorna um token para o seu próprio front-end. A chamada retorna code: 510.
Adicione um network para uma sessão em modo direto, que tem uma URL, ou omita email.curl \
-H "Authorization: Bearer API_KEY" \
-H 'Content-Type: application/json' \
-H 'Profile-Key: PROFILE_KEY' \
-d '{"expiresIn": 60}' \
-X POST https://api.ayrshare.com/api/profiles/link-sessions
const API_KEY = "API_KEY";
const PROFILE_KEY = "PROFILE_KEY";
fetch("https://api.ayrshare.com/api/profiles/link-sessions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${API_KEY}`,
"Profile-Key": PROFILE_KEY,
},
body: JSON.stringify({ expiresIn: 60 }),
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
payload = {'expiresIn': 60}
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY',
'Profile-Key': 'PROFILE_KEY'}
response = requests.post('https://api.ayrshare.com/api/profiles/link-sessions',
json=payload, headers=headers)
print(response.json())
<?php
require 'vendor/autoload.php'; // Composer auto-loader using Guzzle. See .../guzzlephp.org/en/stable/overview.html
$client = new GuzzleHttp\Client();
$res = $client->request(
'POST',
'https://api.ayrshare.com/api/profiles/link-sessions',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer API_KEY',
'Profile-Key' => 'PROFILE_KEY'
],
'json' => [
'expiresIn' => 60,
]
]
);
echo json_encode(json_decode($res->getBody()), JSON_PRETTY_PRINT);
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace CreateLinkSession_csharp
{
class CreateLinkSession
{
static async Task Main(string[] args)
{
string API_KEY = "API_KEY";
string PROFILE_KEY = "PROFILE_KEY";
string url = "https://api.ayrshare.com/api/profiles/link-sessions";
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + API_KEY);
client.DefaultRequestHeaders.Add("Profile-Key", PROFILE_KEY);
var sendData = new { expiresIn = 60 };
string jsonData = JsonConvert.SerializeObject(sendData);
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, content);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
catch (HttpRequestException e)
{
Console.WriteLine($"HTTP request error: {e.Message}");
}
}
}
}
{
"status": "success",
"sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8", // Identifier for this link. Use it with Get and Revoke a Link Session.
"url": "https://profile.ayrshare.com?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu&domain=YOUR_DOMAIN", // Send this to your user exactly as returned. The token exists only in here.
"expiresAt": "2026-09-02T08:03:26.838Z", // When the link stops working, as an ISO 8601 timestamp.
"emailSent": false, // Whether the connect-accounts email was sent. false means none was requested; a send failure returns code: 333 instead.
"title": "Acme Client" // The User Profile's title. Omitted when the profile has none.
}
{
"status": "success",
"sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
"url": "https://profile.ayrshare.com/connect?session=ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu", // Open this in a popup. One network, no domain parameter.
"expiresAt": "2026-09-02T08:03:26.838Z",
"emailSent": false,
"title": "Acme Client"
}
{
"status": "success",
"sessionId": "c7a2434e72e91bde27579efde0fd6dd0b74ceee29a471fd368407f273708c2e8",
"token": "ayr_ls_kJ8mQ2vX9pLnR4tYwZ6aBcD1eFgH3iJkLmN0oPqRsTu", // No url: this shape returns the bare token instead. Treat it like a password.
"expiresAt": "2026-09-02T08:03:26.838Z",
"emailSent": false, // Always false here - email needs a link to send, so it returns code: 510.
"title": "Acme Client"
}
{
"action": "link session",
"status": "error",
"code": 504,
"message": "Connect mode requires the Max Pack. Activate it on your Account page: https://app.ayrshare.com/account"
}
{
"action": "JWT",
"status": "error",
"code": 188,
"message": "Missing or incorrect privateKey, profileKey, domain, email 'to', or expiresIn fields."
}
{
"action": "JWT",
"status": "error",
"code": 189,
"message": "Error generating JWT. Check the sent parameters.",
"details": "Missing or incorrect domain."
}
{
"action": "JWT",
"status": "error",
"code": 340,
"message": "Max Pack required. Go to your dashboard to add the Max Pack."
}