Submissions over WebSocket
A submission is one video published to one account. Create it, then watch its status until
it settles.
All six funs need the submissions ability. See Frames for the request
and reply envelope, Overview for the status table, and
Events for the submission push that saves you polling.
| Fun | Data fields | Reply |
|---|---|---|
/app/submissions/list | page, platform | 200 with {data, meta} |
/app/submissions/get | submission | 200 with one submission |
/app/submissions/create | platform, account, one of video_url or upload_id, caption, draft | 201 with the created submission |
/app/submissions/cancel | submission | 200 with the cancelled submission |
/app/submissions/delete | submission | 204 with data: null |
/app/submissions/upload-url | (none) | 201 with {upload_id, upload_url, expires_at} |
The submission shape
Code
A submission id is an integer, not a UUID. failure is null unless status is
failed, in which case it is {"step": "...", "message": "..."} naming the stage that failed
and what to do next.
List submissions
| Field | Type | Description | |
|---|---|---|---|
page | integer | optional | Page number, 1 or more. Defaults to 1. |
platform | string | optional | Narrow to tiktok, instagram or youtube. |
The reply is {"data": [...], "meta": {"current_page", "last_page", "per_page", "total"}},
50 submissions a page, newest first.
Get a submission
| Field | Type | Description | |
|---|---|---|---|
submission | integer | required | Submission id. |
This is the polling fun. Read status against the
status table.
Create a submission
| Field | Type | Description | |
|---|---|---|---|
platform | string | optional | tiktok, instagram or youtube. Defaults to tiktok. |
account | string | required | Account UUID to post as. |
video_url | string | one of | Public https URL of the video. The server downloads it. |
upload_id | string | one of | Id from /app/submissions/upload-url. |
caption | string | see below | The post's text. |
draft | boolean | optional | Save as a draft on the phone instead of publishing. |
The field is account, not account_id.
Give exactly one of video_url or upload_id. There is no multipart over a socket, so a
local file goes through the upload URL flow below. Sending both is refused with 422, and so
is sending neither.
caption is the caption on TikTok and Instagram, optional and up to 2200 characters. On
YouTube it is the Short's title: required, and capped at 100 characters. Leaving it out on
YouTube is refused with
Give the Short a title. YouTube names an untitled Short after the date.
The account is looked up on the requested platform only. An id from another platform reads the
same as one that does not exist, so a platform that does not match the account answers 404.
The account must already have a phone assigned. If it does not, the reply is 422 on the
account field with This account is not assigned to a phone yet, so it cannot post.
The reply is 201 with the submission in pending. The phone is then driven through the
platform's app.
Cancel a submission
| Field | Type | Description | |
|---|---|---|---|
submission | integer | required | Submission id. |
This stops the phone between steps. A submission that has not started yet is simply marked
cancelled. One that already finished answers 409 with
This submission has already finished. One you cannot see answers 404 with
Submission not found.
Delete a submission
| Field | Type | Description | |
|---|---|---|---|
submission | integer | required | Submission id. |
Deletes a finished submission and its stored video. The reply is 204 with data: null.
A submission still in flight cannot be deleted. Cancel it first, or you get 409 with
Submissions can only be deleted once they have finished processing.
Upload URL
/app/submissions/upload-url takes no fields. It mints a short-lived signed URL you can push
a video to.
Code
Send the video to upload_url within 15 minutes, then pass upload_id to
/app/submissions/create.
The signature in the URL is the grant. The upload endpoint takes no bearer token, and the URL
carries the owning account so /app/submissions/create can check the upload is yours.
Either shape works, POST or PUT:
Code
The file must be MP4 or QuickTime. The endpoint answers 201 with {"upload_id": "..."}, or
422 with No video was uploaded., Video exceeds the maximum allowed size. or
Video must be an MP4 or QuickTime file.
Passing an upload_id that was never filled is refused at create time with 422 on the
upload_id field: Upload not found. Upload the video to the signed URL first.
Worked example: upload a file and publish it
Both SDKs take account_id as the argument name and send it over the socket as account.
The raw frames are the create and the poll, after the file has been pushed to upload_url.
Both SDKs also accept a local file directly. Over a socket they mint the upload URL, push the
bytes over HTTPS and then send upload_id for you:

