# ConnectSafely.ai API Documentation

## Overview

ConnectSafely.ai provides a comprehensive REST API for LinkedIn automation, lead generation, and social media management. Access all platform features programmatically.

**Base URL:** `https://connectsafely.ai/api`

**API Version:** v1

## Authentication

All API requests require authentication using an API key.

### Getting Your API Key

1. Log in to your ConnectSafely.ai dashboard
2. Navigate to Settings → API Keys
3. Click "Generate New API Key"
4. Copy and securely store your API key

### Authentication Header

```http
Authorization: Bearer YOUR_API_KEY_HERE
Content-Type: application/json
```

### Example Request

```bash
curl -X GET https://connectsafely.ai/api/linkedin/profile \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
```

## Rate Limits

- **Standard Plan:** 1,000 requests per hour
- **Enterprise Plan:** 10,000 requests per hour

Rate limit headers included in every response:
- `X-RateLimit-Limit`: Maximum requests per hour
- `X-RateLimit-Remaining`: Remaining requests
- `X-RateLimit-Reset`: Unix timestamp when limit resets

## API Endpoints

### LinkedIn Actions

Perform LinkedIn actions like following, connecting, and messaging.

**Base Path:** `/docs/api/linkedin-actions`

#### Check Relationship

```http
GET /linkedin/relationship/:profileId
```

Check relationship status with a specific LinkedIn profile.

**Parameters:**
- `profileId` (required): LinkedIn profile ID

**Response:**
```json
{
  "connected": true,
  "following": false,
  "follower": true,
  "connectionDegree": 1
}
```

#### Send Connection Request

```http
POST /linkedin/connect
```

Send a connection request to a LinkedIn profile.

**Request Body:**
```json
{
  "profileId": "string",
  "message": "string (optional, max 300 characters)"
}
```

**Response:**
```json
{
  "success": true,
  "invitationId": "string",
  "timestamp": "2025-12-02T10:30:00Z"
}
```

#### Follow User

```http
POST /linkedin/follow
```

Follow a LinkedIn user or company page.

**Request Body:**
```json
{
  "profileId": "string",
  "profileType": "user|company"
}
```

#### Send Message

```http
POST /linkedin/message
```

Send a direct message to a LinkedIn connection.

**Request Body:**
```json
{
  "conversationId": "string",
  "message": "string",
  "withTypingIndicator": boolean
}
```

### LinkedIn Profiles

Fetch detailed profile information including experience, education, and contact data.

**Base Path:** `/docs/api/linkedin-profiles`

#### Fetch Profile

```http
POST /linkedin/profile
```

Retrieve complete LinkedIn profile data.

**Request Body:**
```json
{
  "profileUrl": "https://www.linkedin.com/in/username",
  "includeExperience": true,
  "includeEducation": true,
  "includeContact": true
}
```

**Response:**
```json
{
  "profileId": "string",
  "fullName": "string",
  "headline": "string",
  "location": "string",
  "industry": "string",
  "experience": [...],
  "education": [...],
  "skills": [...],
  "contactInfo": {
    "email": "string",
    "phone": "string"
  }
}
```

### LinkedIn Posts

Post engagement, commenting, reactions, and search functionality.

**Base Path:** `/docs/api/linkedin-posts`

#### Comment on Post

```http
POST /linkedin/posts/comment
```

Add a comment to a LinkedIn post.

**Request Body:**
```json
{
  "postUrn": "string",
  "commentText": "string",
  "replyToCommentId": "string (optional)"
}
```

#### Get Post Comments

```http
POST /linkedin/posts/comments
```

Retrieve all comments on a specific post.

**Request Body:**
```json
{
  "postUrn": "string",
  "limit": 50,
  "offset": 0
}
```

#### Like a Comment

```http
POST /linkedin/like-comment
```

Like an existing comment on a LinkedIn post.

**Request Body:**
```json
{
  "commentId": "7441783492948054016",
  "postUrl": "https://www.linkedin.com/feed/update/urn:li:activity:7441028442856251392",
  "companyUrn": "string (optional)"
}
```

#### React to Post

```http
POST /linkedin/posts/react
```

React to a LinkedIn post.

**Request Body:**
```json
{
  "postUrn": "string",
  "reactionType": "LIKE|PRAISE|APPRECIATION|EMPATHY|INTEREST|ENTERTAINMENT"
}
```

#### Search Posts

```http
POST /linkedin/posts/search
```

Search LinkedIn posts by keyword.

**Request Body:**
```json
{
  "keywords": ["string"],
  "authorRoles": ["CEO", "CTO", "VP"],
  "dateRange": "PAST_24H|PAST_WEEK|PAST_MONTH",
  "limit": 50
}
```

#### Scrape Post

```http
POST /linkedin/posts/scrape
```

Extract full post content including text, media, and engagement metrics.

**Request Body:**
```json
{
  "postUrl": "string"
}
```

**Response:**
```json
{
  "postUrn": "string",
  "author": {...},
  "text": "string",
  "mediaUrls": [...],
  "reactions": {
    "like": 120,
    "praise": 45,
    "total": 165
  },
  "comments": 32,
  "shares": 18,
  "timestamp": "2025-12-01T15:30:00Z"
}
```

### LinkedIn Messaging

Advanced messaging with typing indicators and delivery acknowledgments.

**Base Path:** `/api/linkedin-messaging`

#### Get Recent Messages

```http
GET /linkedin/messaging/recent
```

Retrieve recent conversations and messages.

**Query Parameters:**
- `limit`: Number of conversations (default: 20)
- `unreadOnly`: Filter for unread messages (boolean)

#### Send Message with Typing Indicator

```http
POST /linkedin/messaging/send-with-typing
```

Send message with realistic typing indicator before delivery.

**Request Body:**
```json
{
  "conversationId": "string",
  "message": "string",
  "typingDuration": 3000
}
```

#### Get Conversation Details

```http
GET /linkedin/messaging/conversation/:conversationId
```

Retrieve full conversation thread with participant details.

### LinkedIn Groups

Access and manage LinkedIn group data.

**Base Path:** `/api/linkedin-groups`

#### Get Group Members

```http
POST /linkedin/groups/members
```

Retrieve members of a LinkedIn group.

**Request Body:**
```json
{
  "groupId": "string",
  "limit": 100,
  "offset": 0,
  "filters": {
    "role": ["Member", "Manager", "Owner"],
    "joinedAfter": "2025-01-01"
  }
}
```

#### Get Group Members by URL

```http
POST /linkedin/groups/members-by-url
```

Extract group members using group URL.

**Request Body:**
```json
{
  "groupUrl": "https://www.linkedin.com/groups/12345678"
}
```

### LinkedIn Organizations

Organization data and insights.

**Base Path:** `/api/linkedin-organizations`

#### Get Organizations

```http
GET /linkedin/organizations
```

Search and retrieve organization data.

**Query Parameters:**
- `name`: Company name
- `industry`: Industry filter
- `size`: Company size range
- `location`: Geographic location

**Response:**
```json
{
  "organizations": [
    {
      "id": "string",
      "name": "string",
      "industry": "string",
      "size": "11-50",
      "location": "San Francisco, CA",
      "websiteUrl": "string",
      "followerCount": 5000
    }
  ],
  "total": 100
}
```

## Webhooks

Receive real-time notifications for LinkedIn events.

### Available Webhooks

- `connection.accepted` - Connection request accepted
- `message.received` - New message received
- `post.commented` - Your post received a comment
- `profile.viewed` - Someone viewed your profile
- `lead.captured` - New inbound lead identified

### Webhook Configuration

1. Navigate to Settings → Webhooks
2. Add webhook endpoint URL
3. Select events to subscribe to
4. Save and verify endpoint

### Webhook Payload Example

```json
{
  "event": "connection.accepted",
  "timestamp": "2025-12-02T10:30:00Z",
  "data": {
    "profileId": "string",
    "fullName": "John Doe",
    "headline": "CEO at TechCorp",
    "connectionDate": "2025-12-02T10:30:00Z"
  }
}
```

### Webhook Security

All webhook requests include signature header for verification:

```http
X-ConnectSafely-Signature: sha256=<computed_signature>
```

Verify signature using your webhook secret:

```javascript
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  const computed = hmac.update(payload).digest('hex');
  return `sha256=${computed}` === signature;
}
```

## Error Codes

Standard HTTP status codes with detailed error messages.

| Code | Meaning | Common Causes |
|------|---------|---------------|
| 200 | Success | Request completed successfully |
| 400 | Bad Request | Invalid parameters or missing required fields |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource doesn't exist |
| 429 | Rate Limited | Exceeded rate limit |
| 500 | Server Error | Internal server error |

### Error Response Format

```json
{
  "error": {
    "code": "INVALID_PARAMETER",
    "message": "Profile ID is required",
    "details": {
      "field": "profileId",
      "reason": "missing_required_field"
    }
  }
}
```

## Best Practices

### 1. Rate Limit Management

Implement exponential backoff for rate limit errors:

```javascript
async function apiRequestWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After') || 60;
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    return response;
  }
}
```

### 2. Pagination

For endpoints returning lists, use pagination parameters:

```javascript
let allResults = [];
let offset = 0;
const limit = 100;

do {
  const response = await fetch(`/api/endpoint?limit=${limit}&offset=${offset}`);
  const data = await response.json();
  allResults = allResults.concat(data.results);
  offset += limit;
} while (data.hasMore);
```

### 3. Webhook Reliability

Implement retry logic for webhook delivery failures:

- Exponential backoff: 1s, 2s, 4s, 8s, 16s
- Maximum 5 retry attempts
- Log failed webhooks for manual review

### 4. Security

- Never expose API keys in client-side code
- Rotate API keys every 90 days
- Use environment variables for key storage
- Implement IP whitelisting when possible

## SDKs & Libraries

### Official SDKs

**Node.js / TypeScript**
```bash
npm install @connectsafely/sdk
```

```typescript
import { ConnectSafely } from '@connectsafely/sdk';

const client = new ConnectSafely({
  apiKey: process.env.CONNECTSAFELY_API_KEY
});

const profile = await client.profiles.fetch({
  profileUrl: 'https://linkedin.com/in/username'
});
```

**Python**
```bash
pip install connectsafely-python
```

```python
from connectsafely import ConnectSafely

client = ConnectSafely(api_key=os.environ['CONNECTSAFELY_API_KEY'])

profile = client.profiles.fetch(
    profile_url='https://linkedin.com/in/username'
)
```

### Community Libraries

- **Go:** github.com/connectsafely/go-client
- **Ruby:** gem install connectsafely
- **PHP:** composer require connectsafely/php-sdk

## Support & Resources

### Documentation
- **API Reference:** https://connectsafely.ai/docs/api
- **Integration Guides:** https://connectsafely.ai/integrations
- **Changelog:** https://connectsafely.ai/changelog

### Support Channels
- **24/7 API Support:** api-support@connectsafely.ai
- **Developer Discord:** https://discord.gg/connectsafely
- **GitHub Issues:** https://github.com/connectsafely/api-issues

### API Status
Monitor API uptime and performance:
- **Status Page:** https://status.connectsafely.ai
- **Incident History:** Real-time notifications
- **Scheduled Maintenance:** Advance notice via email

---

**Ready to integrate?**

Get your API key at https://connectsafely.ai/settings/api

**Need help?** Contact our API team at api-support@connectsafely.ai
