UniPost API Documentation

One API to post across all major social platforms.

Overview

UniPost is a unified social media API that lets developers integrate posting capabilities into their products without dealing with each platform individually. Connect social accounts once, then publish content to Bluesky, LinkedIn, Instagram, Threads, TikTok, and YouTube through a single API call.

Base URL

https://api.unipost.dev

Response Format

JSON

All responses follow this structure:

// Success
{ "data": { ... }, "meta": { "total": 10, "page": 1, "per_page": 20 } }

// Error
{ "error": { "code": "UNAUTHORIZED", "message": "Invalid API key" } }

Authentication

All API requests require a Bearer token in the Authorization header. Create API keys in your project dashboard at app.unipost.dev.

Example

curl https://api.unipost.dev/v1/social-accounts \
  -H "Authorization: Bearer up_live_your_api_key_here"

Key format: up_live_ (production) or up_test_ (test)

Security: Keys are shown only once at creation. Store them securely — never commit to version control.

Quick Start

Get posting in 3 steps:

1. Connect a social account

curl -X POST https://api.unipost.dev/v1/social-accounts/connect \
  -H "Authorization: Bearer up_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "bluesky",
    "credentials": {
      "handle": "yourname.bsky.social",
      "app_password": "xxxx-xxxx-xxxx-xxxx"
    }
  }'

2. Get your account ID from the response

{
  "data": {
    "id": "sa_abc123",
    "platform": "bluesky",
    "account_name": "yourname.bsky.social",
    "status": "active"
  }
}

3. Create a post

curl -X POST https://api.unipost.dev/v1/social-posts \
  -H "Authorization: Bearer up_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "Hello from UniPost!",
    "account_ids": ["sa_abc123"]
  }'

Social Accounts

Connect, list, and disconnect social media accounts.

POST/v1/social-accounts/connectAPI Key

Connect a new social media account. For Bluesky, provide credentials directly. For OAuth platforms (LinkedIn, Instagram, Threads, TikTok, YouTube), use the OAuth flow instead.

Request Body

platformstringrequiredPlatform identifier: bluesky
credentialsobjectrequiredPlatform-specific credentials

Example: Connect Bluesky

curl -X POST https://api.unipost.dev/v1/social-accounts/connect \
  -H "Authorization: Bearer up_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "bluesky",
    "credentials": {
      "handle": "alice.bsky.social",
      "app_password": "xxxx-xxxx-xxxx-xxxx"
    }
  }'

Response (201)

{
  "data": {
    "id": "sa_abc123",
    "platform": "bluesky",
    "account_name": "alice.bsky.social",
    "connected_at": "2026-04-02T10:00:00Z",
    "status": "active"
  }
}
GET/v1/social-accountsAPI Key

List all connected social accounts for the current project.

Example

curl https://api.unipost.dev/v1/social-accounts \
  -H "Authorization: Bearer up_live_your_key"

Response (200)

{
  "data": [
    {
      "id": "sa_abc123",
      "platform": "bluesky",
      "account_name": "alice.bsky.social",
      "connected_at": "2026-04-02T10:00:00Z",
      "status": "active"
    },
    {
      "id": "sa_def456",
      "platform": "linkedin",
      "account_name": "Alice Smith",
      "connected_at": "2026-04-02T11:00:00Z",
      "status": "active"
    }
  ],
  "meta": { "total": 2, "page": 1, "per_page": 20 }
}
DELETE/v1/social-accounts/{id}API Key

Disconnect a social account. The account's tokens are invalidated.

Example

curl -X DELETE https://api.unipost.dev/v1/social-accounts/sa_abc123 \
  -H "Authorization: Bearer up_live_your_key"

Response (200)

{ "data": { "disconnected": true } }

Social Posts

Create, list, get, and delete social media posts. Posts can be published to multiple accounts simultaneously.

POST/v1/social-postsAPI Key

Create and publish a post to one or more connected accounts. Posts are published concurrently — one failure won't block others.

Request Body

captionstringrequiredThe text content of the post
account_idsstring[]requiredArray of social account IDs to post to
media_urlsstring[]Array of media URLs (images for Instagram, videos for TikTok/YouTube)

Response Headers

X-UniPost-UsageheaderCurrent usage, e.g. 450/1000
X-UniPost-WarningheaderWarning level: approaching_limit (80%+) or over_limit (100%+)

Example: Post to multiple platforms

curl -X POST https://api.unipost.dev/v1/social-posts \
  -H "Authorization: Bearer up_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "Hello from UniPost! 🚀",
    "account_ids": ["sa_bluesky_123", "sa_linkedin_456"],
    "media_urls": ["https://example.com/image.jpg"]
  }'

Response (200)

{
  "data": {
    "id": "post_xyz789",
    "caption": "Hello from UniPost! 🚀",
    "status": "published",
    "created_at": "2026-04-02T12:00:00Z",
    "results": [
      {
        "social_account_id": "sa_bluesky_123",
        "platform": "bluesky",
        "status": "published",
        "external_id": "at://did:plc:xxx/app.bsky.feed.post/yyy",
        "published_at": "2026-04-02T12:00:01Z"
      },
      {
        "social_account_id": "sa_linkedin_456",
        "platform": "linkedin",
        "status": "published",
        "external_id": "urn:li:share:123456",
        "published_at": "2026-04-02T12:00:01Z"
      }
    ]
  }
}

Post status values:

  • published — all accounts succeeded
  • partial — some accounts succeeded, some failed
  • failed — all accounts failed
GET/v1/social-posts/{id}API Key

Get a post with its per-account results. For TikTok posts, includes real-time publish status from TikTok.

Example

curl https://api.unipost.dev/v1/social-posts/post_xyz789 \
  -H "Authorization: Bearer up_live_your_key"
GET/v1/social-postsAPI Key

List all posts for the current project, ordered by creation date (newest first).

Example

curl https://api.unipost.dev/v1/social-posts \
  -H "Authorization: Bearer up_live_your_key"
DELETE/v1/social-posts/{id}API Key

Delete a post. Attempts to delete from all platforms where it was published.

Example

curl -X DELETE https://api.unipost.dev/v1/social-posts/post_xyz789 \
  -H "Authorization: Bearer up_live_your_key"

Response (200)

{ "data": { "deleted": true } }

Webhooks

Register webhook endpoints to receive notifications about post status changes.

POST/v1/webhooksAPI Key

Register a webhook endpoint.

urlstringrequiredHTTPS URL to receive events
eventsstring[]requiredEvent types: post.published, post.failed, account.connected, account.disconnected
secretstringrequiredSecret for HMAC-SHA256 signature verification

Example

curl -X POST https://api.unipost.dev/v1/webhooks \
  -H "Authorization: Bearer up_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/unipost",
    "events": ["post.published", "post.failed"],
    "secret": "your_webhook_secret"
  }'

Webhook payload format:

{
  "event": "post.published",
  "timestamp": "2026-04-02T12:00:01Z",
  "data": {
    "post_id": "post_xyz789",
    "social_account_id": "sa_abc123",
    "platform": "bluesky",
    "external_id": "at://did:plc:xxx/app.bsky.feed.post/yyy"
  }
}

Verify signatures with the X-UniPost-Signature header:

expected = HMAC-SHA256(your_secret, request_body)
actual = headers["X-UniPost-Signature"].replace("sha256=", "")
assert expected == actual
GET/v1/webhooksAPI Key

List all registered webhooks for the current project.

Example

curl https://api.unipost.dev/v1/webhooks \
  -H "Authorization: Bearer up_live_your_key"

OAuth Flow

For platforms that require OAuth (LinkedIn, Instagram, Threads, TikTok, YouTube), use the OAuth connect endpoint to get an authorization URL, then redirect the user.

GET/v1/oauth/connect/{platform}API Key

Get an OAuth authorization URL for the specified platform.

platformpathrequiredOne of: linkedin, instagram, threads, tiktok, youtube
redirect_urlqueryURL to redirect to after authorization

Example

curl "https://api.unipost.dev/v1/oauth/connect/linkedin?redirect_url=https://your-app.com/callback" \
  -H "Authorization: Bearer up_live_your_key"

Response (200)

{
  "data": {
    "auth_url": "https://www.linkedin.com/oauth/v2/authorization?client_id=...&state=..."
  }
}

Redirect the user to auth_url. After authorization, they'll be redirected to your redirect_url with ?status=success&account_name=... or ?status=error&error=....

Billing & Usage

UniPost uses a soft-block quota system. Exceeding your limit won't interrupt service — you'll receive warnings via response headers and dashboard notifications.

Plans

Free

$0/mo

100 posts

Starter

$10/mo

1,000 posts

Growth

$50/mo

5,000 posts

Scale

$150/mo

20,000 posts

Additional tiers available: $25, $75, $300, $500, $1000/mo.See full pricing

Usage headers on POST /v1/social-posts:

# Normal usage
X-UniPost-Usage: 450/1000

# Approaching limit (80%+)
X-UniPost-Usage: 820/1000
X-UniPost-Warning: approaching_limit

# Over limit (still processing, upgrade recommended)
X-UniPost-Usage: 1050/1000
X-UniPost-Warning: over_limit

Error Handling

CodeStatusDescription
UNAUTHORIZED401Invalid or missing API key
FORBIDDEN403No access to this resource
NOT_FOUND404Resource not found
VALIDATION_ERROR422Invalid request parameters
INTERNAL_ERROR500Server error

Error response format

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Caption is required"
  }
}

Supported Platforms

Bluesky

App Password

Content: Text, Images

Generate an App Password at bsky.app → Settings → App Passwords

LinkedIn

OAuth

Content: Text, Links

Requires Share on LinkedIn product

Instagram

OAuth

Content: Images (required)

Must have an Instagram Business or Creator account

Threads

OAuth

Content: Text, Images

Uses Meta developer app

TikTok

OAuth

Content: Video (required)

Video must be MP4/H.264 with audio, min 3 seconds

YouTube

OAuth

Content: Video (required)

Requires YouTube Data API v3