Introduction
Welcome to the Planly API! You can use our API to schedule posts, upload medias, manage your channels and much more.
Authentication
To authorize, use this code:
fetch('https://app.planly.com/api/...', {
headers: {
'Authorization': 'Bearer api_key'
}
})
Make sure to replace
api_key
with your API key.
Planly uses API keys to allow access to the API. You can get your Planly API key from Settings > Security.
Planly expects for the API key to be included in all API requests to the server in a header that looks like the following:
Authorization: Bearer api_key
Teams
List Teams
fetch('https://app.planly.com/api/teams/list', {
method: 'POST',
headers: { 'Authorization': 'Bearer api_key' },
})
Response:
{
"data": [
{
"id": "874d98cd-34e4-4865-85f4-e9f16172a26f",
"name": "My team",
"picture": "...",
"role": 1,
"users": 7,
"channels": 4
}
]
}
This endpoint retrieves all teams that you belong.
HTTP Request
POST https://app.planly.com/api/teams/list
List Channels
fetch('https://app.planly.com/api/channels/list', {
method: 'POST',
headers: { 'Authorization': 'Bearer api_key' },
body: JSON.stringify({
"team_id": "874d98cd-34e4-4865-85f4-e9f16172a26f"
})
})
HTTP Request
POST https://app.planly.com/api/channels/list
Parameters
Name | Required | Description |
---|---|---|
team_id | yes | ID of the team to retrieve its channels. |
Schedules
List Schedules
fetch('https://app.planly.com/api/v2/schedules/list', {
method: 'POST',
headers: { 'Authorization': 'Bearer api_key' },
body: JSON.stringify({
"teamId": "1ed3a4fa-ff8f-6166-a14e-6850a91715e8",
"pagination": {
"cursor": null,
"orderBy": ["CreatedAt", "DESC"]
}
})
})
Response:
{
"data": {
"rows": [
{
"id": "1ede989b-3576-69b4-8c32-5662aa0940f5",
"media": [
{
"id": "1ede9882-1d09-6fc1-8c32-20e1401dc7b6",
"contentUri": "https://cdn.planly.com/media/...",
"thumbnailUri": "https://cdn.planly.com/media/...",
"contentType": 1
}
],
"content": "hello world",
"status": 1,
"url": null,
"publish_on": "2023-05-18T09:00:00.688Z",
"created_at": "2023-05-03T08:08:34.699515Z"
}
],
"next": "WyIyMDIzLTA4LTI4VDA4OjI4OjE3LjE3ODE4NloiLCJjNDliNTRlMy0wNWQ1LTRlMjgtOTkwOS01NjU3YTAxNmY5M2EiXQ=="
}
}
This endpoint retrieves schedules in a specified team.
For pagination, include next
field returned from response in next request's pagination.cursor
field.
HTTP Request
POST https://app.planly.com/api/v2/schedules/list
Parameters
Name | Required | Description |
---|---|---|
teamId | yes | Id of team to retrieve its schedules. |
pagination.next | Use for pagination |
Delete Schedules
fetch('https://app.planly.com/api/v2/schedules/delete', {
method: 'POST',
headers: { 'Authorization': 'Bearer api_key' },
body: JSON.stringify({
"ids": ["1ede989b-3576-69b4-8c32-5662aa0940f5"]
})
})
HTTP Request
POST https://app.planly.com/api/v2/schedules/delete
Parameters
Name | Required | Description |
---|---|---|
ids | yes | UUID array with IDs' of schedules to delete. |
Create Schedule
fetch('https://app.planly.com/api/v2/schedules/create', {
method: 'POST',
headers: { 'Authorization': 'Bearer api_key' },
body: JSON.stringify({
"schedules": [
{
"channelId": "48e092b8-1d45-4736-acb2-3717218c0f52",
"publishOn": "2023-11-29T20:00:00.356Z",
"status": 1,
"content": "Hello world",
"media": [
{
"options": {},
"id": "f9560569-3089-49de-9b17-b1f52bc03588"
}
],
"options": {
"selfDeclaredMadeForKids": true,
"notifySubscribers": true,
"allowEmbedding": true,
"title": "My YouTube video",
"categoryId": "28",
"privacyStatus": "public",
"firstCommentEnabled": true,
"firstComment": "My comment"
}
},
{
"channelId": "c44ed066-a234-4a1d-a1ba-86acca71ae4b",
"publishOn": "2023-11-29T20:00:00.356Z",
"status": 1,
"content": "Hello world",
"media": [
{
"options": {},
"id": "f9560569-3089-49de-9b17-b1f52bc03588"
}
],
"options": {
"postType": 0,
"firstComment": true,
"firstCommentContent": "My comment for Instagram"
}
}
]
})
})
HTTP Request
POST https://app.planly.com/api/v2/schedules/create
Parameters
Name | Required | Description |
---|---|---|
channelId | yes | |
publishOn | no | Planly will publish schedule at this date and time. If not specified, schedule should be published immediately |
status | no | Status of schedule. 0 for Draft, 1 for Scheduled. Default is 1 (Scheduled) |
content | no | Text content for post |
media[] | no | An array of media (video, image or gif) |
options | no | Social network specific options. (Youtube video category, Instagram post type etc. Detailed docs coming soon) |
Media
Overview
To upload media files to Planly you need to first send request to start-upload
endpoint with your file size to get uploadUrl
.
Then upload your files to that url with HTTP PUT
request. After your upload finishes, call finish-upload
endpoint.
Start Upload
fetch('https://app.planly.com/api/v2/media/start-upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer api_key'
},
body: JSON.stringify({
teamId: "1ed3a4fa-ff8f-6166-a14e-6850a91715e8",
contentLength: 3431948,
contentType: "video/mp4",
fileName: "hello.mp4",
})
})
Response:
{
"mediaId": "8deb9b93-38ad-448b-ac4b-3bfbc7307214",
"uploadUrl": "https://planly.s3-accelerate.amazonaws.com/tmp/738536fa54e06b3db16faf726aa6b4913b150e083ceb73669eef4c12ad27dbc7.mp4?X-Amz-Expires=3600&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA46UUZUWCMLGVL6FO%2F20241008%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20241008T081906Z&X-Amz-SignedHeaders=content-length%3Bhost&X-Amz-Signature=d2913f3dae59fd9de669928cd6b01c40c5dd0c042499318e472bfeef1e0273ab",
"verb": "PUT",
"headers": {
"Content-Type": "video/mp4",
"Content-Length": "3431948"
}
}
To initiate the upload process for your media file to Planly, call the start-upload
endpoint. The fields teamId
and contentLength
are mandatory. Additionally, you must provide at least one of the contentType
or fileName
fields. If both contentType
and fileName
are provided, only contentType
will be honored.
As a response, this endpoint returns a unique mediaId
and a pre-signed uploadUrl
to which you can upload your file using a PUT
request.
Important: The file size (contentLength
) will be validated during the upload. For example, if you specify a size of 10MB but attempt to upload a 15MB file, the upload will be rejected.
HTTP Request
POST https://app.planly.com/api/v2/media/start-upload
Parameters
Name | Required | Description |
---|---|---|
teamId |
Yes | ID of the team to which the media will be uploaded. |
contentLength |
Yes | Size of the file in bytes. |
contentType |
Yes, if fileName is not provided |
MIME type of the file (e.g., video/mp4 ). |
fileName |
Yes, if contentType is not provided |
Name of the file being uploaded. |
Finish Upload
fetch('https://app.planly.com/api/v2/media/finish-upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer api_key'
},
body: JSON.stringify({
mediaId: "8deb9b93-38ad-448b-ac4b-3bfbc7307214"
})
})
Response:
{
"data": {
"id": "8deb9b93-38ad-448b-ac4b-3bfbc7307214",
"note": null,
"contentType": 0,
"contentLength": 3431948,
"thumbnailUri": "https://cdn.planly.com/media/1ed3a4faff8f6166a14e6850a91715e8/B15188655D80028A-thumb.jpg",
"contentUri": "https://cdn.planly.com/media/1ed3a4faff8f6166a14e6850a91715e8/B15188655D80028A.mp4",
"labels": [],
"starred": false,
"duration": 30150,
"resolution": {
"width": 1920,
"height": 1200
},
"width": 1920,
"height": 1200,
"createdAt": "2024-10-08T08:19:09.1257662Z",
"createdBy": {
"id": "1ed3a4fa-ff8f-615d-a14e-9b251da9cf9a",
"fullname": "Mister Feature",
"picture": "https://cdn.planly.com/upp/1E41D8FE08430484.jpg"
}
},
"error": null
}
To complete the upload process for your media file, call the finish-upload
endpoint. This step is necessary to confirm that the file was successfully uploaded and to finalize its storage on the server. You must provide the mediaId
that was returned in the response of the start-upload
request.
As a response, this endpoint returns metadata for the uploaded file, including the file's direct URL, resolution, duration (for videos), and creation details.
HTTP Request
POST https://app.planly.com/api/v2/media/finish-upload
Parameters
Name | Required | Description |
---|---|---|
mediaId |
Yes | The unique ID of the media file returned from the start-upload response. |
Import Media from URL
fetch('https://app.planly.com/api/media/import', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer api_key'
},
body: JSON.stringify({
team_id: "1ed3a4fa-ff8f-6166-a14e-6850a91715e8",
link: "https://http.cat/200.jpg",
name: "Awesome cat photo",
})
})
The response is identical to
/media/upload
To import media from URL to your team use this endpoint. Supported media content types are video/mp4
, image/png
, image/jpeg
, image/webp
.
HTTP Request
POST https://app.planly.com/api/media/import
Parameters
Name | Required | Description |
---|---|---|
team_id | yes | Id of team to import media. |
link | yes | URL of remote media file. |
name | no | Description of media. |
List Media
fetch('https://app.planly.com/api/media/list', {
method: 'POST',
headers: { 'Authorization': 'Bearer api_key' },
body: JSON.stringify({
"team_id": "1ed3a4fa-ff8f-6166-a14e-6850a91715e8",
"cursor": null
})
})
Response:
{
"data": {
"medias": [
{
"id": "1ede9882-1d09-6fc1-8c32-20e1401dc7b6",
"note": "",
"content_type": 1,
"content_length": 200117,
"thumbnail_uri": "...",
"content_uri": "...",
"labels": [],
"starred": false,
"duration": 0,
"resolution": {
"width": 1412,
"height": 958
},
"created_at": "2023-05-03T07:57:21.646549Z",
"created_by": {
"id": "1ed3a4fa-ff8f-615d-a14e-9b251da9cf9a",
"fullname": "John Doe",
"picture": "..."
},
"usage": 0
}
],
"cursor": [
"1ed9cb26-c8e0-6b53-a4ea-721f892988ee"
]
}
}
This endpoint retrieves medias in a specified team.
HTTP Request
POST https://app.planly.com/api/media/list
Parameters
Name | Required | Description |
---|---|---|
team_id | yes | Id of team to retrieve its medias. |
cursor | Use for pagination |
Delete Media
fetch('https://app.planly.com/api/media/delete', {
method: 'POST',
headers: { 'Authorization': 'Bearer api_key' },
body: JSON.stringify({
"ids": ["1ede9882-1d09-6fc1-8c32-20e1401dc7b6"]
})
})
HTTP Request
POST https://app.planly.com/api/media/delete
Parameters
Name | Required | Description |
---|---|---|
ids | yes | UUID array with IDs' of medias to delete. |
Artificial Intelligence
Get Available Credits
fetch('https://app.planly.com/api/v2/ai/credits?teamId=874d98cd-34e4-4865-85f4-e9f16172a26f', {
method: 'GET',
headers: { 'Authorization': 'Bearer api_key' }
})
Response:
{
"data": 252
}
Get available AI credits left in a team.
HTTP Request
GET https://app.planly.com/api/v2/ai/credits
Query Parameters
Name | Required | Description |
---|---|---|
teamId | yes | Id of team |
Complete Prompt
fetch('https://app.planly.com/api/v2/ai/complete', {
method: 'POST',
headers: { 'Authorization': 'Bearer api_key' },
body: JSON.stringify({
teamId: "874d98cd-34e4-4865-85f4-e9f16172a26f",
prompt: "Who is the first president of USA?",
n: 1
})
})
Response:
{
"data": {
"id": "cmpl-7CUN5FhBapPkwAFRtKNhszvT9fxow",
"choices": [
{
"text": "The first president of the United States was George Washington."
}
]
}
}
Complete text prompt.
HTTP Request
POST https://app.planly.com/api/v2/ai/complete
Parameters
Name | Required | Description |
---|---|---|
teamId | yes | Id of team |
prompt | yes | Prompt as a text |
n | yes | How many results to generate |