profiles
Profiles API Endpoint: Create and manage multiple user profiles.
❗Click the › in the endpoint to view details.
POST
https://app.ayrshare.com/api/post
In addition to the /post endpoint spec, you can post to a User Profile by adding the Profile Key in the header or using the "profileKey" body parameter. The return will be an array of posts or error results, with an overall status. If all posts successful, "success", or if any post failed, "error".
You may obtain a user's Profile Key via either the when the profile is created with the /create-profile endpoint (see below) or in Ayrshare's Web Dashboard GUI by switching to the profile and going to Profile Key page.
Name | Type | Description |
---|---|---|
profileKey | string | The User Profile Key. You must be the owner of these user profile to post. See post verification for restrictions. If the body parameter is not specified, add the Profile Key in the header. |
200 Post results of all posts successful.
400 Example of some posts success and other failure, with an overall failure.
{
"status": "success",
"posts": [
{
"status": "success",
"errors": [],
"postIds": [
{
"status": "success",
"id": "1381620827414728708",
"platform": "twitter"
}
],
"id": "DQf4P4tBf0rpAibpt3Gm",
"profileTitle": "Good Fun",
"refId": "da19d0d2875afb2a516cde881172eb6c1002c592",
"post": "I love to post"
},
{
"status": "success",
"errors": [],
"postIds": [
{
"status": "success",
"id": "1381620827397951497",
"platform": "twitter"
}
],
"id": "jnKLGKcNcGS2iSPWnakw",
"profileTitle": "Digg It",
"refId": "866a36e1185b45e63f019386f941f320972b8e70",
"post": "I love to post"
}
]
}
{
"status": "error",
"posts": [
{
"status": "error",
"errors": [
{
"action": "post",
"status": "error",
"code": 156,
"message": "Facebook does not seem to be linked with Ayrshare. Please confirm the linkage on the Social Accounts page in your dashboard. https://docs.ayrshare.com/additional-info/troubleshooting",
"platform": "facebook"
}
],
"postIds": [
{
"status": "success",
"id": "1381620363155607552",
"platform": "twitter"
}
],
"id": "2crtBXkWRsh9xbGThE1O",
"profileTitle": "Good Fun",
"refId": "da19d0d2875afb2a516cde881172eb6c1002c592",
"post": "What a wonderful post"
},
{
"status": "success",
"errors": [],
"postIds": [
{
"status": "success",
"id": "1381620363096899585",
"platform": "twitter"
},
{
"status": "success",
"id": "102775157855689_323026635830539",
"postUrl": "https://www.facebook.com/102775157858689_323026635030539",
"platform": "facebook"
}
],
"id": "7ojyAsPpLR0ZlyL6B5rz",
"profileTitle": "Digg It",
"refId": "866a36e1185b45e63f019386f941f320972b8e70",
"post": "What a wonderful post"
}
]
}
If a response of an array is required instead of an object, please include the body parameter
arrayResponse
with the boolean value of true
. For example, arrayResponse: true
It is important to follow the rules of the social networks, especially in regards to duplicate or similar content. Please see here for details:
cURL
Node.js
Python
PHP
Go
C#
curl \
-H "Authorization: Bearer API_KEY" \
-H 'Content-Type: application/json' \
-d '{"post": "Today is a great day!", "platforms": ["twitter", "facebook", "instagram", "linkedin"], "profileKey": "PROFILE_KEY", "mediaUrls": ["https://img.ayrshare.com/012/gb.jpg"]}' \
-X POST https://app.ayrshare.com/api/post
const API_KEY = "API_KEY";
const postMsg = "Today is a great day!";
fetch("https://app.ayrshare.com/api/post", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
},
body: JSON.stringify({
post: postMsg, // required
platforms: ["twitter", "facebook", "instagram", "linkedin"], // required
profileKey: "PROFILE_KEY", // required for client posting
mediaUrls: ["https://img.ayrshare.com/012/gb.jpg"], //optional
}),
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
payload = {'post': 'Today is a great day!',
'platforms': ['twitter', 'facebook', 'instagram', 'linkedin'],
'profileKey': 'PROFILE_KEY',
'mediaUrls': ['https://img.ayrshare.com/012/gb.jpg']}
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY'}
r = requests.post('https://app.ayrshare.com/api/post',
json=payload,
headers=headers)
print(r.json())
<?php
require 'vendor/autoload.php'; // Composer auto-loader using Guzzle. See https://docs.guzzlephp.org/en/stable/overview.html
$client = new GuzzleHttp\Client();
$res = $client->request(
'POST',
'https://app.ayrshare.com/api/post',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer API_KEY'
],
'json' => [
'post' => 'Today is a great day!',
'platforms' => ['twitter', 'facebook', 'instagram', 'linkedin'], // required
'profileKey' => 'PROFILE_KEY', // required
'mediaUrls' => ['https://img.ayrshare.com/012/gb.jpg'], // optional
]
]
);
echo json_encode(json_decode($res->getBody()), JSON_PRETTY_PRINT);
package main
import (
"bytes"
"encoding/json"
"log"
"net/http"
)
func main() {
message := map[string]interface{}{
"post": "Today is a great day!",
"platforms": []string{"twitter", "facebook", "instagram", "linkedin"},
"profileKey": "PROFILE_KEY",
"mediaUrls": []string{"https://img.ayrshare.com/012/gb.jpg"}
}
bytesRepresentation, err := json.Marshal(message)
if err != nil {
log.Fatalln(err)
}
req, _ := http.NewRequest("POST", "https://app.ayrshare.com/api/post",
bytes.NewBuffer(bytesRepresentation))
req.Header.Add("Content-Type", "application/json; charset=UTF-8")
req.Header.Add("Authorization", "Bearer API_KEY")
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal("Error:", err)
}
res.Body.Close()
}
using System;
using System.Net;
using System.IO;
namespace PostPOSTRequest_charp
{
class Post
{
static void Main(string[] args)
{
string API_KEY = "API_KEY";
string url = "https://app.ayrshare.com/api/post";
var httpWebRequest = WebRequest.CreateHttp(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("Authorization", "Bearer " + API_KEY);
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"post\" : \"Today is a great day forever!\","
+ "\"platforms\" : [ \"twitter\", \"facebook\", \"instagram\", \"linkedin\" ],"
+ "\"mediaUrls\" : [ \"https://img.ayrshare.com/012/gb.jpg\" ],"
+ "\"profileKey\" : \"PROFILE_KEY\"}";
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = streamReader.ReadToEnd();
Console.WriteLine(response);
}
}
}
}
POST
https://app.ayrshare.com/api/profiles/profile
Create a new profile under your primary account. The Profile Key of the newly created profile is returned. Use the Profile Key to manage and post on behalf of your client.
Name | Type | Description |
---|---|---|
Authorization* | string | Format: Authorization: Bearer API_KEY . See Overview for more information. |
Name | Type | Description |
---|---|---|
title* | string | Title of the new profile. Must be unique. |
hideTopHeader | boolean | Hide the top header on the social accounts linkage page. Boolean true to not display. |
topHeader | string | Change the header on the social accounts linkage page. Currently displays: "Social Accounts for {title}" where {title} is the profile title. |
disableSocial | array | Array of social networks that are disabled for this user's profile. The primary profile's list of disabled social networks takes precedence.
Available networks: twitter, facebook, fbg, instagram, linkedin, telegram, gmb, youtube, tiktok, pinterest, and reddit. |
team | boolean | Create a new user profile as a team member by setting team: true . The email field will be used to send an invite email. See inviting a team member for details on the requirements. |
email | string | A valid email address where the team member invite will be sent. Required if team: true |
subHeader | string | Change the sub header on the social accounts linakge page. Currently displays "Click an icon to link a social network". Set to an empty string to remove. |
200 Successful creation of a new profile with the profileKey. refId used to reference the profile when calling /user endpoint.
400 Profile with this title already exists.
{
"status": "success",
"title": "Digg It",
"refId": "140b8709bd6ade099b242d895e268fb886130c53",
"profileKey": "7TVRLEZ-24A43C0-NJW0Z82-F11984N"
}
{
"action": "create",
"status": "error",
"code": 146,
"message": "Profile title already exists."
}
cURL
Node.js
Python
PHP
Go
C#
curl \
-H "Authorization: Bearer API_KEY" \
-H 'Content-Type: application/json' \
-d '{"title": "ACME Profile"}' \
-X POST https://app.ayrshare.com/api/profiles/profile
const API_KEY = "API_KEY";
fetch("https://app.ayrshare.com/api/profiles/profile", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
},
body: JSON.stringify({
title: "ACME Profile", // required
}),
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
payload = {'title': 'ACME Profile'}
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY'}
r = requests.post('https://app.ayrshare.com/api/profiles/profile',
json=payload,
headers=headers)
print(r.json())
<?php
require 'vendor/autoload.php'; // Composer auto-loader using Guzzle. See https://docs.guzzlephp.org/en/stable/overview.html
$client = new GuzzleHttp\Client();
$res = $client->request(
'POST',
'https://app.ayrshare.com/api/profiles/profile',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer API_KEY'
],
'title' => ['ACME Profile'],
]
);
echo json_encode(json_decode($res->getBody()), JSON_PRETTY_PRINT);
package main
import (
"bytes"
"encoding/json"
"log"
"net/http"
)
func main() {
message := map[string]interface{}{
"title": "ACME Profile"
}
bytesRepresentation, err := json.Marshal(message)
if err != nil {
log.Fatalln(err)
}
req, _ := http.NewRequest("POST", "https://app.ayrshare.com/api/profiles/profile",
bytes.NewBuffer(bytesRepresentation))
req.Header.Add("Content-Type", "application/json; charset=UTF-8")
req.Header.Add("Authorization", "Bearer API_KEY")
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal("Error:", err)
}
res.Body.Close()
}
using System;
using System.Net;
using System.IO;
namespace CreateProfilePOSTRequest_charp
{
class CreateProfile
{
static void Main(string[] args)
{
string API_KEY = "API_KEY";
string url = "https://app.ayrshare.com/api/profiles/profile";
var httpWebRequest = WebRequest.CreateHttp(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("Authorization", "Bearer " + API_KEY);
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"title\" : \"ACME Profile\"}";
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = streamReader.ReadToEnd();
Console.WriteLine(response);
}
}
}
}
The Profile Key returned should be securely stored in your system with appropriate access controls. For security reasons, the Profile Key can't not be retrieved again via the API. However, you can retrieve the Profile Key via the dashboard.
The
refId
should also be stored to associate a profile to an endpoint return.DELETE
https://app.ayrshare.com/api/profiles/profile
Delete a user profile you are the owner of. Deleting is irrevocable and can not be undone.
Name | Type | Description |
---|---|---|
Authorization* | string | Format: Authorization: Bearer API_KEY . See Overview for more information. |
Profile-Key* | string | The Profile Key of the profile to delete, returned from /create-profile. May also use the API Key found in the web dashboard. |
Name | Type | Description |
---|---|---|
title | string | Title of the User Profile to delete. Must be present if profileKey is not passed. title is case-sensitive and must match the User Profile title. |
200 Successful delete
500 Error deleting profile
403: Forbidden Profile Key not found
{
"status": "success",
"refId": "823nd82nd92jsnn2932"
}
{
"action": "delete",
"status": "error",
"code": 147,
"message": "Error deleting profile."
}
{
"action": "post",
"status": "error",
"code": 144,
"message": "Some profiles not found. Please verify the Profile Keys."
}
cURL
Node.js
Python
PHP
C#
curl \
-H "Authorization: Bearer API_KEY" \
-H 'Content-Type: application/json' \
-H 'Profile-Key: PROFILE_KEY' \
-X DELETE https://app.ayrshare.com/api/profiles/profile
const API_KEY = "API_KEY";
const profileKey = "PROFILE_KEY";
fetch("https://app.ayrshare.com/api/profiles/profile", {
method: "DELETE",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`,
"Profile-Key": profileKey
}
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
payload = {}
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY', 'Profile-Key': 'PROFILE_KEY'}
r = requests.delete('https://app.ayrshare.com/api/profiles/profile',
json=payload,
headers=headers)
print(r.json())
<?php
$url = 'https://app.ayrshare.com/api/profiles/profile';
$apiKey = 'API_KEY'; // Replace with your actual API key
$profileKey = 'PROFILE_KEY'; // Replace with your actual Profile key
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey,
'Profile-Key: ' . $profileKey
],
]);
$response = curl_exec($curl);
if (curl_errno($curl)) {
echo 'Error:' . curl_error($curl);
} else {
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
}
curl_close($curl);
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
using var client = new HttpClient();
var requestUri = "https://app.ayrshare.com/api/profiles/profile";
var bearerToken = "Bearer API_KEY";
var profileKey = "PROFILE_KEY";
using var request = new HttpRequestMessage(HttpMethod.Delete, requestUri);
request.Headers.Add("Authorization", bearerToken);
request.Headers.Add("Profile-Key", profileKey);
try
{
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
catch (HttpRequestException e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
PUT
https://app.ayrshare.com/api/profiles/profile
Update an existing profile's title, hide title, list of disabled social platforms, or display the title.
Name | Type | Description |
---|---|---|
Authorization* | string | Format: Authorization: Bearer API_KEY . See Overview for more information. |
Profile-Key* | string | Profile Key for a user profile. |
Name | Type | Description |
---|---|---|
disableSocial | array | Update the list of disabled profiles. The array will overwrite the previous list of disabled social networks.
Remove all disabled social by sending an empty array [].
Available networks: twitter, facebook, fbg, instagram, linkedin, telegram, gmb, youtube, tiktok, pinterest, and reddit. |
title | string | Updated title. |
hideTitle | boolean | Update hide title. |
displayTitle | string | Update display title. |
200
400 Profile Key not found
{
"status": "success",
"refId": "b1eb30ce50607a40000b220c01c20a88a49fe76f"
}
{
"action": "post",
"status": "error",
"code": 144,
"message": "Some profiles not found. Please verify the Profile Keys."
}
cURL
Node.js
Python
PHP
C#
curl \
-H "Authorization: Bearer API_KEY" \
-H 'Content-Type: application/json' \
-d '{"profileKey": "Jokdf-903Js-j9sd0-Pow02-QS9n3", "title": "ACME Profile"}' \
-X PUT https://app.ayrshare.com/api/profiles/profile
const API_KEY = "API_KEY";
fetch("https://app.ayrshare.com/api/profiles/profile", {
method: "PUT",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
"Profile-Key": "PROFILE_KEY";
},
body: JSON.stringify({
title: "ACME Profile"
}),
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
payload = {'title': 'ACME Profile'}
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY',
'Profile-Key': 'PROFILE_KEY'}
r = requests.put('https://app.ayrshare.com/api/profiles/profile',
json=payload,
headers=headers)
print(r.json())
<?php
$url = 'https://app.ayrshare.com/api/profiles/profile';
$apiKey = 'API_KEY'; // Replace with your actual API key
$profileKey = 'PROFILE_KEY'; // Replace with your actual Profile key
$data = ['title' => 'ACME Profile']; // Your data to be sent
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey,
'Profile-Key: ' . $profileKey
],
]);
$response = curl_exec($curl);
if (curl_errno($curl)) {
echo 'Error:' . curl_error($curl);
} else {
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
}
curl_close($curl);
using System;
using System.Net;
using System.IO;
namespace CreateProfilePOSTRequest_charp
{
class CreateProfile
{
static void Main(string[] args)
{
string API_KEY = "API_KEY";
string url = "https://app.ayrshare.com/api/profiles/profile";
var httpWebRequest = WebRequest.CreateHttp(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "PUT";
httpWebRequest.Headers.Add("Authorization", "Bearer " + API_KEY);
httpWebRequest.Headers.Add("Profile-Key", PROFILE_KEY);
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"title\" : \"ACME Profile\"}";
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = streamReader.ReadToEnd();
Console.WriteLine(response);
}
}
}
}
GET
https://app.ayrshare.com/api/profiles
Get all the profiles associated with the primary account.
Name | Type | Description |
---|---|---|
title | string | Return only the profile associated with the URL encoded title . Optional. |
refId | string | Return only the profile associated with the given refId . The refId was returned during the profile creation or from the /user endpoint. Optional. |
Name | Type | Description |
---|---|---|
Authorization | string | Format: Authorization: Bearer API_KEY . See Overview for more information. |
200
{
"profiles": [
{
"title": "Digg It Title",
"displayTitle": "Your title",
"created": {
"_seconds": 1604094099,
"_nanoseconds": 530000000
},
"createdUTC": "2022-03-02T16:11:00.839Z",
"refId": "160c8700bd6ade099b242d845e268fb986130c53",
"activeSocialAccounts": [
"twitter",
"facebook",
"linkedin",
"instagram"
],
},
{
"title": "Super Profile",
"created": {
"_seconds": 1604377627,
"_nanoseconds": 252000000
},
"createdUTC": "2022-03-02T16:11:00.839Z",
"refId": "170a8700bd6ade099b242d845e268fb986130c53"
},
{
"title": "Good Fun Title"
"created": {
"_seconds": 1605107864,
"_nanoseconds": 96000000
},
"createdUTC": "2022-03-02T16:11:00.839Z",
"refId": "180s8700bd6ade099b242d845e268fb986130c53",
"activeSocialAccounts": [
"facebook",
"linkedin",
"youtube"
],
}
]
}
cURL
Node.js
Python
PHP
C#
curl \
-H "Authorization: Bearer API_KEY" \
-X GET https://app.ayrshare.com/api/profiles
const API_KEY = "API_KEY";
fetch("https://app.ayrshare.com/api/profiles", {
method: "GET",
headers: {
"Authorization": `Bearer ${API_KEY}`
}
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
headers = {'Authorization': 'Bearer API_KEY'}
r = requests.get('https://app.ayrshare.com/api/profiles', headers=headers)
print(r.json())
<?php
$url = 'https://app.ayrshare.com/api/profiles';
$apiKey = 'API_KEY'; // Replace with your actual API key
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPGET => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey
],
]);
$response = curl_exec($curl);
if (curl_errno($curl)) {
echo 'Error:' . curl_error($curl);
} else {
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
}
curl_close($curl);
using System;
using System.Net;
using System.IO;
namespace HistoryGETRequest_charp
{
class History
{
static void Main(string[] args)
{
string API_KEY = "API_KEY";
string url = "https://app.ayrshare.com/api/profiles";
var httpWebRequest = WebRequest.CreateHttp(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add("Authorization", "Bearer " + API_KEY);
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = streamReader.ReadToEnd();
Console.WriteLine(response);
}
}
}
}
DELETE
https://app.ayrshare.com/api/profiles/social
Unlink a social network for a given user profile. For example, if a user profile is linked to TikTok, unlink TikTok by making this endpoint request. A successful 200 response will be returned even if the platform is not linked.
Name | Type | Description |
---|---|---|
Authorization* | string | Format: Authorization: Bearer API_KEY . See Overview for more information. |
Profile-Key* | string | The Profile Key of a user profile. |
Name | Type | Description |
---|---|---|
platform* | string | Platform to unlink: "facebook", "fbg", gmb", "instagram", "linkedin", "reddit", "telegram", "tiktok", "twitter", "youtube". |
200: OK Successful unlink
400: Bad Request Error response
{
"status": "success",
"platform": "twitter",
"refId": "13a9wa9e0df1183b7a6a1fc2c61b8023fa9a32a1"
}
{
"action": "post",
"status": "error",
"code": 163,
"message": "Missing, empty, or not valid platforms parameter. Please verify sending an array of valid platfoms. https://docs.ayrshare.com/rest-api/endpoints/post"
}
cURL
Node.js
Python
PHP
C#
curl \
-H "Authorization: Bearer API_KEY" \
-H 'Content-Type: application/json' \
-H 'Profile-Key: PROFILE_KEY' \
-d '{"platform": "twitter"}' \
-X DELETE https://app.ayrshare.com/api/profiles/social
const API_KEY = "API_KEY";
fetch("https://app.ayrshare.com/api/profiles/social", {
method: "DELETE",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`,
"Profile-Key": PROFILE_KEY
},
body: JSON.stringify({ platform: "twitter" }),
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
payload = {'platform': 'twitter' }
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY',
'Profile-Key': PROFILE_KEY }
r = requests.delete('https://app.ayrshare.com/api/profiles/social',
json=payload,
headers=headers)
print(r.json())
<?php
$url = 'https://app.ayrshare.com/api/profiles/social';
$apiKey = 'API_KEY'; // Replace with your actual API key
$profileKey = 'PROFILE_KEY'; // Replace with your actual Profile key
$data = ['platform' => 'twitter']; // Data to be sent
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey,
'Profile-Key: ' . $profileKey
],
]);
$response = curl_exec($curl);
if (curl_errno($curl)) {
echo 'Error:' . curl_error($curl);
} else {
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
}
curl_close($curl);
using System;
using System.Net;
using System.IO;
namespace DeletePOSTRequest_charp
{
class Delete
{
static void Main(string[] args)
{
string API_KEY = "API_KEY";
string url = "https://app.ayrshare.com/api/profiles/social";
var httpWebRequest = WebRequest.CreateHttp(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "DELETE";
httpWebRequest.Headers.Add("Authorization", "Bearer " + API_KEY);
httpWebRequest.Headers.Add("Profile-Key", PROFILE_KEY);
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"platform\" : \"twitter\"}";
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = streamReader.ReadToEnd();
Console.WriteLine(response);
}
}
}
}
POST
https://app.ayrshare.com/api/profiles/generateJWT
Generate a JSON Web Token (JWT) for use with single sign on. Used if you do not want to generate the JWT yourself. Also provided is the URL that can directly be used for SSO.
The JWT URL is valid for 5 minutes. After 5 minutes you must generate a new JWT URL. Please the Max Pack
expireIn
for additional options.Name | Type | Description |
---|---|---|
Authorization* | string | Format: Authorization: Bearer API_KEY . See Overview for more information. |
Name | Type | Description |
---|---|---|
domain* | string | Domain of app. Please use the exact domain given during onboarding. |
privateKey* | string | Private Key use for encryption. |
profileKey* | string | User Profile Key. The API Key can not be used in this field. |
logout | boolean | Automatically logout the current session. Recommend not to use in production since it affects the performance. Please see here. |
redirect | string | Specify a URL to redirect to when the "Done" button or logo image is clicked. The URL will be automatically shortened in the returned JWT url. Redirect the origin opener window by adding the query parameter origin=true to the redirect URL. |
verify | boolean | Verify that the generated token is valid. Recommend to only use in non-production environment. See below for details. |
base64 | boolean | If the private key is base64 encoded, set to true . Default false . Encode the private.key file in base64 and pass the single line String in the privateKey field. E.g in Linux: cat private.key | base64 |
expiresIn | number | Set the longevity of the token in minutes. Default 5 minutes. Range: 1 minute to 2880 minutes. |
email | object | Send a Connect Accounts email with a link for users to directly access their social linkage page. |
200 Returns JWT token and url.
400 Example of the private.key information is incorrect not properly formatted, e.g. missing carriage returns.
{
"status": "success",
"title": "User Profile Title",
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGlLZXkiOiJBSjNQR1cxLThIWk04UjQtR0NXVFZKVy1ZRTE1M1BFIiwicHJvZmlsZUtleSI6IjhKNDY4UFktSjM5TVlXRC1IWEpLVlIyLVBRMjBQUlMiLCJpYXQiOjE2MTQyMjYwNDksImV4cCI6MTYxNDIyNjM0OSwiYXVkIjoiaHR0cHM6Ly9hcHAuYXlyc2hhcmUuY29tIiwiaXNzIjoiYm9uZGJyYW5kbG95YWx0eS5jb20iLCJzdWIiOiJzdXBwb3J0QGF5cnNoYXJlLmNvbSJ9.Se387OyhJIdaDkFkvAe0Dwo3pQrHBwdg2bbjqKYn7BZuVDxPboJmTsd7rra8N-Z6b9_fJOtwlRFGBLW1CvgLGU4RSisTVqjqhAkb3KNhpA7cZ673IJbRX-ST7tYadKKzmd9GNrZW9rhxHOlgMJ9uOboc4dcaDbNmzb_yCrfLY-E"
"url": "https://profile.ayrshare.com?domain=PROVIDED_DOMAIN&jwt=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGlLZXkiOiJBSjNQR1cxLThIWk04UjQtR0NXVFZKVy1ZRTE1M1BFIiwicHJvZmlsZUtleSI6IjhKNDY4UFktSjM5TVlXRC1IWEpLVlIyLVBRMjBQUlMiLCJpYXQiOjE2MTQyMjYwNDksImV4cCI6MTYxNDIyNjM0OSwiYXVkIjoiaHR0cHM6Ly9hcHAuYXlyc2hhcmUuY29tIiwiaXNzIjoiYm9uZGJyYW5kbG95YWx0eS5jb20iLCJzdWIiOiJzdXBwb3J0QGF5cnNoYXJlLmNvbSJ9.Se387OyhJIdaDkFkvAe0Dwo3pQrHBwdg2bbjqKYn7BZuVDxPboJmTsd7rra8N-Z6b9_fJOtwlRFGBLW1CvgLGU4RSisTVqjqhAkb3KNhpA7cZ673IJbRX-ST7tYadKKzmd9GNrZW9rhxHOlgMJ9uOboc4dcaDbNmzb_yCrfLY-E",
"emailSent": true, // See details below
"expiresIn": "30m" // See details below
}
{
"action": "JWT",
"status": "error",
"code": 189,
"message": "Error generating JWT. Check the sent parameters, such as the privateKey has no extra tabs, spaces, or newlines. Error: error:0909006C:PEM routines:get_name:no start line"
}
cURL
Node.js
Python
PHP
C#
curl \
-H "Authorization: Bearer API_KEY" \
-H 'Content-Type: application/json' \
-d '{"domain": "ACME", "privateKey": "-----BEGIN RSA PRIVATE KEY...", "profileKey": "PROFILE_KEY"}' \
-X POST https://app.ayrshare.com/api/profiles/generateJWT
const fs = require('fs');
const API_KEY = "API_KEY";
const PROFILE_KEY = "PROFILE_KEY";
// Read in local private.key files - also can read from a DB
const privateKey = fs.readFileSync('private.key', 'utf8');
fetch("https://app.ayrshare.com/api/profiles/generateJWT", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
},
body: JSON.stringify({
domain: "ACME", // required
privateKey, // required
profileKey: PROFILE_KEY, // required
}),
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
import requests
# Read in local private.key files - also can read from a DB
with open('.private.key') as f:
profileKey = f.read()
payload = {'domain': 'ACME',
'privateKey': profileKey,
'profileKey': 'PROFILE_KEY' }
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer API_KEY'}
r = requests.post('https://app.ayrshare.com/api/profiles/generateJWT',
json=payload,
headers=headers)
print(r.json())
<?php
require 'vendor/autoload.php'; // Composer auto-loader using Guzzle. See https://docs.guzzlephp.org/en/stable/overview.html
$client = new GuzzleHttp\Client();
$res = $client->request(
'POST',
'https://app.ayrshare.com/api/post',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer API_KEY'
],
'json' => [
'domain' => 'ACME',
'privateKey' => '-----BEGIN RSA PRIVATE KEY...', // required
'profileKey' => 'PROFILE_KEY', // requires
]
]
);
echo json_encode(json_decode($res->getBody()), JSON_PRETTY_PRINT);
using System;
using System.Net;
using System.IO;
namespace GenerateJWTRequest_charp
{
class GenerateJWT
{
static void Main(string[] args)
{
string API_KEY = "API_KEY";
string url = "https://app.ayrshare.com/api/profiles/generateJWT";
var httpWebRequest = WebRequest.CreateHttp(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("Authorization", "Bearer " + API_KEY);
string privateKey = File.ReadAllText("./private.key"); // Provide with integration guide
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
var sendData = new
{
domain = "domain", // Provide in integration guide
privateKey = privateKey,
profileKey = "PROFILE_KEY"
};
// Install Newtonsoft.Json with NuGet or another JSOON serializer
string jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(sendData);
streamWriter.Write(jsonData);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = streamReader.ReadToEnd();
Console.WriteLine(response);
}
}
}
}
If you want to switch profile sessions, i.e. use a different profile, please see Automatic Logout of a Profile Session.
The Private Key must be precise, meaning preserving all characters including newlines. We recommend reading the private.key from a file to preserve all characters. If you paste the key into your code, you might need to manually replace newlines with a
\n
character or URL encode the string.Pasting the key directly into code often gives issues.
It is recommend to first verify your data in Postman using generateJWT. You can then generate the code from Postman, or read the key file from a directory or database. Use the user's profile Profile Key in the
profileKey
field. Using the API Key in the profileKey
field will result in an error.❗Use the
verify
field in the /generateJWT endpoint to check the parameters.Open the JWT URL in a new browser tab, browser window, or View Controller on iOS. The social networks do not allow opening the URL in an iFrame or obfuscating the approved partner origin domain.
1 minute video explaining how to generate a JSON Web Token (JWT):
The
generateJWT
endpoint does not validate the returned JWT URL by default. For example, if a corrupt Private Key is passed into generateJWT
a URL will still be returned and the URL result in a 401 error.You can verify the returned JWT URL by including
verify: true
in the generateJWT
body parameters. If the JWT URL can not be validated an error will be returned. For example, if the Private Key had a character removed the following would be returned:{
"action": "JWT",
"status": "error",
"code": 189,
"message": "Error generating JWT. Check the sent parameters, such as the privateKey has no extra tabs, spaces, or newlines. Also the entire private.key file including -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----. Error: secretOrPrivateKey must be an asymmetric key when using RS256"
}
We recommend using
verify: true
only in a non-production environment since te validation takes additional processing time.If you are a Bubble user, please see Generate JWT Token in the Bubble.io section for instructions:
If you want a longer JWT timeout than the default 5 minutes, include the
expireIn
field.Max Pack Required
For example, send the following JSON to set the JWT URL valid for 30 minutes:
{
"expireIn": 30
}
This allows you to email the link to your users instead of them having to go to your app or platform. A common use case is if your user need to reconnect a social account, you can email them the JWT link to directly re-link the social account instead of having to navigate to your platform.
Be sure to review with your security team how long your business wants to keep the JWT alive. Longer expire times creates additional risk of an unauthorized party accessing the link.
The following Swift, Flutter, and React Native code examples show how to launch the social linking page on an iOS device. Replace the
jwtURL
String variable with the return from the /generateJWT endpoint. In Swift, use a
UIViewController
and SFSafariViewControllerDelegate
. We don't recommend using a WebView
since some social networks such as Facebook and Google block authentication.In Flutter (Dart), there is no direct equivalent to a
UIViewController
or the SFSafariViewController
. However, you can achieve a similar functionality by using the url_launcher
package to open web URLs.React Native also doesn't have a direct equivalent to
SFSafariViewController
, but you can achieve a similar result with the WebBrowser
API provided by expo-web-browser
, which opens a URL in a modal browser window that shares cookies with the system browser. Otherwise, you can use the built-in React Native Linking
function to open Safari: await Linking.canOpenURL(jwtURL);
Swift
Flutter
React Native
import UIKit
import SafariServices
class ViewController: UIViewController, SFSafariViewControllerDelegate {
var jwtURL = "https://profile.ayrshare.com?domain=acme&jwt=eyJhbGciOiJ"
override func viewDidLoad() {
super.viewDidLoad()
setupButton()
}
func setupButton() {
let button = UIButton(type: .system)
button.frame = CGRect(x: (view.bounds.width - 200) / 2, y: (view.bounds.height - 50) / 2, width: 200, height: 50)
button.setTitle("Open URL", for: .normal)
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
view.addSubview(button)
}
@objc func buttonTapped() {
openURLInInAppBrowser()
}
func openURLInInAppBrowser() {
if let url = URL(string: jwtURL) {
let safariVC = SFSafariViewController(url: url)
safariVC.delegate = self
present(safariVC, animated: true, completion: nil)
}
}
// Optional: If you want to handle when the in-app browser is closed
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
}
/* yaml dependencies
dependencies:
flutter:
sdk: flutter
url_launcher: ^6.2.1
*/
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'URL Launcher Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
final String jwtURL = "https://profile.ayrshare.com?domain=acme&jwt=eyJhbGciOiJ";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('URL Launcher Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
openURLInBrowser(context);
},
child: Text('Open URL'),
),
),
);
}
void openURLInBrowser(BuildContext context) async {
if (await canLaunch(jwtURL)) {
await launch(jwtURL);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Could not launch $jwtURL'),
),
);
}
}
}
/**
* Using the API provided by expo-web-browser,
* which opens a URL in a modal browser window that shares cookies
* with the system browser.
* Learn more about expo: https://reactnative.dev/docs/environment-setup?guide=quickstart
*
* expo install expo-web-browser
*/
import React from 'react';
import { StyleSheet, Button, View } from 'react-native';
import * as WebBrowser from 'expo-web-browser';
export default function App() {
const jwtURL = 'https://profile.ayrshare.com?domain=acme&jwt=eyJhbGciOiJ';
const openURLInBrowser = async () => {
try {
await WebBrowser.openBrowserAsync(jwtURL);
// Optional: WebBrowser.openBrowserAsync returns a promise that resolves with an object containing
// 'type' that can be 'cancelled' or 'dismissed'. You can use this to handle when the browser is closed.
} catch (error) {
console.error(error);
}
};
return (
<View style={styles.container}>
<Button title="Open URL" onPress={openURLInBrowser} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
In conjunction with the longer expire time option, you can also automatically have Ayrshare email your users a link to the social linkage page.
Max Pack Required
For example the following JSON will send an email to [email protected] with the company name ACME, contact email [email protected] , and links to the terms and privacy policy:
{
"email": {
"to": "[email protected]", // required
"contactEmail": "[email protected]", // required
"company": "ACME", // required
"termsUrl": "https://www.ayrshare.com/terms", // required
"privacyUrl": "https://www.ayrshare.com/privacy", // required
"expireIn": 60 // optional
}
}
The response will include the following if the email and expire time was set:
{
"emailSent": true,
"expiresIn": "30m"
}
Here is an example of an email with the Connect Account link that opens social linkage page:
Example JWT Email
The email will come from the address: Social Connect Hub [email protected]
All other endpoints, such as /user, /analytics, or /delete, can be called on behalf of a Profile account by adding the "Profile-Key" parameter in the Header.
For example, the /delete endpoint can be called to delete a Profile account's post for the given post id for the provided Profile Key.
const API_KEY = "API_KEY";
const PROFILE_KEY = "PROFILE_KEY";
const id = "Post ID";
fetch("https://app.ayrshare.com/api/delete", {
method: "DELETE",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
"Profile-Key": PROFILE_KEY
},
body: JSON.stringify({
id: id
}),
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch(console.error);
or for a path parameter with /history:
https://app.ayrshare.com/api/history?profileKeys=ldfnk0s82j
Please see the endpoints for further detail.
You can disable and enable social account at either the global level or at the User Profile level.
It is important to note that disabled social networks in the global setting, set via the dashboard, override User Profile settings.
For example, if you turn disable TikTok access in the dashboard, then no User Profile can access TikTok. On the other hand, if you turn on TikTok access in the dashboard but disable it for a specific User Profile, all User Profiles will have access to TikTok except that particular one.
Retrieve the social accounts a User Profile has linked with either the /profiles endpoint or the /user endpoint.
Last modified 2d ago