# Connecting X and LinkedIn

This guide explains how to connect X (Twitter) and LinkedIn to MarkOps. Connections are tenant-specific and can be managed from **Settings → OAuth Connections** by a Supervisor.

## X (Twitter)

### 1. Create and configure the X application

1. Open the [X Developer Portal](https://developer.x.com/).
2. Create or select a Project and App.
3. In **User authentication settings**, enable **OAuth 2.0**.
4. Set the app permission to **Read and write**.
5. Add this callback URL exactly (replace `your-domain.com`):

   ```text
   https://your-domain.com/auth/social/x/callback
   ```

6. Copy the OAuth 2.0 **Client ID** and, when the app is configured as a confidential client, its **Client Secret**.

### 2. Configure MarkOps

Either add the values in **Settings → Developer Credentials** or configure the environment:

```dotenv
X_CLIENT_ID=your_x_client_id
X_CLIENT_SECRET=your_x_client_secret
X_REDIRECT_URI="${APP_URL}/auth/social/x/callback"
```

Save the settings, then select **Connect X (Twitter)**. Approve access on X and return to MarkOps.

### What X supports in MarkOps

- Secure OAuth 2.0 Authorization Code flow with PKCE.
- Encrypted access and refresh-token storage per tenant.
- Publishing a text post from the content calendar.
- Including X when publishing to **All platforms**.
- X in the content platform selector, design rules, creative records, campaign dashboard, and reporting filters.

### X publishing notes

- The current publishing route creates a text post through `POST /2/tweets`.
- Posts are limited to **280 characters** by the application before they are sent.
- Image/video upload and paid X Ads campaign creation require the relevant X API/Ads API products and approvals; they are not enabled merely by connecting a standard OAuth application.

## LinkedIn

### LinkedIn platform requirements

For a production connection, create an application in the [LinkedIn Developer Portal](https://www.linkedin.com/developers/), request the products your organization needs, and configure:

- **Sign In with LinkedIn using OpenID Connect** for identity.
- **Share on LinkedIn** for publishing posts.
- **Marketing Developer Platform** access for organization pages, advertising accounts, reporting, and campaign management.
- A redirect URI such as:

  ```text
  https://your-domain.com/auth/social/linkedin/callback
  ```

The exact permissions and approval requirements depend on whether the connection posts as a member, posts as an organization, or accesses LinkedIn Ads data.

### Current MarkOps status

The existing **Connect LinkedIn Ads** action is a demo/sandbox connection. It creates a sample account and sample data; it is **not** a production LinkedIn OAuth flow. Do not use it with real advertising credentials or expect it to import live LinkedIn Ads performance.

MarkOps does contain a LinkedIn publishing branch that uses the versioned REST posts endpoint. To make it live, replace the demo connector with a real OAuth callback that stores the authenticated member/organization URN, encrypted token, refresh token, expiry, and granted scopes in `social_accounts`.

### Production implementation checklist

1. Add `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET`, and `LINKEDIN_REDIRECT_URI` to the environment/service configuration.
2. Add `/auth/social/linkedin` and `/auth/social/linkedin/callback` routes.
3. Implement OAuth state validation and authorization-code exchange.
4. Request and record only the LinkedIn permissions approved for the application.
5. Store the author URN in `platform_id`; this is used when publishing to `https://api.linkedin.com/rest/posts`.
6. Use a current `LINKEDIN_API_VERSION` and send it with every REST request.
7. Add Ads API synchronization only after Marketing Developer Platform access is approved.

## Security checklist

- Register the callback URLs exactly, using HTTPS in production.
- Never commit client secrets or access tokens.
- Restrict connection/disconnection to Supervisor users.
- Revoke a platform connection from MarkOps when a staff member leaves or access should end.
