Skip to content

The uploads resource is the core of the SDK. Use it for every kind of post.

Methods

MethodWhat it does
text()Publish text-only content
photos()Publish one or more images
video()Publish a single video
document()Publish a PDF / document
list()Paginate post history
get(id)Fetch one post
getStatus(id)Get the current status + channel results
waitForCompletion(id)Poll getStatus until terminal state
update(id, params)Edit a draft
publishDraft(id)Publish a saved draft
publishNow(id)Move a scheduled post forward
retry(id)Retry failed channels
cancel(id)Delete an upload
archive(id) / unarchive(id)Soft archive
bulkDelete(ids) / bulkArchive(ids) / bulkUnarchive(ids)Batch ops

Posting text

typescript
const upload = await socifyr.uploads.text({
  connections: ['linkedin-myhandle', 'x-myhandle'],
  text: 'Just shipped v2.0 🚀',
})

Posting photos

typescript
import { readFileSync } from 'fs'

await socifyr.uploads.photos({
  connections: ['instagram-mybrand'],
  text: 'Carousel of the week',
  medias: [
    readFileSync('a.jpg'),
    readFileSync('b.jpg'),
    'https://cdn.example.com/c.png', // public URL
    '6a04f715d3d7d93575e65d13', // media library ID
  ],
  contentFormat: 'photo_carousel',
})

medias accepts any mix of:

  • Buffer / Blob (raw file — auto-uploaded to media library)
  • string starting with https:// or http:// (public URL)
  • string matching /^[a-f\d]{24}$/i (media library ID)

Posting video

typescript
await socifyr.uploads.video({
  connections: ['instagram-mybrand', 'tiktok-me'],
  text: 'Behind the scenes',
  medias: [readFileSync('demo.mp4')],
  contentFormat: 'short_video', // make it a reel
})

Only one video per post.

Scheduling

Add scheduledAt:

typescript
await socifyr.uploads.text({
  connections: ['linkedin-myhandle'],
  text: 'Tomorrow at 9am',
  scheduledAt: '2026-06-01T09:00:00Z',
  timezone: 'America/New_York', // optional, for display
})

Drafts

Add saveDraft: true to save without publishing:

typescript
const upload = await socifyr.uploads.photos({
  connections: ['instagram-mybrand'],
  medias: [readFileSync('banner.jpg')],
  text: 'Polish me later',
  saveDraft: true,
})

// Later — edit
await socifyr.uploads.update(upload.id, {
  text: 'Final caption',
})

// Then publish
await socifyr.uploads.publishDraft(upload.id)

Checking status

typescript
const status = await socifyr.uploads.getStatus(upload.id)
//  {
//    uploadId: '...',
//    requestId: '...',
//    status: 'partial_failure',
//    type: 'text',
//    channels: [
//      { platform: 'linkedin', result: { status: 'success', postUrl: '...' } },
//      { platform: 'x', result: { status: 'failed', error: '...' } },
//    ],
//    createdAt: '...',
//  }

// Or poll until done
const final = await socifyr.uploads.waitForCompletion(upload.id, 3000, 300_000)

waitForCompletion(id, intervalMs?, timeoutMs?) blocks until status is completed, failed, or partial_failure.

Retrying

typescript
await socifyr.uploads.retry(upload.id)

Successful channels are skipped via an idempotency guard.

Listing history

typescript
const { data, total, page, limit } = await socifyr.uploads.list({
  page: 1,
  limit: 20,
  status: 'completed',
  type: 'video',
  from: '2026-01-01',
  to: '2026-06-01',
})

Archive / delete

typescript
await socifyr.uploads.archive(id)         // hide from history without deleting
await socifyr.uploads.unarchive(id)
await socifyr.uploads.cancel(id)          // hard delete
await socifyr.uploads.bulkDelete([id1, id2, id3])

Full type reference

The TypeScript types are exported from the SDK root:

typescript
import type {
  Upload,
  UploadVideoParams,
  UploadPhotosParams,
  UploadTextParams,
  UploadDocumentParams,
  UploadStatusResponse,
  UploadStatusChannel,
  UpdateDraftParams,
  UploadHistoryQuery,
  PaginatedResponse,
} from '@socifyr/sdk'