Skip to main content

Social API

Social media connections, posts, and publishing.


Social Connections

List Connections

GET /social/connections

Query Parameters

ParameterTypeDescription
tenantIdstringRequired
clubIdstringFilter by club
platformstringFACEBOOK, INSTAGRAM, TWITTER, LINKEDIN
isActivebooleanFilter active

Response: 200 OK

{
"data": [{
"id": "connection_123",
"platform": "FACEBOOK",
"accountId": "page_123456",
"accountName": "Randpark Golf Club",
"accountType": "page",
"permissions": ["pages_manage_posts", "pages_read_engagement"],
"isActive": true,
"lastUsedAt": "2025-12-10T14:00:00Z",
"tokenExpiry": "2026-03-10T14:00:00Z",
"connectedBy": "user_456",
"connectedByName": "Admin User",
"createdAt": "2025-06-01T00:00:00Z"
}]
}

Get Connection

GET /social/connections/:id

Response: 200 OK


Initiate OAuth Connection

Starts the OAuth flow to connect a social media account.

POST /social/connections/connect

Request Body

{
"tenantId": "tenant_123",
"clubId": "club_456",
"platform": "FACEBOOK",
"redirectUri": "https://app.example.com/social/callback"
}

Response: 200 OK

{
"authUrl": "https://facebook.com/v18.0/dialog/oauth?...",
"state": "encrypted_state_token"
}

Usage: Redirect the user to authUrl to complete OAuth authorization.


Complete OAuth Callback

Completes the OAuth flow after user authorization.

POST /social/connections/callback

Request Body

{
"platform": "FACEBOOK",
"code": "oauth_authorization_code",
"state": "encrypted_state_token"
}

Response: 201 Created

{
"id": "connection_123",
"platform": "FACEBOOK",
"accountId": "page_123456",
"accountName": "Randpark Golf Club",
"isActive": true,
"createdAt": "2025-12-14T10:00:00Z"
}

Disconnect

Removes a social media connection.

DELETE /social/connections/:id

Response: 204 No Content

Note: This revokes the OAuth tokens and removes the connection. Scheduled posts will fail.


Refresh Token

Manually refreshes the access token.

POST /social/connections/:id/refresh

Response: 200 OK

{
"id": "connection_123",
"tokenExpiry": "2026-06-14T10:00:00Z",
"refreshedAt": "2025-12-14T10:00:00Z"
}

Note: Tokens are automatically refreshed when they're within 7 days of expiry.


Test Connection

Verifies the connection is working.

POST /social/connections/:id/test

Response: 200 OK

{
"id": "connection_123",
"isValid": true,
"permissions": ["pages_manage_posts", "pages_read_engagement"],
"testedAt": "2025-12-14T10:00:00Z"
}

Social Posts

List Posts

GET /social/posts

Query Parameters

ParameterTypeDescription
tenantIdstringRequired
connectionIdstringFilter by connection
campaignIdstringFilter by campaign
statusstringDRAFT, SCHEDULED, PUBLISHING, PUBLISHED, FAILED
skipnumberOffset
takenumberLimit

Response: 200 OK

{
"data": [{
"id": "post_123",
"connectionId": "connection_456",
"platform": "FACEBOOK",
"accountName": "Randpark Golf Club",
"content": "Join us for the Summer Tournament!",
"mediaUrls": ["https://cdn.example.com/image.jpg"],
"hashtags": ["golf", "tournament"],
"status": "PUBLISHED",
"publishedAt": "2025-12-10T14:00:00Z",
"platformPostId": "fb_post_789",
"platformUrl": "https://facebook.com/...",
"likes": 45,
"comments": 12,
"shares": 8,
"reach": 1250
}],
"meta": { "total": 25, "skip": 0, "take": 25 }
}

Get Post

GET /social/posts/:id

Response: 200 OK


Create Post

POST /social/posts

Request Body

{
"tenantId": "tenant_123",
"connectionId": "connection_456",
"campaignId": "campaign_789",
"content": "Join us for the Summer Tournament! Register now.",
"mediaUrls": ["https://cdn.example.com/tournament.jpg"],
"linkUrl": "https://club.example.com/tournaments/summer-2025",
"hashtags": ["golf", "tournament", "summer2025"]
}

Response: 201 Created

{
"id": "post_123",
"status": "DRAFT",
"createdAt": "2025-12-14T10:00:00Z"
}

Update Post

PATCH /social/posts/:id

Request Body

{
"content": "Updated post content",
"hashtags": ["golf", "updated"]
}

Response: 200 OK

Note: Only DRAFT and SCHEDULED posts can be updated.


Schedule Post

POST /social/posts/:id/schedule

Request Body

{
"scheduledAt": "2025-12-20T09:00:00Z"
}

Response: 200 OK

{
"id": "post_123",
"status": "SCHEDULED",
"scheduledAt": "2025-12-20T09:00:00Z"
}

Publish Post Immediately

POST /social/posts/:id/publish

Response: 200 OK

{
"id": "post_123",
"status": "PUBLISHED",
"publishedAt": "2025-12-14T10:00:00Z",
"platformPostId": "fb_post_789",
"platformUrl": "https://facebook.com/..."
}

Cancel Scheduled Post

POST /social/posts/:id/cancel

Response: 200 OK

{
"id": "post_123",
"status": "DRAFT",
"cancelledAt": "2025-12-14T10:00:00Z"
}

Sync Engagement Metrics

Fetches latest engagement metrics from the platform.

POST /social/posts/:id/sync-engagement

Response: 200 OK

{
"id": "post_123",
"likes": 52,
"comments": 15,
"shares": 10,
"reach": 1500,
"syncedAt": "2025-12-14T10:00:00Z"
}

Delete Post

DELETE /social/posts/:id

Response: 204 No Content

Note: Published posts can optionally be deleted from the platform as well.


Platform-Specific Notes

Facebook

  • Supports: Text, images, videos, links
  • Account type: Page (not personal profiles)
  • Required permissions: pages_manage_posts, pages_read_engagement

Instagram

  • Supports: Images, videos (reels), carousels
  • Account type: Business or Creator account
  • Required permissions: instagram_basic, instagram_content_publish
  • Limitations: No direct link posting, hashtags in content

Twitter (X)

  • Supports: Text (280 chars), images, videos, polls
  • Character limit: 280 for text
  • Required scopes: tweet.read, tweet.write, users.read

LinkedIn

  • Supports: Text, images, articles, documents
  • Account type: Company page
  • Required permissions: w_member_social, r_organization_social

Post Status Flow

DRAFT → SCHEDULED → PUBLISHING → PUBLISHED
↘ ↘ ↘ FAILED
StatusDescription
DRAFTCreated but not scheduled
SCHEDULEDScheduled for future publishing
PUBLISHINGCurrently being published
PUBLISHEDSuccessfully published
FAILEDPublishing failed (see error)