Introduction

wavpost lets you publish to LinkedIn, Twitter, and YouTube from a single HTTP endpoint. Connect accounts once via OAuth โ€” then post everywhere with one call.

Base URL

https://api.wavpost.com

Auth

API key (sk_live_โ€ฆ)

Format

JSON

Authentication

Programmatic access uses an Authorization: Bearer sk_live_โ€ฆ API key (create and revoke under Dashboard โ†’ API Keys). The dashboard web app uses a first-party session cookie after you sign in โ€” not a Firebase JWT in Authorization.

Keys start with sk_live_. The full secret is shown only once when created.

Authorization: Bearer sk_live_your_api_key_here

Quickstart

From zero to publishing in 3 steps.

1

Get your API key

Go to Dashboard โ†’ API Keys โ†’ Create key.

sk_live_abc123efg456...  # store this securely, shown only once
2

Check connected platforms

curl https://api.wavpost.com/api/connect/status \
  -H "Authorization: Bearer sk_live_your_key"
3

Publish a post

curl -X POST https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello from the API!",
    "platforms": ["linkedin", "twitter"]
  }'

Posts

POST/api/v1/postsPublish a post

Parameters

NameTypeDescription
text*stringPost content. Max 3000 chars for LinkedIn.
platforms*string[]linkedin ยท twitter ยท youtube
mediaUrlsstring[]Public image URLs. Up to 9 for LinkedIn.
scheduledFordatetimeISO 8601 UTC. Saves post as scheduled.
profilestringProfile slug. Defaults to default profile.
curl -X POST https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "New feature drop!",
    "platforms": ["linkedin", "twitter"],
    "mediaUrls": ["https://your-cdn.com/image.jpg"]
  }'

Response 201

{
  "id": "a6c01b90-37da-4224-9338-e2025626b7bf",
  "text": "New feature drop!",
  "platforms": ["linkedin", "twitter"],
  "status": "published",
  "createdAt": "2025-03-19T07:19:57Z",
  "platformResults": {
    "linkedin": { "ok": true, "platformPostId": "urn:li:share:123456" },
    "twitter": { "ok": false, "error": "Twitter not connected." }
  }
}
GET/api/v1/postsList all posts
curl https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_your_key"

Profiles

Profiles let you manage multiple brands or clients. Each profile has its own set of connected platform accounts. A default profile is created automatically on signup.

GET/api/profilesList profiles
curl https://api.wavpost.com/api/profiles \
  -H "Authorization: Bearer sk_live_your_key"
POST/api/profilesCreate a profile

Parameters

NameTypeDescription
name*stringDisplay name for the profile
curl -X POST https://api.wavpost.com/api/profiles \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Brand"}'
PATCH/api/profiles/{profileId}Update a profile

Parameters

NameTypeDescription
namestringNew display name
isDefaultbooleanSet as the default profile
DELETE/api/profiles/{profileId}Delete a profile
curl -X DELETE https://api.wavpost.com/api/profiles/profile-uuid \
  -H "Authorization: Bearer sk_live_your_key"

Connections

Connect social accounts via OAuth. Users open the connect URL in their browser โ€” no platform developer apps needed.

GET/api/connect/statusCheck platform connection status

Parameters

NameTypeDescription
profileIdstringQuery param. Uses default profile if omitted.
curl "https://api.wavpost.com/api/connect/status?profileId=uuid" \
  -H "Authorization: Bearer sk_live_your_key"

Response 200

{
  "linkedin": { "connected": true,  "displayName": "Anshu Raj Singh" },
  "twitter":  { "connected": false, "displayName": null },
  "youtube":  { "connected": false, "displayName": null }
}
GET/api/auth/{platform}Start OAuth (browser redirect)

Open this URL in a browser to start the OAuth flow. After connecting, the user is redirected to the dashboard.

# Open in browser โ€” supported platforms: linkedin, twitter, youtube
https://api.wavpost.com/api/auth/linkedin?profileId=your-profile-id
POST/api/connect/{platform}/disconnectDisconnect a platform

Parameters

NameTypeDescription
profileIdstringOptional. Uses default profile if omitted.
curl -X POST https://api.wavpost.com/api/connect/linkedin/disconnect \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"profileId": "uuid"}'

Logs

Every publish attempt, platform connection, and profile change is automatically logged.

GET/api/logsGet activity logs

Parameters

NameTypeDescription
limitintegerNumber of logs. Default 50, max 200.
offsetintegerPagination offset. Default 0.
curl "https://api.wavpost.com/api/logs?limit=20&offset=0" \
  -H "Authorization: Bearer sk_live_your_key"

Response 200

{
  "logs": [
    {
      "id": "uuid",
      "action": "post.published",
      "platform": "linkedin",
      "profileName": "Default",
      "status": "success",
      "metadata": {
        "text": "New feature drop!",
        "platformPostId": "urn:li:share:123456"
      },
      "createdAt": "2025-03-19T07:19:57Z"
    }
  ],
  "total": 42,
  "limit": 20,
  "offset": 0
}

Action types

post.publishedplatform.connectedplatform.disconnectedprofile.createdprofile.deleted

API Keys

API keys start with sk_live_ and don't expire unless revoked. The raw key is shown only once โ€” store it immediately.

GET/api/keysList API keys
curl https://api.wavpost.com/api/keys \
  -H "Authorization: Bearer sk_live_your_key"
POST/api/keysCreate an API key

Parameters

NameTypeDescription
name*stringLabel to identify this key
curl -X POST https://api.wavpost.com/api/keys \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "My agent key"}'

Response 201

{
  "key": { "id": "uuid", "name": "My agent key", "keyPreview": "...x9z2" },
  "rawKey": "sk_live_abc123..."  // shown only once
}
DELETE/api/keys/{keyId}Revoke an API key
curl -X DELETE https://api.wavpost.com/api/keys/key-uuid \
  -H "Authorization: Bearer sk_live_your_key"

Usage & Credits

Check your current plan, credit balance, and recent usage transactions.

GET/api/usageGet usage and credit balance
curl https://api.wavpost.com/api/usage \
  -H "Authorization: Bearer sk_live_your_key"

Response 200

{
  "plan": {
    "id": "free",
    "label": "Free",
    "price": 0
  },
  "credits": {
    "balance": 480,
    "monthlyAllowance": 500,
    "used": 20,
    "resetAt": "2026-04-01T00:00:00.000Z"
  },
  "recentTransactions": [
    {
      "amount": -2,
      "action": "post.published",
      "metadata": { "platforms": ["linkedin"], "breakdown": { "linkedin": 2 } },
      "createdAt": "2026-03-20T09:56:05.000Z"
    }
  ]
}

Credit costs

ActionCost
Twitter/X โ€” post tweet3 credits
Twitter/X โ€” send DM2 credits
Twitter/X โ€” like, unlike, follow, unfollow, bookmark, delete, hide reply1 credit each
Twitter/X โ€” timeline read, user lookupFree
LinkedIn โ€” create post1 credit
LinkedIn โ€” delete post, reshare1 credit each
YouTube โ€” post1 credit
Credits resetMonthly, on plan renewal

LinkedIn

Current access

Scopes approved: openid profile email w_member_social โ€” covers personal profile identity and publishing posts as a member.

1. Connect a LinkedIn account

Open the OAuth URL in a browser. After the user grants access, they are redirected back and the account is saved to the profile.

GET/api/auth/linkedinStart LinkedIn OAuth

Parameters

NameTypeDescription
profileIdstringQuery param. Which profile to connect the account to. Uses default if omitted.
# Open in browser
https://api.wavpost.com/api/auth/linkedin?profileId=your-profile-id

2. What profile data is returned

After connecting, WavPost fetches the user's identity via the OpenID Connect /v2/userinfo endpoint.

FieldScopeDescription
subopenidUnique LinkedIn member ID
nameprofileFull name
pictureprofileProfile photo URL
emailemailPrimary email address
// Stored internally as:
{
  "id": "abc123",                        // LinkedIn member ID (sub)
  "authorUrn": "urn:li:person:abc123",   // used as post author
  "displayName": "Anshu Raj Singh",
  "picture": "https://media.licdn.com/..."
}

3. Publishing posts

Use the standard POST /api/v1/posts endpoint with "linkedin" in the platforms array.

Text post

curl -X POST https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Excited to share our latest update!",
    "platforms": ["linkedin"]
  }'

Single image post

curl -X POST https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Check out this visual!",
    "platforms": ["linkedin"],
    "mediaUrls": ["https://your-cdn.com/image.jpg"]
  }'

Multi-image post (up to 9)

curl -X POST https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Our product gallery:",
    "platforms": ["linkedin"],
    "mediaUrls": [
      "https://your-cdn.com/img1.jpg",
      "https://your-cdn.com/img2.jpg",
      "https://your-cdn.com/img3.jpg"
    ]
  }'

4. Response

{
  "id": "post-uuid",
  "status": "published",
  "platformResults": {
    "linkedin": {
      "ok": true,
      "platformPostId": "urn:li:share:7123456789"
    }
  }
}

The platformPostId is the LinkedIn post URN โ€” you can use this to reference the post on LinkedIn.

5. Limits & notes

ConstraintValue
Max text length3,000 characters
Max images per post9 (multi-image carousel)
Image formatJPEG, PNG, GIF (public URL required)
Post visibilityPUBLIC (feed distribution)
Post authorPersonal member only (company pages require Community Management API)
Access token expiry60 days (LinkedIn default)

5. Delete a post

DELETE/api/v1/linkedin/postDelete a LinkedIn post โ€” 1 credit

Parameters

NameTypeDescription
post_urn*stringLinkedIn post URN returned from create post (e.g. urn:li:share:123456)
curl -X DELETE https://api.wavpost.com/api/v1/linkedin/post \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"post_urn": "urn:li:share:7442092074763481088"}'

Response 200

{ "ok": true, "deleted": true, "postUrn": "urn:li:share:7442092074763481088" }

6. Reshare a post

POST/api/v1/linkedin/reshareReshare a LinkedIn post โ€” 1 credit

Parameters

NameTypeDescription
post_urn*stringURN of the post to reshare (e.g. urn:li:share:123456)
commentarystringOptional text to add above the reshare. Max 3000 chars.
curl -X POST https://api.wavpost.com/api/v1/linkedin/reshare \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "post_urn": "urn:li:share:7442092074763481088",
    "commentary": "Great post worth sharing!"
  }'

Response 201

{ "ok": true, "reshareId": "urn:li:share:7442092169974145024" }

Not available โ€” requires LinkedIn Partnership

  • โ€ข Reactions (like, praise, etc.) โ€” requires partnerApiReactions
  • โ€ข Comments on posts โ€” requires partnerApiSocialActions
  • โ€ข Analytics (impressions, clicks) โ€” requires r_member_social

Twitter / X

Current access

Uses OAuth 2.0 PKCE. Scopes requested:

tweet.readtweet.writeusers.readoffline.accessmedia.writelike.readlike.writefollows.readfollows.writebookmark.readbookmark.writetweet.moderate.writedm.readdm.write

1. Connect a Twitter / X account

GET/api/auth/twitterStart Twitter OAuth (PKCE)

Parameters

NameTypeDescription
profileIdstringQuery param. Which profile to connect the account to. Uses default if omitted.
# Open in browser
https://api.wavpost.com/api/auth/twitter?profileId=your-profile-id

2. Profile data returned

FieldDescription
idUnique Twitter user ID
nameDisplay name
usernameHandle (e.g. wavpost)
pictureProfile image URL

3. Publishing tweets

Publish tweets with text. Media uploads (photos, videos) are available via the media.write scope.

POST/api/v1/postsPublish a tweet
curl -X POST https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Shipping social features in minutes. ๐Ÿš€",
    "platforms": ["twitter"]
  }'

Response 201

{
  "id": "post-uuid",
  "status": "published",
  "platformResults": {
    "twitter": {
      "ok": true,
      "platformPostId": "1856234567890123456"
    }
  }
}

4. Delete a tweet

DELETE/api/v1/twitter/tweetDelete a tweet โ€” 1 credit

Parameters

NameTypeDescription
tweet_id*stringID of the tweet to delete
curl -X DELETE https://api.wavpost.com/api/v1/twitter/tweet \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"tweet_id": "1856234567890123456"}'
{ "ok": true, "deleted": true, "tweetId": "1856234567890123456" }

5. Like / Unlike a tweet

POST/api/v1/twitter/likeLike a tweet โ€” 1 credit

Parameters

NameTypeDescription
tweet_id*stringID of the tweet to like
curl -X POST https://api.wavpost.com/api/v1/twitter/like \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"tweet_id": "1856234567890123456"}'
{ "ok": true, "liked": true }
DELETE/api/v1/twitter/likeUnlike a tweet โ€” 1 credit

Parameters

NameTypeDescription
tweet_id*stringID of the tweet to unlike
{ "ok": true, "liked": false }

6. Follow / Unfollow a user

Use GET /api/v1/twitter/user?username=handle to resolve a username to a user ID first.

POST/api/v1/twitter/followFollow a user โ€” 1 credit

Parameters

NameTypeDescription
target_user_id*stringTwitter user ID to follow
curl -X POST https://api.wavpost.com/api/v1/twitter/follow \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"target_user_id": "3433773514"}'
{ "ok": true, "following": true, "pending_follow": false }
DELETE/api/v1/twitter/followUnfollow a user โ€” 1 credit

Parameters

NameTypeDescription
target_user_id*stringTwitter user ID to unfollow
{ "ok": true, "following": false }

7. Bookmark / Remove bookmark

POST/api/v1/twitter/bookmarkBookmark a tweet โ€” 1 credit

Parameters

NameTypeDescription
tweet_id*stringID of the tweet to bookmark
curl -X POST https://api.wavpost.com/api/v1/twitter/bookmark \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"tweet_id": "1856234567890123456"}'
{ "ok": true, "bookmarked": true }
DELETE/api/v1/twitter/bookmarkRemove a bookmark โ€” free

Parameters

NameTypeDescription
tweet_id*stringID of the tweet to un-bookmark
{ "ok": true, "bookmarked": false }

8. Send a Direct Message

POST/api/v1/twitter/dmSend a DM โ€” 2 credits

Parameters

NameTypeDescription
recipient_id*stringTwitter user ID of the recipient
text*stringMessage text
curl -X POST https://api.wavpost.com/api/v1/twitter/dm \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"recipient_id": "3433773514", "text": "Hey, great post!"}'
{ "ok": true, "dm_conversation_id": "...", "dm_event_id": "..." }

9. Hide / Unhide a reply

Hides a reply made on one of your own tweets. Only works on replies to your tweets โ€” not on your own replies.

PUT/api/v1/twitter/reply/hideHide or unhide a reply โ€” 1 credit

Parameters

NameTypeDescription
tweet_id*stringID of the reply tweet to hide
hiddenbooleantrue to hide, false to unhide. Defaults to true.
curl -X PUT https://api.wavpost.com/api/v1/twitter/reply/hide \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"tweet_id": "1856234567890123456", "hidden": true}'
{ "ok": true, "hidden": true }

10. Read timeline

GET/api/v1/twitter/timelineGet your recent tweets โ€” free

Parameters

NameTypeDescription
max_resultsintegerNumber of tweets to return. Min 5, max 100. Default 10.
curl "https://api.wavpost.com/api/v1/twitter/timeline?max_results=10" \
  -H "Authorization: Bearer sk_live_your_key"
{
  "ok": true,
  "tweets": [
    { "id": "1856234567890123456", "text": "Hello world!", "createdAt": "2026-03-24T09:00:00.000Z" }
  ],
  "count": 1
}

11. Look up a user by username

GET/api/v1/twitter/userResolve username to user ID โ€” free

Parameters

NameTypeDescription
username*stringTwitter handle without @
curl "https://api.wavpost.com/api/v1/twitter/user?username=ishaansehgal" \
  -H "Authorization: Bearer sk_live_your_key"
{ "ok": true, "user": { "id": "3433773514", "name": "Ishaan Sehgal", "username": "ishaansehgal" } }

12. Limits & notes

ConstraintValue
Max tweet length280 characters
Access token expiry2 hours โ€” auto-refreshed silently via refresh token
Auth methodOAuth 2.0 PKCE
Post tweet3 credits
Send DM2 credits
Like, unlike, follow, unfollow, bookmark, delete, hide reply1 credit each
Timeline read, user lookupFree (0 credits)
Requires paid planAll Twitter endpoints โ€” free plan users are blocked

YouTube

Current access

Scopes: youtube.upload youtube.readonly openid profile โ€” supports video uploads and community text posts.

1. Connect a YouTube channel

GET/api/auth/youtubeStart YouTube OAuth

Parameters

NameTypeDescription
profileIdstringQuery param. Which profile to connect the account to. Uses default if omitted.
# Open in browser
https://api.wavpost.com/api/auth/youtube?profileId=your-profile-id

2. Profile data returned

FieldDescription
idYouTube channel ID
displayNameChannel name
pictureChannel thumbnail URL

3. Publishing

WavPost auto-detects the post type based on mediaUrls: if a video URL is present it uploads a video; otherwise it creates a community post.

Video upload

Pass a direct video URL in mediaUrls. The first line of text becomes the video title (max 100 chars); the full text becomes the description.

curl -X POST https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "My video title\nFull description goes here.",
    "platforms": ["youtube"],
    "mediaUrls": ["https://your-cdn.com/video.mp4"]
  }'

Community post (text)

Requires 500+ subscribers on the connected channel.

curl -X POST https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Check out our latest update!",
    "platforms": ["youtube"]
  }'

Response 201

// Video upload
{
  "platformResults": {
    "youtube": {
      "ok": true,
      "platformPostId": "https://youtube.com/watch?v=dQw4w9WgXcQ"
    }
  }
}

// Community post
{
  "platformResults": {
    "youtube": {
      "ok": true,
      "platformPostId": "Ug_community_post_id"
    }
  }
}

4. Limits & notes

ConstraintValue
Video formatsmp4, mov, avi, mkv, webm, flv, wmv (public URL required)
Video titleFirst line of text, max 100 characters
Video visibilityPublic
Video categoryPeople & Blogs (categoryId: 22)
Community postsRequires 500+ subscribers
Access token expiry1 hour (refresh token issued automatically)
Auth methodOAuth 2.0 (Google)
Credit cost1 credit per post

Platforms

PlatformIDTextImagesAuth method
LinkedInlinkedinโœ“Up to 9OAuth 2.0
Twitter / Xtwitterโœ“โ€”OAuth 2.0 PKCE
YouTubeyoutubeโœ“โ€”OAuth 2.0

AI Agents

Two machine-readable formats are available for AI agents and OpenAPI toolchains.

# 1. Fetch the API reference for your agent
curl https://api.wavpost.com/llms.txt

# 2. Agent calls the API
curl -X POST https://api.wavpost.com/api/v1/posts \
  -H "Authorization: Bearer sk_live_agent_key" \
  -H "Content-Type: application/json" \
  -d '{"text": "Agent-generated post!", "platforms": ["linkedin"]}'

Errors

All errors return a JSON body with an error field.

{ "error": "Missing or invalid 'text' (string)" }
StatusMeaning
200Success
201Resource created successfully
400Bad request โ€” missing or invalid fields
401Unauthorized โ€” missing, invalid, or revoked token
404Not found โ€” profile or platform does not exist