Skip to main content

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)
platform
string
required
Platform identifier (e.g., instagram, tiktok, youtube)
platform_username
string
Creator’s username on the platform (optional)
credentials
object
required
Platform-specific credentials object (will be encrypted server-side)Example for Instagram:
{
  "username": "creator123",
  "password": "securepass",
  "session_id": "abc123xyz"
}
Response:
success
boolean
Operation success status
id
string
UUID of the created/updated platform_connections record
updated
boolean
true if existing connection was updated, false if new record created
Example Request:
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:
{
  "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)
creator_profile_id
string
required
UUID of the platform_connections record to update
credentials
object
required
New credentials object (replaces existing encrypted data)
platform_username
string
Update the platform username (optional)
Example Request:
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:
{
  "success": true,
  "id": "d3f21c8e-4a5b-4c9d-8e7f-1a2b3c4d5e6f"
}

Server-to-Server Endpoints

These endpoints require the X-RBAC-SYNC-SECRET header. Never call from client code.

POST /api/credentials/store

Encrypt and save credentials to Directus platform_connections table. Authentication: X-RBAC-SYNC-SECRET header
creatorProfileId
string
required
UUID of the platform_connections record
credentials
object
required
Credentials object to encrypt and store
Example Request:
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:
{
  "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
creatorProfileId
string
required
UUID of the platform_connections record
success
boolean
Operation success status
creatorProfileId
string
UUID of the profile
credentials
object
Decrypted credentials object
Example Request:
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:
{
  "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)
platform
string
required
Platform identifier (e.g., youtube, instagram)
creator_profile_id
string
required
UUID of the associated platform_connections record
auth_type
string
required
Either password or cookies
username
string
Platform username (optional for cookies auth)
credentials
object
required
For password auth:
{ "password": "mypassword" }
For cookies auth:
{ "cookies_netscape": "# Netscape HTTP Cookie File\n.youtube.com\tTRUE\t/\t..." }
display_name
string
Human-readable name for this credential set (optional)
Example Request (Password Auth):
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": "[email protected]",
    "credentials": {
      "password": "MyYouTubePassword123"
    },
    "display_name": "My YouTube Channel"
  }'
Response:
{
  "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
id
string
required
UUID of the download_credentials record
Example Request:
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:
{
  "success": true,
  "id": "a1b2c3d4-5e6f-7g8h-9i0j-k1l2m3n4o5p6",
  "platform": "youtube",
  "auth_type": "password",
  "credentials": {
    "password": "MyYouTubePassword123"
  }
}

POST /api/credentials/store-platform-session

Store browser cookies captured via extension (HITL authentication). Authentication: Directus JWT (Bearer token)
creator_profile_id
string
required
UUID of the platform_connections record
platform
string
required
Platform identifier (e.g., instagram, tiktok)
cookies
array
required
Array of browser cookie objects:
[
  {
    "name": "sessionid",
    "value": "abc123xyz",
    "domain": ".instagram.com",
    "path": "/",
    "expires": 1735689600,
    "httpOnly": true,
    "secure": true
  }
]
user_agent
string
Browser user agent string (optional)
expires_at
string
ISO 8601 expiry timestamp (optional)
Example Request:
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:
{
  "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
creator_profile_id
string
required
UUID of the platform_connections record
platform
string
required
Platform identifier
Example Request:
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:
{
  "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)
id
string
required
UUID of the platform_sessions record
Example Request:
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:
{
  "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:
{
  "success": false,
  "error": "No encrypted_credentials found"
}
Unauthorized (invalid secret):
{
  "success": false,
  "error": "Unauthorized"
}
Forbidden (not profile owner):
{
  "success": false,
  "error": "Forbidden"
}
Directus error (upstream):
{
  "success": false,
  "error": "Directus 400 /items/platform_connections/invalid-uuid: {\"errors\":[{\"message\":\"Invalid UUID\"}]}"
}

Build docs developers (and LLMs) love