> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Kismetkanceled/geniehelper/llms.txt
> Use this file to discover all available pages before exploring further.

# Credentials API

> Server-side AES-256-GCM encryption/decryption for platform credentials

## Overview

The Credentials API provides secure, server-side encryption for sensitive creator credentials (API keys, passwords, session cookies). All encryption uses **AES-256-GCM** with keys that never leave the server.

**Key Features:**

* Server-side encryption (clients never handle encryption keys)
* Multiple credential types: platform connections, download credentials, session cookies
* Directus JWT authentication for user-facing endpoints
* Shared secret authentication for server-to-server operations

## Endpoint Categories

### 1. Platform Connections

User-facing endpoints for managing creator platform credentials (Instagram, TikTok, etc.)

### 2. Download Credentials

YouTube-DL/yt-dlp compatible credentials (passwords, Netscape cookies)

### 3. Platform Sessions

Browser extension cookie capture for HITL (Human-in-the-Loop) authentication

***

## Platform Connections

### POST /api/credentials/create-profile

Create or update a creator profile with encrypted credentials.

**Authentication:** Directus JWT (Bearer token)

<ParamField body="platform" type="string" required>
  Platform identifier (e.g., `instagram`, `tiktok`, `youtube`)
</ParamField>

<ParamField body="platform_username" type="string">
  Creator's username on the platform (optional)
</ParamField>

<ParamField body="credentials" type="object" required>
  Platform-specific credentials object (will be encrypted server-side)

  Example for Instagram:

  ```json theme={null}
  {
    "username": "creator123",
    "password": "securepass",
    "session_id": "abc123xyz"
  }
  ```
</ParamField>

**Response:**

<ResponseField name="success" type="boolean">
  Operation success status
</ResponseField>

<ResponseField name="id" type="string">
  UUID of the created/updated `platform_connections` record
</ResponseField>

<ResponseField name="updated" type="boolean">
  `true` if existing connection was updated, `false` if new record created
</ResponseField>

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:3001/api/credentials/create-profile \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "instagram",
    "platform_username": "fitcreator99",
    "credentials": {
      "username": "fitcreator99",
      "password": "MySecurePass123!",
      "session_id": "abc123sessionxyz"
    }
  }'
```

**Response:**

```json theme={null}
{
  "success": true,
  "id": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f",
  "updated": false
}
```

### POST /api/credentials/update-profile-creds

Update encrypted credentials on an existing creator profile the user owns.

**Authentication:** Directus JWT (Bearer token)

<ParamField body="creator_profile_id" type="string" required>
  UUID of the `platform_connections` record to update
</ParamField>

<ParamField body="credentials" type="object" required>
  New credentials object (replaces existing encrypted data)
</ParamField>

<ParamField body="platform_username" type="string">
  Update the platform username (optional)
</ParamField>

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:3001/api/credentials/update-profile-creds \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "creator_profile_id": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f",
    "credentials": {
      "username": "fitcreator99",
      "password": "NewSecurePass456!",
      "session_id": "newSessionXYZ789"
    }
  }'
```

**Response:**

```json theme={null}
{
  "success": true,
  "id": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f"
}
```

***

## Server-to-Server Endpoints

<Warning>
  These endpoints require the `X-RBAC-SYNC-SECRET` header. Never call from client code.
</Warning>

### POST /api/credentials/store

Encrypt and save credentials to Directus `platform_connections` table.

**Authentication:** `X-RBAC-SYNC-SECRET` header

<ParamField body="creatorProfileId" type="string" required>
  UUID of the `platform_connections` record
</ParamField>

<ParamField body="credentials" type="object" required>
  Credentials object to encrypt and store
</ParamField>

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:3001/api/credentials/store \
  -H "X-RBAC-SYNC-SECRET: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "creatorProfileId": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f",
    "credentials": {
      "api_key": "sk-proj-abc123xyz",
      "refresh_token": "refresh_token_value"
    }
  }'
```

**Response:**

```json theme={null}
{
  "success": true,
  "creatorProfileId": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f",
  "updated": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f"
}
```

### POST /api/credentials/reveal

Decrypt and return credentials for a creator profile.

**Authentication:** `X-RBAC-SYNC-SECRET` header

<ParamField body="creatorProfileId" type="string" required>
  UUID of the `platform_connections` record
</ParamField>

<ResponseField name="success" type="boolean">
  Operation success status
</ResponseField>

<ResponseField name="creatorProfileId" type="string">
  UUID of the profile
</ResponseField>

<ResponseField name="credentials" type="object">
  Decrypted credentials object
</ResponseField>

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:3001/api/credentials/reveal \
  -H "X-RBAC-SYNC-SECRET: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "creatorProfileId": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f"
  }'
```

**Response:**

```json theme={null}
{
  "success": true,
  "creatorProfileId": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f",
  "credentials": {
    "api_key": "sk-proj-abc123xyz",
    "refresh_token": "refresh_token_value"
  }
}
```

***

## Download Credentials (yt-dlp)

### POST /api/credentials/create-download-cred

Create credentials for yt-dlp/youtube-dl authentication (password or cookies).

**Authentication:** Directus JWT (Bearer token)

<ParamField body="platform" type="string" required>
  Platform identifier (e.g., `youtube`, `instagram`)
</ParamField>

<ParamField body="creator_profile_id" type="string" required>
  UUID of the associated `platform_connections` record
</ParamField>

<ParamField body="auth_type" type="string" required>
  Either `password` or `cookies`
</ParamField>

<ParamField body="username" type="string">
  Platform username (optional for cookies auth)
</ParamField>

<ParamField body="credentials" type="object" required>
  For `password` auth:

  ```json theme={null}
  { "password": "mypassword" }
  ```

  For `cookies` auth:

  ```json theme={null}
  { "cookies_netscape": "# Netscape HTTP Cookie File\n.youtube.com\tTRUE\t/\t..." }
  ```
</ParamField>

<ParamField body="display_name" type="string">
  Human-readable name for this credential set (optional)
</ParamField>

**Example Request (Password Auth):**

```bash theme={null}
curl -X POST http://localhost:3001/api/credentials/create-download-cred \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "youtube",
    "creator_profile_id": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f",
    "auth_type": "password",
    "username": "mychannel@gmail.com",
    "credentials": {
      "password": "MyYouTubePassword123"
    },
    "display_name": "My YouTube Channel"
  }'
```

**Response:**

```json theme={null}
{
  "success": true,
  "id": "a1b2c3d4-5e6f-7g8h-9i0j-k1l2m3n4o5p6"
}
```

### POST /api/credentials/reveal-download-cred

Decrypt download credentials (server-to-server only).

**Authentication:** `X-RBAC-SYNC-SECRET` header

<ParamField body="id" type="string" required>
  UUID of the `download_credentials` record
</ParamField>

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:3001/api/credentials/reveal-download-cred \
  -H "X-RBAC-SYNC-SECRET: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{"id": "a1b2c3d4-5e6f-7g8h-9i0j-k1l2m3n4o5p6"}'
```

**Response:**

```json theme={null}
{
  "success": true,
  "id": "a1b2c3d4-5e6f-7g8h-9i0j-k1l2m3n4o5p6",
  "platform": "youtube",
  "auth_type": "password",
  "credentials": {
    "password": "MyYouTubePassword123"
  }
}
```

***

## Platform Sessions (Cookie Capture)

### POST /api/credentials/store-platform-session

Store browser cookies captured via extension (HITL authentication).

**Authentication:** Directus JWT (Bearer token)

<ParamField body="creator_profile_id" type="string" required>
  UUID of the `platform_connections` record
</ParamField>

<ParamField body="platform" type="string" required>
  Platform identifier (e.g., `instagram`, `tiktok`)
</ParamField>

<ParamField body="cookies" type="array" required>
  Array of browser cookie objects:

  ```json theme={null}
  [
    {
      "name": "sessionid",
      "value": "abc123xyz",
      "domain": ".instagram.com",
      "path": "/",
      "expires": 1735689600,
      "httpOnly": true,
      "secure": true
    }
  ]
  ```
</ParamField>

<ParamField body="user_agent" type="string">
  Browser user agent string (optional)
</ParamField>

<ParamField body="expires_at" type="string">
  ISO 8601 expiry timestamp (optional)
</ParamField>

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:3001/api/credentials/store-platform-session \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "creator_profile_id": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f",
    "platform": "instagram",
    "cookies": [
      {
        "name": "sessionid",
        "value": "123456789%3AabcXYZ%3A28",
        "domain": ".instagram.com",
        "path": "/",
        "expires": 1735689600,
        "httpOnly": true,
        "secure": true
      }
    ],
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
  }'
```

**Response:**

```json theme={null}
{
  "success": true,
  "id": "session-uuid-123",
  "platform": "instagram",
  "cookie_count": 1
}
```

### POST /api/credentials/get-platform-session

Retrieve decrypted session cookies (server-to-server only).

**Authentication:** `X-RBAC-SYNC-SECRET` header

<ParamField body="creator_profile_id" type="string" required>
  UUID of the `platform_connections` record
</ParamField>

<ParamField body="platform" type="string" required>
  Platform identifier
</ParamField>

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:3001/api/credentials/get-platform-session \
  -H "X-RBAC-SYNC-SECRET: your-secret-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "creator_profile_id": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f",
    "platform": "instagram"
  }'
```

**Response:**

```json theme={null}
{
  "success": true,
  "id": "session-uuid-123",
  "platform": "instagram",
  "cookies": [
    {
      "name": "sessionid",
      "value": "123456789%3AabcXYZ%3A28",
      "domain": ".instagram.com",
      "path": "/",
      "expires": 1735689600,
      "httpOnly": true,
      "secure": true
    }
  ],
  "captured_at": "2026-01-15T10:30:00.000Z",
  "expires_at": "2026-12-31T23:59:59.000Z",
  "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
```

### POST /api/credentials/revoke-platform-session

Mark a platform session as revoked (disables cookie usage).

**Authentication:** Directus JWT (Bearer token)

<ParamField body="id" type="string" required>
  UUID of the `platform_sessions` record
</ParamField>

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:3001/api/credentials/revoke-platform-session \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{"id": "session-uuid-123"}'
```

**Response:**

```json theme={null}
{
  "success": true,
  "id": "session-uuid-123"
}
```

***

## Encryption Details

All credential encryption uses the `encryptJSON()` and `decryptJSON()` utilities (`server/utils/credentialsCrypto.js`):

* **Algorithm:** AES-256-GCM
* **Key derivation:** Server-side environment variable (never exposed)
* **IV:** Randomly generated per encryption operation
* **Output format:** Base64-encoded `iv:authTag:ciphertext`

**Security guarantees:**

* Encryption keys never leave the server
* Clients never handle plaintext encryption keys
* Each credential has unique IV (no key reuse)
* Authentication tags prevent tampering

## Error Handling

Common error responses:

**Missing credentials:**

```json theme={null}
{
  "success": false,
  "error": "No encrypted_credentials found"
}
```

**Unauthorized (invalid secret):**

```json theme={null}
{
  "success": false,
  "error": "Unauthorized"
}
```

**Forbidden (not profile owner):**

```json theme={null}
{
  "success": false,
  "error": "Forbidden"
}
```

**Directus error (upstream):**

```json theme={null}
{
  "success": false,
  "error": "Directus 400 /items/platform_connections/invalid-uuid: {\"errors\":[{\"message\":\"Invalid UUID\"}]}"
}
```
