Skip to main content
The Connectivity API uses a multi-layered authentication model to provide security, flexibility, and proper credential isolation. Understanding these layers is essential for building secure integrations.

Authentication Layers

Authentication in the Alloy Automation API operates at three distinct levels:
  1. Platform Authentication: Your application authenticates with Alloy Automation using an API key
  2. User Context: Each request specifies which user’s credentials to use
  3. Connector Credentials: Alloy Automation uses stored credentials to authenticate with third-party platforms

Platform Authentication

API Key

All requests to the Connectivity API require an API key passed via the Authorization header using Bearer token format.
curl https://production.runalloy.com/connectors \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-api-version: {API_VERSION}"
Security Best Practices:
  • Never expose your API key in client-side code - Always make API calls from your backend
  • Store API keys in environment variables or secure secret management systems
  • Rotate API keys periodically
  • Use different API keys for development, staging, and production environments

Required Headers

Every API request must include these headers:
HeaderValueDescription
AuthorizationBearer YOUR_API_KEYAuthenticates your application with Alloy Automation
x-api-version{API_VERSION}Specifies the API version to use
Content-Typeapplication/jsonRequired for POST/PUT requests

User Context Authentication

User ID Header

Operations that execute actions or manage credentials require specifying which user’s context to operate within. This is done via the x-alloy-userid header.
curl -X POST https://production.runalloy.com/connectors/hubspot/actions/createContact/execute \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-api-version: {API_VERSION}" \
  -H "x-alloy-userid: 68c3229752345278627ae373" \
  -H "Content-Type: application/json" \
  -d '{
    "credentialId": "68d2e2fd5aa2c97c2ae99c24",
    "requestBody": {
      "firstName": "Jane",
      "lastName": "Doe",
      "email": "jane.doe@example.com"
    }
  }'

When User ID Is Required

The x-alloy-userid header is required for:
  • Executing actions (POST /connectors/{connectorId}/actions/{actionId}/execute)
  • Creating credentials (POST /users/{userId}/credentials)
  • Listing user-specific credentials (GET /users/{userId}/credentials)
It is not required for:
  • Listing connectors (GET /connectors)
  • Getting connector metadata (GET /connectors/{connectorId})
  • Getting action schemas (GET /connectors/{connectorId}/actions/{actionId})
  • Creating users (POST /users)

Connector Credentials

Overview

Connector credentials are the authentication tokens or API keys that Alloy Automation uses to communicate with third-party platforms on behalf of your users. These credentials are stored securely by Alloy Automation and referenced by a credentialId.

Credential Types

Alloy Automation supports multiple authentication patterns:

OAuth 2.0

Used by most modern SaaS platforms (HubSpot, Salesforce, Notion, etc.). Alloy Automation handles the complete OAuth flow including token refresh. Flow:
  1. Initiate OAuth: Request an authorization URL
  2. User Authenticates: Redirect user to the authorization URL
  3. Token Exchange: Alloy Automation automatically exchanges the authorization code for access/refresh tokens
  4. Credential Created: Credential is attached to the user and ready for use
Example:
# Step 1: Initiate OAuth flow
curl -X POST https://production.runalloy.com/connectors/hubspot/credentials \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-api-version: {API_VERSION}" \
  -H "Content-Type: application/json" \
  -d '{
    "connectorId": "hubspot",
    "credentialType": "oauth2",
    "redirectUri": "https://your-app.com/oauth/callback"
  }'

# Response:
{
  "oauthUrl": "https://api.runalloy.com/api/strategy/connector/hubspot/authorize?userId=..."
}

# Step 2: Redirect user to oauthUrl
# Step 3: User authenticates and grants permissions
# Step 4: User is redirected back to your redirectUri
# Step 5: Alloy Automation exchanges the code and creates the credential

API Keys

Some platforms use API keys or custom authentication schemes. For these, you pass the authentication data directly.
curl -X POST https://production.runalloy.com/users/68c3229752345278627ae373/credentials \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-api-version: {API_VERSION}" \
  -H "Content-Type: application/json" \
  -d '{
    "connectorId": "quickbooks",
    "credentialType": "apiKey",
    "data": {
      "apiKey": "user_provided_api_key",
      "apiSecret": "user_provided_secret"
    }
  }'

Discovering Required Credentials

Before creating credentials, discover what authentication data a connector requires:
curl https://production.runalloy.com/connectors/hubspot/credentials \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-api-version: {API_VERSION}"
Response:
{
  "metadata": [
    {
      "authenticationType": "oauth2",
      "inputSchema": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string"
          },
          "redirectUri": {
            "type": "string"
          }
        },
        "required": ["userId", "redirectUri"]
      }
    }
  ]
}
Use this schema to:
  • Determine the authentication type
  • Identify required fields
  • Build dynamic credential collection forms
  • Validate input before submission

Using Credentials

Once a credential is created and attached to a user, reference it when executing actions:
curl -X POST https://production.runalloy.com/connectors/hubspot/actions/listContacts/execute \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-api-version: {API_VERSION}" \
  -H "x-alloy-userid: 68c3229752345278627ae373" \
  -H "Content-Type: application/json" \
  -d '{
    "credentialId": "68d2e2fd5aa2c97c2ae99c24",
    "input": {
      "limit": 100
    }
  }'

Credential Lifecycle

Automatic Token Refresh: For OAuth credentials, Alloy Automation automatically refreshes access tokens when they expire. You don’t need to handle token refresh logic. Credential Invalidation: Credentials become invalid when:
  • User revokes access in the third-party platform
  • OAuth tokens are manually revoked
  • API keys are rotated or deleted
Error Handling: When credentials are invalid, the API returns:
{
  "error": {
    "source": "CONNECTIVITY_API",
    "code": "INVALID_CREDENTIAL",
    "message": "Credential not found or has been revoked",
    "details": {
      "credentialId": "68d2e2fd5aa2c97c2ae99c24"
    }
  }
}

Security Architecture

What You Store

You are responsible for securely storing:
  • Your Alloy Automation API key - Authenticates your application
  • User-to-Credential mappings - Which of your users have access to which Alloy Automation credentialId values
  • User context - Your own user authentication and session management

What Alloy Automation Stores

Alloy Automation securely stores:
  • OAuth access and refresh tokens - Encrypted at rest
  • API keys and secrets - Encrypted at rest
  • Credential metadata - Connector type, creation date, last used, etc.
Key Principles:
  1. API keys never touch the frontend - All Alloy Automation API calls from your backend
  2. Credential IDs are safe to store - They’re useless without your API key
  3. User context is your responsibility - Ensure users can only access their own credentials
  4. OAuth flows can initiate from frontend - But final credential storage happens server-side

Authentication Errors

Common Error Scenarios

Invalid API Key

{
  "message": "Invalid Authorization"
}
Solution: Verify your API key is correct and has not been rotated.

Missing API Version Header

{
  "errorHtml": "<!DOCTYPE html>...Cannot GET /connectors..."
}
Solution: Include x-api-version: {API_VERSION} header in all requests.

Invalid User ID

{
  "error": {
    "source": "CONNECTIVITY_API",
    "code": "INVALID_USER",
    "message": "User not found",
    "details": {
      "userId": "invalid_user_id"
    }
  }
}
Solution: Ensure the user exists and the x-alloy-userid header is correct.

Invalid Credential ID

{
  "error": {
    "source": "CONNECTIVITY_API",
    "code": "INVALID_INPUT",
    "message": "Credential not found",
    "details": {}
  }
}
Solution: Verify the credential exists, belongs to the specified user, and hasn’t been revoked.

Testing Authentication

Verify Platform Access

Test your API key by listing available connectors:
curl https://production.runalloy.com/connectors \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-api-version: {API_VERSION}"
Successful response indicates your API key is valid.

Test User Context

Create a test user and verify it was created:
# Create user
curl -X POST https://production.runalloy.com/users \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-api-version: {API_VERSION}" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "test_user_001",
    "fullName": "Test User"
  }'

# Response includes userId
{
  "userId": "68c3229752345278627ae373"
}

Test Credential Flow

Use a sandbox account (HubSpot developer account, Notion personal workspace) to test the complete credential flow without affecting production data.

Next Steps

Need Help?

I