Authentication

Understand how DocCentral authenticates with the API and how to manage API keys securely.

Overview

DocCentral uses API keys for authentication. When you initialize the SDK with an API key, it automatically validates the key and establishes an authenticated session. All subsequent API requests include this key in the headers.

API Key Types

There are two types of API keys:

PropTypeDefaultDescription
Publishable Keypk_live_* / pk_test_*-Safe for client-side use. Limited to SDK operations only. Cannot access admin endpoints.
Secret Keysk_live_* / sk_test_*-Server-side only. Full API access. Never expose in browser or client code.

Security Warning

Never use secret keys (sk_) in client-side code. Secret keys have full API access and could be extracted from browser DevTools, source code, or network requests.

Key Prefixes

API keys use prefixes to indicate their type and environment:

  • pk_live_ - Publishable key for production
  • pk_test_ - Publishable key for testing/sandbox
  • sk_live_ - Secret key for production
  • sk_test_ - Secret key for testing/sandbox

Authentication Flow

When the SDK initializes:

  1. The DocCentralProvider component receives your API key
  2. SDK validates the key format (must start with pk_ or sk_)
  3. SDK sends a validation request to the API
  4. API returns organization info and granted scopes
  5. SDK stores this info in context for child components
POST/sdk/validate-key

Validates API key and returns organization information

Responsejson
{
  "valid": true,
  "organizationId": "org_abc123",
  "organizationName": "Acme Corp",
  "scopes": ["documents:read", "documents:write", "signatures:write"],
  "expiresAt": null
}

Using Authentication State

Access authentication state in your components using the useSDK hook:

import { useSDK } from '@doccentral/react';

function MyComponent() {
  const { 
    isInitialized,
    isValidating,
    validationError,
    organizationId,
    organizationName,
    scopes,
  } = useSDK();

  if (isValidating) {
    return <LoadingSpinner />;
  }

  if (validationError) {
    return <ErrorMessage error={validationError} />;
  }

  return (
    <div>
      <p>Organization: {organizationName}</p>
      <p>Scopes: {scopes.join(', ')}</p>
    </div>
  );
}

Making Authenticated Requests

The SDK provides an apiRequest function that automatically includes authentication headers:

import { useSDK } from '@doccentral/react';

function CustomDocumentLoader() {
  const { apiRequest, isInitialized } = useSDK();

  const loadDocument = async (documentId: string) => {
    if (!isInitialized) return;

    try {
      const document = await apiRequest<DocumentResponse>(
        `/sdk/documents/${documentId}`,
        { method: 'GET' }
      );
      
      console.log('Document loaded:', document);
      return document;
    } catch (error) {
      console.error('Failed to load document:', error);
      throw error;
    }
  };

  // ...
}

Request Headers

All authenticated requests include these headers:

{
  "Content-Type": "application/json",
  "X-API-Key": "pk_live_your_api_key_here"
}

You can add custom headers via the provider:

<DocCentralProvider
  apiKey="pk_live_..."
  customHeaders={{
    'X-Request-ID': generateRequestId(),
    'X-Client-Version': '2.0.0',
  }}
>
  {children}
</DocCentralProvider>

Scope-Based Access Control

API keys are granted specific scopes that control what operations they can perform:

PropTypeDefaultDescription
documents:readscope-Read document metadata and download documents
documents:writescope-Upload, modify, and submit documents
signatures:writescope-Add signatures to documents
fields:writescope-Add and modify form fields

Check if a scope is available:

import { useSDK } from '@doccentral/react';

function ConditionalFeature() {
  const { scopes } = useSDK();

  const canSign = scopes.includes('signatures:write');
  const canEdit = scopes.includes('fields:write');

  return (
    <div>
      {canSign && <SignatureButton />}
      {canEdit && <EditFieldsButton />}
    </div>
  );
}

Error Handling

Common authentication errors and how to handle them:

PropTypeDefaultDescription
API key is requiredError-No API key was provided to the provider
Invalid API key formatError-Key doesn't start with pk_ or sk_
API key validation failedError-Key is invalid, expired, or revoked
Insufficient scopesError-Key doesn't have required permissions for the operation
<DocCentralProvider
  apiKey={apiKey}
  onError={(error) => {
    switch (error) {
      case 'API key is required':
        // Redirect to setup page
        router.push('/setup');
        break;
      case 'Invalid API key format':
        // Show configuration help
        showConfigurationHelp();
        break;
      default:
        // Generic error handling
        showErrorNotification(error);
    }
  }}
>
  {children}
</DocCentralProvider>

Next Steps