Skip to contentdeploy.social
API and MCP

API quickstart

Create a workspace API key, add a video, make a draft and check how it posts through the deploy.social API.

Create a key

#

API keys come with Standard and our Studio plan. Open Account → API in Deploy and create a key for one workspace. Choose read access to look things up, or read and write access to add videos and posts. A key acts as the member who created it, within that workspace.

Copy the key when it appears. It starts with ds_live_. Set it as DEPLOY_API_KEY in your shell or server environment; the examples below read that variable.

Keep the key like a password. If it is ever exposed, revoke it from Account → API and make a new one.

Use the base URL

#

Send requests to https://api.deploy.social/v1 with Authorization: Bearer followed by your key. Requests and responses use JSON. As you go, save the ids each step returns as the environment variables DESTINATION_ID, MEDIA_ID and POST_ID; the later examples read them. The JavaScript runs as an ES module on Node 18 or later; the Python uses requests.

Check your key

#

GET /me returns key, workspace, plan, usage and limits. Check the workspace name before you write to it. The limits object shows this key's request allowance and today's API post allowance.

curl
curl -sS -X GET "https://api.deploy.social/v1/me" \
  -H "Authorization: Bearer $DEPLOY_API_KEY"

Find your destinations

#

GET /destinations returns data, a list of connected accounts. Pick an account whose status is active and save its id as DESTINATION_ID. The list also gives its platform, handle and video limits.

For TikTok, read GET /destinations/{id}/options before posting. The person posting must choose a privacy option and see the creator details. Platform rules explains why.
curl
curl -sS -X GET "https://api.deploy.social/v1/destinations" \
  -H "Authorization: Bearer $DEPLOY_API_KEY"

Check destination options

#

GET /destinations/{id}/options returns the settings this connected account accepts. Read each option's key, values, default and required fields before making a post. For TikTok, it also returns creator and max_duration_sec; show the creator details and privacy choices to the person posting.

curl
curl -sS -X GET "https://api.deploy.social/v1/destinations/$DESTINATION_ID/options" \
  -H "Authorization: Bearer $DEPLOY_API_KEY"

Start an upload

#

For a local file, send filename, size_bytes and content_type to POST /media/uploads. The response has media.id and an upload object with url, method, headers and expires_at. Save the id as MEDIA_ID and the upload details for the next step.

Set VIDEO_PATH to your video file. The examples send an MP4 called hiking-supercut.mp4; for a MOV, WebM, AVI or MTS file, change filename and content_type to match (video/quicktime, video/webm, video/x-msvideo, video/mp2t). A file can be up to 1 GB.
curl
curl -sS -X POST "https://api.deploy.social/v1/media/uploads" \
  -H "Authorization: Bearer $DEPLOY_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"filename\":\"hiking-supercut.mp4\",\"size_bytes\":$(wc -c < "$VIDEO_PATH"),\"content_type\":\"video/mp4\"}"

Send the file

#

PUT the file bytes to upload.url, using upload.headers exactly as returned. The link is already signed, so leave your API key off this request. For these examples, set UPLOAD_URL to upload.url and UPLOAD_CONTENT_TYPE to the Content-Type in upload.headers. curl's -T sends the file straight from disk, so a large video never has to fit in memory.

curl
curl -sS -T "$VIDEO_PATH" -H "Content-Type: $UPLOAD_CONTENT_TYPE" "$UPLOAD_URL"

Complete the upload

#

Once the PUT succeeds, call POST /media/{id}/complete with MEDIA_ID. Deploy starts preparing the video and returns it with status set to processing.

curl
curl -sS -X POST "https://api.deploy.social/v1/media/$MEDIA_ID/complete" \
  -H "Authorization: Bearer $DEPLOY_API_KEY"

Or import from a URL

#

If your video already has a public HTTPS link straight to the file, use POST /media/imports instead of the three upload steps. Send url and, if you like, filename. Deploy downloads it in the background and returns the video right away; save its id as MEDIA_ID.

The URL must point to an MP4, MOV, WebM, AVI or MTS file, not a page that plays it.
curl
curl -sS -X POST "https://api.deploy.social/v1/media/imports" \
  -H "Authorization: Bearer $DEPLOY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/videos/hiking-supercut.mp4"}'

Wait for the video

#

Poll GET /media/{id} every few seconds until status is ready. While it is uploading or processing, progress may show a phase and percent. If it becomes failed, error.message says why. Stop polling on any status other than uploading or processing.

curl
curl -sS -X GET "https://api.deploy.social/v1/media/$MEDIA_ID" \
  -H "Authorization: Bearer $DEPLOY_API_KEY"

Create a draft

#

Send media_id, a caption and a destinations list with at least one destination_id to POST /posts. Leave out publish_at to save a draft. The response has status set to draft, a review_url that opens it in Deploy, and any issues still to fix. Save its id as POST_ID.

A destination's settings go in its options, by the keys GET /destinations/{id}/options listed. To publish or schedule in the same request, add publish_at as now or an ISO time with a timezone offset, such as 2026-11-29T09:00:00-07:00. The video must be ready for that.

curl
curl -sS -X POST "https://api.deploy.social/v1/posts" \
  -H "Authorization: Bearer $DEPLOY_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"media_id\":\"$MEDIA_ID\",\"caption\":\"Hiking Supercut\",\"destinations\":[{\"destination_id\":\"$DESTINATION_ID\"}]}"

Publish the draft

#

Once the draft has no issues with severity set to error, send publish_at as now to POST /posts/{id}/publish, or an ISO time with an offset to schedule it. A scheduled post uses this same path to move its time or go out now. The post comes back as publishing or scheduled.

curl
curl -sS -X POST "https://api.deploy.social/v1/posts/$POST_ID/publish" \
  -H "Authorization: Bearer $DEPLOY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"publish_at":"now"}'

Check the post

#

GET /posts/{id} shows the post's status and each destination's status, url, warning and failure. Posting runs in the background, so poll this path until every destination is published, failed or cancelled.

Webhooks are coming. For now, poll GET /posts/{id} to learn whether each destination posted.
curl
curl -sS -X GET "https://api.deploy.social/v1/posts/$POST_ID" \
  -H "Authorization: Bearer $DEPLOY_API_KEY"

Retry safely

#
Send an Idempotency-Key header, such as a UUID, on any POST you may retry. Sending the same key with the same request within 24 hours in the same workspace returns the first response again, with Idempotent-Replayed: true, instead of doing it twice. A different request needs a new key.