> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.swellsystem.com/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Client Portal API

# Client Portal API

## Overview

The Client Portal API allows you to programmatically manage portal invitations, retrieve portal configuration, and generate portal access tokens.

## Base URL

All endpoints are under `/api/v1/client-portal/`

## Authentication

All endpoints require authentication using a Bearer token:

```
Authorization: Bearer your-api-token-here
```

## Endpoints

### Get Portal Configuration

Get the current portal configuration for the authenticated tenant.

**Endpoint:** `GET /api/v1/client-portal/config`

**Response:**
```json
{
  "data": {
    "portal_name": "Client Portal",
    "portal_logo": "portal-logos/logo.png",
    "primary_color": "#3B82F6",
    "secondary_color": "#1E40AF",
    "welcome_message": "Welcome to your client portal!",
    "enabled_modules": ["invoices", "proposals", "tasks"],
    "is_active": true,
    "allow_file_sharing": true,
    "show_activity_feed": true,
    "token_expiration_days": 30
  }
}
```

**Example:**
```bash
curl -H "Authorization: Bearer your-token" \
     https://your-domain.com/api/v1/client-portal/config
```

---

### Send Portal Invitation to Contact

Send a portal access invitation email to a contact.

**Endpoint:** `POST /api/v1/client-portal/contacts/{contactId}/invite`

**URL Parameters:**
- `contactId` (required) - The ID of the contact

**Request Body:**
```json
{
  "custom_message": "Welcome to your client portal! Click the link below to access your invoices, proposals, and more."
}
```

**Response:**
```json
{
  "message": "Portal invitation sent successfully",
  "token": "portal-access-token-here"
}
```

**Example:**
```bash
curl -X POST \
     -H "Authorization: Bearer your-token" \
     -H "Content-Type: application/json" \
     -d '{"custom_message": "Welcome!"}' \
     https://your-domain.com/api/v1/client-portal/contacts/1/invite
```

**Error Responses:**
- `400 Bad Request` - Contact doesn't have an email address
- `404 Not Found` - Contact not found
- `500 Internal Server Error` - Failed to send invitation

---

### Send Portal Invitation to Company

Send a portal access invitation email to a company.

**Endpoint:** `POST /api/v1/client-portal/companies/{companyId}/invite`

**URL Parameters:**
- `companyId` (required) - The ID of the company

**Request Body:**
```json
{
  "custom_message": "Welcome to your company portal!"
}
```

**Response:**
```json
{
  "message": "Portal invitation sent successfully",
  "token": "portal-access-token-here"
}
```

**Example:**
```bash
curl -X POST \
     -H "Authorization: Bearer your-token" \
     -H "Content-Type: application/json" \
     -d '{"custom_message": "Welcome!"}' \
     https://your-domain.com/api/v1/client-portal/companies/1/invite
```

---

### Get Portal Token

Get or create a portal access token for a contact or company.

**Endpoint:** `POST /api/v1/client-portal/token`

**Request Body:**
```json
{
  "type": "contact",
  "id": 1
}
```

**Parameters:**
- `type` (required) - Either `"contact"` or `"company"`
- `id` (required) - The ID of the contact or company

**Response:**
```json
{
  "token": "portal-access-token-here",
  "url": "https://your-domain.com/client-portal/token-here",
  "expires_at": "2026-02-19T00:00:00Z"
}
```

**Example:**
```bash
curl -X POST \
     -H "Authorization: Bearer your-token" \
     -H "Content-Type: application/json" \
     -d '{"type": "contact", "id": 1}' \
     https://your-domain.com/api/v1/client-portal/token
```

**Use Case:**
Use this endpoint to generate portal access tokens programmatically. You can then:
- Embed the portal URL in your own application
- Create custom invitation flows
- Build integrations that require portal access

---

## Error Responses

All endpoints return standard error responses:

**400 Bad Request:**
```json
{
  "message": "Contact does not have an email address"
}
```

**404 Not Found:**
```json
{
  "message": "Contact not found"
}
```

**500 Internal Server Error:**
```json
{
  "message": "Failed to send portal invitation: Error details"
}
```

---

## Rate Limiting

API requests are rate limited to **60 requests per minute** per token. If you exceed this limit, you'll receive a `429 Too Many Requests` response.

---

## Webhooks

Portal-related webhook events:

- `client_portal.invitation_sent` - Fired when a portal invitation is sent
- `client_portal.token_created` - Fired when a new portal token is created
- `client_portal.token_accessed` - Fired when a portal token is accessed

See [Webhooks Documentation](../webhooks.md) for more information.

---

## Examples

### Send Invitation and Get Token

```javascript
// Send invitation
const response = await fetch('/api/v1/client-portal/contacts/1/invite', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer your-token',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    custom_message: 'Welcome to your portal!'
  })
});

const data = await response.json();
console.log('Portal token:', data.token);
console.log('Portal URL:', `https://your-domain.com/client-portal/${data.token}`);
```

### Get Portal Configuration

```javascript
const response = await fetch('/api/v1/client-portal/config', {
  headers: {
    'Authorization': 'Bearer your-token'
  }
});

const { data } = await response.json();
console.log('Portal name:', data.portal_name);
console.log('Enabled modules:', data.enabled_modules);
```

---

## Best Practices

1. **Store Tokens Securely**: If you store portal tokens, encrypt them
2. **Monitor Token Expiration**: Check `expires_at` and send new invitations before expiration
3. **Handle Errors Gracefully**: Always check response status and handle errors appropriately
4. **Respect Rate Limits**: Implement retry logic with exponential backoff
5. **Use Custom Messages**: Personalize invitation messages when possible

---

## Next Steps

- See [Client Portal Overview](https://help.swellsystem.com/en/article/client-portal-overview-e4781w/)
- Review [Webhooks Documentation](../webhooks.md)
- Check [Authentication Guide](../authentication.md)
