Skip to main content

Authentication

Gumnut supports multiple authentication methods to suit different use cases, from simple API keys for server-side applications to OAuth for user-facing integrations.

Authentication Methods

API Keys

API keys are the simplest way to authenticate with Gumnut. They’re ideal for:
  • Server-side applications
  • Scripts and automation
  • Development and testing
  • CI/CD pipelines

Creating an API Key

  1. Log into the Gumnut Dashboard
  2. Navigate to API Keys
  3. Click Create API Key
  4. Name your key descriptively (e.g., “Production Server”, “Development”)
  5. Copy and securely store the key
API keys are shown only once when created. Store them securely in environment variables or a secrets manager. Never commit API keys to version control.

Using API Keys

Include your API key in the Authorization header of your requests:
curl -X GET https://api.gumnut.ai/api/assets \
  -H "Authorization: Bearer apikey_your_api_key_here"
In the TypeScript SDK:
import Gumnut from 'gumnut-sdk';

const client = new Gumnut({
  apiKey: process.env.GUMNUT_API_KEY // Reads from environment variable
});
In the Python SDK:
from gumnut import Gumnut

client = Gumnut(
    api_key=os.environ.get("GUMNUT_API_KEY")
)

OAuth 2.1

Gumnut implements OAuth 2.1 through Clerk for secure, user-facing authentication. OAuth is ideal for:
  • Web applications
  • Mobile apps
  • Third-party integrations
  • Applications requiring user consent

How OAuth Works

OAuth allows third-party applications to access Gumnut resources on behalf of a user without exposing their credentials:
  1. Authorization Request: Your app redirects users to Gumnut’s authorization page
  2. User Consent: Users approve the requested permissions (scopes)
  3. Authorization Code: Gumnut redirects back with an authorization code
  4. Token Exchange: Your app exchanges the code for access tokens
  5. API Access: Use the access token to make authorized requests

OAuth Endpoints

Gumnut provides standard OAuth 2.1 endpoints:
  • Authorization: https://api.gumnut.ai/oauth/authorize
  • Token: https://api.gumnut.ai/oauth/token
  • Token Revocation: https://api.gumnut.ai/oauth/revoke

OAuth Metadata

OAuth metadata is available at these well-known endpoints:
  • Protected Resource: /.well-known/oauth-protected-resource/mcp
  • Authorization Server: /.well-known/oauth-authorization-server

Supported OAuth Flows

Authorization Code Flow with PKCE (Recommended):
// 1. Generate PKCE challenge
const codeVerifier = generateRandomString();
const codeChallenge = await sha256(codeVerifier);

// 2. Redirect to authorization
window.location.href = `https://api.gumnut.ai/oauth/authorize?
  client_id=${CLIENT_ID}&
  redirect_uri=${REDIRECT_URI}&
  response_type=code&
  scope=read:assets write:assets&
  code_challenge=${codeChallenge}&
  code_challenge_method=S256`;

// 3. Exchange code for token
const response = await fetch('https://api.gumnut.ai/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    grant_type: 'authorization_code',
    code: authorizationCode,
    client_id: CLIENT_ID,
    client_secret: CLIENT_SECRET,
    redirect_uri: REDIRECT_URI,
    code_verifier: codeVerifier
  })
});

OAuth Scopes

Control access with granular scopes:
  • read:assets - View photos and videos
  • write:assets - Upload and modify assets
  • read:albums - View albums
  • write:albums - Create and modify albums
  • read:people - View people and faces
  • write:people - Modify people data
  • read:libraries - View libraries
  • write:libraries - Modify libraries

Using OAuth Tokens

Once obtained, use OAuth tokens like API keys:
curl -X GET https://api.gumnut.ai/api/assets \
  -H "Authorization: Bearer oat_your_oauth_token"

Session Tokens (Web Applications)

For web applications using Clerk, session tokens are automatically managed through cookies:
// Clerk handles authentication automatically
import { useAuth } from '@clerk/nextjs';

function MyComponent() {
  const { getToken } = useAuth();
  
  const fetchAssets = async () => {
    const token = await getToken();
    const response = await fetch('https://api.gumnut.ai/api/assets', {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });
    return response.json();
  };
}

Security Best Practices

API Key Security

  • Environment Variables: Always store keys in environment variables
  • Rotation: Rotate keys periodically
  • Minimal Scope: Create separate keys for different environments
  • Monitoring: Track key usage in the dashboard
  • Revocation: Immediately revoke compromised keys

OAuth Security

  • PKCE: Always use PKCE for public clients
  • State Parameter: Include state to prevent CSRF attacks
  • Secure Storage: Store tokens securely (never in localStorage for sensitive data)
  • Token Refresh: Implement token refresh for long-lived sessions
  • Scope Limitation: Request only necessary scopes

HTTPS Only

All API requests must use HTTPS. HTTP requests will be rejected.

Rate Limiting

Authentication doesn’t bypass rate limits. See our API documentation in the API reference tab for current limits.

Error Handling

Common Authentication Errors

401 Unauthorized:
{
  "error": "unauthorized",
  "message": "Invalid or expired token"
}
Solution: Check your API key or refresh your OAuth token 403 Forbidden:
{
  "error": "forbidden",
  "message": "Insufficient permissions for this operation"
}
Solution: Ensure your token has the required scopes 429 Too Many Requests:
{
  "error": "rate_limited",
  "message": "Rate limit exceeded",
  "retry_after": 60
}
Solution: Implement exponential backoff and respect the retry_after header

WWW-Authenticate Headers

Failed authentication returns proper WWW-Authenticate headers:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="Gumnut API", scope="read:assets write:assets"

Token Management

API Key Management

View and manage API keys in the dashboard:
  • See creation date and last used time
  • Track usage statistics
  • Revoke keys instantly
  • Set expiration dates (coming soon)

OAuth Token Lifecycle

  1. Access Token: Short-lived (1 hour default)
  2. Refresh Token: Long-lived (30 days)
  3. Token Refresh: Exchange refresh token for new access token
  4. Revocation: Explicitly revoke tokens when needed
// Refresh an OAuth token
const response = await fetch('https://api.gumnut.ai/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    grant_type: 'refresh_token',
    refresh_token: REFRESH_TOKEN,
    client_id: CLIENT_ID,
    client_secret: CLIENT_SECRET
  })
});

Integration Examples

Node.js with API Key

const axios = require('axios');

const gumnutApi = axios.create({
  baseURL: 'https://api.gumnut.ai',
  headers: {
    'Authorization': `Bearer ${process.env.GUMNUT_API_KEY}`
  }
});

// Use the configured client
const assets = await gumnutApi.get('/api/assets');

Python with OAuth

import requests
from requests_oauthlib import OAuth2Session

# OAuth setup
client_id = 'your_client_id'
client_secret = 'your_client_secret'
redirect_uri = 'http://localhost:3000/callback'

# Create OAuth session
oauth = OAuth2Session(client_id, redirect_uri=redirect_uri)

# Get authorization URL
authorization_url, state = oauth.authorization_url(
    'https://api.gumnut.ai/oauth/authorize',
    scope=['read:assets', 'write:assets']
)

# After user authorizes, exchange code for token
token = oauth.fetch_token(
    'https://api.gumnut.ai/oauth/token',
    authorization_response=callback_url,
    client_secret=client_secret
)

# Make authenticated requests
response = oauth.get('https://api.gumnut.ai/api/assets')

React with Clerk

import { useAuth } from '@clerk/clerk-react';
import { useState, useEffect } from 'react';

function GumnutAssets() {
  const { getToken } = useAuth();
  const [assets, setAssets] = useState([]);

  useEffect(() => {
    const fetchAssets = async () => {
      const token = await getToken();
      const response = await fetch('https://api.gumnut.ai/api/assets', {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      });
      const data = await response.json();
      setAssets(data.assets);
    };
    
    fetchAssets();
  }, [getToken]);

  return (
    <div>
      {assets.map(asset => (
        <img key={asset.id} src={asset.thumbnail_url} alt={asset.id} />
      ))}
    </div>
  );
}

Troubleshooting

Invalid API Key

  • Verify the key is copied correctly
  • Check it hasn’t been revoked in the dashboard
  • Ensure you’re using the correct environment’s key

OAuth Redirect Issues

  • Verify redirect URI matches exactly (including trailing slashes)
  • Ensure redirect URI is whitelisted in your OAuth app settings
  • Check for URL encoding issues

Token Expiration

  • Implement token refresh logic for OAuth
  • Monitor token expiry times
  • Handle 401 responses gracefully with retry logic

CORS Issues (Browser)

  • OAuth tokens work in browsers with proper CORS headers
  • API keys should not be used in client-side code
  • Use a backend proxy for API key authentication

Next Steps

  • Explore the API Reference tab for all endpoints
  • Learn about Webhooks for real-time updates
  • Set up the MCP Server for AI tool integration
  • Review our SDKs for easier integration
I