Authentication

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

Overview

MIMS SDK 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 MIMSProvider 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 '@mims/sdk-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 '@mims/sdk-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:

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

Scope-Based Access Control

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

PropTypeDefaultDescription
documents:readscopeRead document metadata and download documents
documents:writescopeUpload, modify, and submit documents
signatures:writescopeAdd signatures to documents
fields:writescopeAdd and modify form fields

Check if a scope is available:

import { useSDK } from '@mims/sdk-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 requiredErrorNo API key was provided to the provider
Invalid API key formatErrorKey doesn't start with pk_ or sk_
API key validation failedErrorKey is invalid, expired, or revoked
Insufficient scopesErrorKey doesn't have required permissions for the operation
<MIMSProvider
  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}
</MIMSProvider>

Next Steps