---
title: Custom Credential Service
subtitle: Integrate your own HTTP API for credential management
slug: credentials/custom-credential-service
---

Skyvern supports integrating with custom HTTP APIs for credential management, allowing you to use your existing credential infrastructure instead of third-party services.

## Overview

The custom credential service feature enables Skyvern to store and retrieve credentials from external HTTP APIs. This is perfect for organizations that:

- Have existing credential management systems
- Need to maintain credentials in their own infrastructure
- Want to integrate with proprietary credential vaults
- Require custom authentication flows

## API Contract

Your custom credential service must implement these HTTP endpoints:

### Create Credential
```http
POST {API_BASE_URL}
Authorization: Bearer {API_TOKEN}
Content-Type: application/json

{
  "name": "My Credential",
  "type": "password",
  "username": "user@example.com",
  "password": "secure_password",
  "totp": "JBSWY3DPEHPK3PXP",
  "totp_type": "authenticator"
}
```

**Response:**
```json
{
  "id": "cred_123456"
}
```

### Get Credential
```http
GET {API_BASE_URL}/{credential_id}
Authorization: Bearer {API_TOKEN}
```

**Response:**
```json
{
  "type": "password",
  "username": "user@example.com",
  "password": "secure_password",
  "totp": "JBSWY3DPEHPK3PXP",
  "totp_type": "authenticator"
}
```

### Delete Credential
```http
DELETE {API_BASE_URL}/{credential_id}
Authorization: Bearer {API_TOKEN}
```

**Response:** HTTP 200 (empty body acceptable)

## Configuration

### Environment Variables (Self-hosted)

Set these environment variables in your `.env` file:

```bash
CREDENTIAL_VAULT_TYPE=custom
CUSTOM_CREDENTIAL_API_BASE_URL=https://credentials.company.com/api/v1/credentials
CUSTOM_CREDENTIAL_API_TOKEN=your_api_token_here
```

### Organization Configuration (Cloud)

Use the Skyvern API to configure per-organization:

```http
POST /api/v1/credentials/custom_credential/create
Authorization: Bearer {SKYVERN_API_KEY}
Content-Type: application/json

{
  "config": {
    "api_base_url": "https://credentials.company.com/api/v1/credentials",
    "api_token": "your_api_token_here"
  }
}
```

### UI Configuration

1. Navigate to **Settings** → **Custom Credential Service**
2. Enter your API Base URL and API Token
3. Click **Test Connection** to verify connectivity
4. Click **Update Configuration** to save

## Example Implementation

Here's a minimal example using FastAPI:

```python
from fastapi import FastAPI, HTTPException, Depends, Header
from pydantic import BaseModel
from typing import Optional
import uuid

app = FastAPI()

# In-memory storage (use a real database in production)
credentials_store = {}

class CreateCredentialRequest(BaseModel):
    name: str
    type: str  # "password" or "credit_card"
    username: Optional[str] = None
    password: Optional[str] = None
    totp: Optional[str] = None
    totp_type: Optional[str] = None

class CredentialResponse(BaseModel):
    id: str

def verify_token(authorization: str = Header(...)):
    if not authorization.startswith("Bearer "):
        raise HTTPException(401, "Invalid authorization header")

    token = authorization.split("Bearer ")[1]
    if token != "your_expected_api_token":
        raise HTTPException(401, "Invalid API token")

@app.post("/api/v1/credentials", response_model=CredentialResponse)
async def create_credential(
    request: CreateCredentialRequest,
    _: None = Depends(verify_token)
):
    credential_id = f"cred_{uuid.uuid4().hex[:12]}"
    credentials_store[credential_id] = request.model_dump()
    return CredentialResponse(id=credential_id)

@app.get("/api/v1/credentials/{credential_id}")
async def get_credential(
    credential_id: str,
    _: None = Depends(verify_token)
):
    if credential_id not in credentials_store:
        raise HTTPException(404, "Credential not found")
    return credentials_store[credential_id]

@app.delete("/api/v1/credentials/{credential_id}")
async def delete_credential(
    credential_id: str,
    _: None = Depends(verify_token)
):
    if credential_id not in credentials_store:
        raise HTTPException(404, "Credential not found")
    del credentials_store[credential_id]
    return {"status": "deleted"}
```

## Security Considerations

- API tokens are stored encrypted in the database
- Bearer tokens are transmitted over HTTPS only
- Frontend masks sensitive tokens in the UI
- API credentials are never logged in plaintext
- Implement proper rate limiting and authentication in your API

## Troubleshooting

### Connection Test Fails

1. Verify API base URL is correct and accessible
2. Check that API token is valid
3. Check firewall and network connectivity
4. Note: Connection test only verifies basic connectivity - 404/405 responses are considered successful if the server is reachable

### Credentials Not Created

1. Review API logs for authentication errors
2. Verify request format matches expected schema
3. Ensure API returns `id` in response

### Environment Configuration Not Working

1. Restart Skyvern after setting environment variables
2. Verify `CREDENTIAL_VAULT_TYPE=custom` is set
3. Check both URL and token are provided

## Limitations

- Connection testing verifies network connectivity and basic API reachability but not full endpoint implementation
- API must support all required endpoints (no partial implementation)
- Token rotation requires manual reconfiguration
- No built-in credential synchronization between vaults
