PostPost

Test Connection

Validate that a platform connection is working before scheduling posts.

Endpoint

POST https://api.postpost.dev/api/v1/test-connection/:platformId

Headers

HeaderRequiredDescription
x-api-keyYesYour API key
x-postpost-user-idNoManaged user ID (workspace only)
x-postpost-clientNoClient identifier (e.g., mcp). Used for MCP access gating.

Path Parameters

ParameterTypeDescription
platformIdstringThe platform ID (e.g., linkedin-Tz9W5i6ZYG)

Response

Successful Connection

{
  "platform": "linkedin",
  "platformId": "linkedin-Tz9W5i6ZYG",
  "username": "John Doe",
  "status": "ok",
  "message": "Connected as John Doe",
  "permissions": ["w_member_social", "w_member_social_feed", "r_basicprofile", "r_member_postAnalytics", "r_member_profileAnalytics"],
  "tokenExpiresIn": "45d 3h",
  "lastSuccessfulPost": "2026-02-22T09:15:00.000Z",
  "lastError": null
}

Failed Connection

{
  "platform": "threads",
  "platformId": "threads-17841412345678",
  "username": "yourthreads",
  "status": "error",
  "message": "Error validating access token: Session has expired",
  "permissions": [],
  "tokenExpiresIn": "expired",
  "lastSuccessfulPost": "2026-02-15T14:30:00.000Z",
  "lastError": {
    "message": "Session has expired",
    "occurredAt": "2026-02-22T10:00:00.000Z"
  }
}

Important: All validation results — both success and failure — return HTTP 200. The connection test outcome is indicated by the status field ("ok" or "error"), not the HTTP status code. Only infrastructure errors (404 connection not found, 500 server error) use non-200 status codes.

Response Fields

FieldTypeDescription
platformstringPlatform name (twitter, linkedin, threads, etc.)
platformIdstringFull platform ID
usernamestringConnected account username
statusstringok or error
messagestringHuman-readable status message
permissionsarrayList of granted permissions/scopes
tokenExpiresInstring/nullTime until token expiry. Possible values: "7d 3h" (days and hours), "5h" (hours only, when less than one day remains), "< 1h" (less than one hour remaining), "expired" (token already expired), or null (no expiration).
lastSuccessfulPoststring/nullTimestamp of last successful post
lastErrorobject/nullLast error details if any. When present, contains: message (string — error description) and occurredAt (string — ISO 8601 timestamp of when the error occurred).

Examples

JavaScript (fetch)

const platformId = 'linkedin-Tz9W5i6ZYG';
const response = await fetch(
  `https://api.postpost.dev/api/v1/test-connection/${platformId}`,
  {
    method: 'POST',
    headers: { 'x-api-key': 'YOUR_API_KEY' }
  }
);
const result = await response.json();

if (result.status === 'ok') {
  console.log(`✅ ${result.message}`);
  console.log(`Token expires in: ${result.tokenExpiresIn}`);
} else {
  console.log(`❌ Connection failed: ${result.message}`);
}

Python (requests)

import requests

platform_id = 'linkedin-Tz9W5i6ZYG'
response = requests.post(
    f'https://api.postpost.dev/api/v1/test-connection/{platform_id}',
    headers={'x-api-key': 'YOUR_API_KEY'}
)
result = response.json()

if result['status'] == 'ok':
    print(f"✅ {result['message']}")
    print(f"Permissions: {', '.join(result['permissions'])}")
else:
    print(f"❌ {result['message']}")

cURL

curl -X POST https://api.postpost.dev/api/v1/test-connection/linkedin-Tz9W5i6ZYG \
  -H "x-api-key: YOUR_API_KEY"

Pre-flight Check Before Scheduling

async function validateConnectionsBeforePost(platformIds) {
  const results = await Promise.all(
    platformIds.map(async (platformId) => {
      const response = await fetch(
        `https://api.postpost.dev/api/v1/test-connection/${platformId}`,
        {
          method: 'POST',
          headers: { 'x-api-key': process.env.PUBLORA_API_KEY }
        }
      );
      return response.json();
    })
  );

  const failed = results.filter(r => r.status === 'error');
  if (failed.length > 0) {
    console.log('⚠️  Some connections need attention:');
    failed.forEach(r => console.log(`  - ${r.platformId}: ${r.message}`));
    return false;
  }

  console.log('✅ All connections healthy');
  return true;
}

// Usage
const platforms = ['twitter-123', 'linkedin-ABC', 'threads-456'];
const healthy = await validateConnectionsBeforePost(platforms);
if (healthy) {
  // Proceed with scheduling
}

Telegram MTProto Connections

Note: Telegram MTProto connections will always fail the test-connection check because the validator only checks connectionType === "bot" connections. MTProto connections fall through to the default failure case, returning a misleading "Invalid bot token" error.

Unknown Platform

If the platform has no test-connection validator implemented (e.g., Pinterest), the endpoint returns HTTP 200 with a full response structure but error status:

{
  "platform": "pinterest",
  "platformId": "pinterest-abc123",
  "username": "unknown",
  "status": "error",
  "message": "Unknown platform: pinterest",
  "permissions": [],
  "tokenExpiresIn": null,
  "lastSuccessfulPost": null,
  "lastError": null
}

Note: The public API route returns only { error: "Failed to test connection" } for 500 errors without a message field. The internal dashboard endpoint may include an additional message field in error responses.

Errors

StatusErrorCause
400"Invalid platformId format"platformId doesn't contain a dash or is malformed. Note: This endpoint uses a simple dash-split validation (not the stricter PLATFORM_ID_REGEX used by the create-post endpoint), so it may accept platform IDs with uppercase platform prefixes that create-post would reject.
400"Invalid x-postpost-user-id"x-postpost-user-id header contains an invalid ObjectId
401"API key is required"Missing x-api-key header
401"Invalid API key"x-api-key value is not a valid key
401"Invalid API key owner"The API key's owner account could not be found
403"API access is not enabled for this account"Account does not have API access enabled
403"MCP access is not enabled for this account"MCP access is not enabled when x-postpost-client: mcp is sent
403"Workspace access is not enabled for this key"API key does not have workspace permissions
403"User is not managed by key"The x-postpost-user-id user is not managed by this API key
500"Internal server error"Unexpected error in middleware
404"Connection not found"Invalid platformId or connection doesn't exist
500"Failed to test connection"Server error during validation

On this page