Secure Your API: A Complete Guide to API Authentication in ElmapiCMS
API authentication is essential for securing your ElmapiCMS API and controlling who can access your content. Whether you're building a public blog or a private application, understanding how authentication works in ElmapiCMS API will help you protect your content and grant appropriate access to different services.
In this guide, we'll walk through everything you need to know about API authentication in ElmapiCMS, from basic token creation to advanced security practices.
Table of Contents
- What is API Authentication in ElmapiCMS?
- Understanding Project ID and API Endpoint
- Public vs Private API
- Step 1: Access API Settings
- Step 2: Create Your First API Token
- Step 3: Understanding Token Abilities
- Step 4: Using Tokens in API Requests
- Step 5: Using the JavaScript SDK
- Real-World Examples
- Security Best Practices
- Troubleshooting
- Next Steps
- Conclusion
What is API Authentication in ElmapiCMS?
API authentication in ElmapiCMS is how you prove your identity when making API requests. It uses API tokens (also called access tokens) that you generate in the admin panel. These tokens grant specific permissions (called "abilities") to read, create, update, or delete content.
Key concepts:
- API Tokens: Secure strings that authenticate your requests
- Token Abilities: Permissions that define what a token can do (
read,create,update,delete) - Project ID: A unique identifier for your project, required in every API request
- Public API: Option to allow unauthenticated GET requests
How it works:
- You create an API token in the admin panel
- You assign specific abilities to the token
- You include the token in API request headers
- ElmapiCMS validates the token and checks its abilities
- The request is allowed or denied based on the token's permissions
Understanding Project ID and API Endpoint
Every API request in ElmapiCMS requires two essential pieces of information:
Project ID
The Project ID is a unique UUID that identifies which project you're accessing. Since ElmapiCMS supports multiple projects, this ID tells the API which project's content to return.
- Format: UUID (e.g.,
a1b2c3d4-e5f6-7890-1234-567890abcdef) - Required: Yes, in every API request
- Where to find it: API Access settings page in your project
- How to use: Include it in the
project-idheader
Content API Endpoint
The Content API Endpoint is the base URL for all your API requests.
- Format:
https://your-domain.com/apiorhttp://localhost:8000/api - Required: Yes, for all API calls
- Where to find it: API Access settings page
- How to use: Base URL for all collection endpoints
Example endpoints:
- List entries:
https://your-domain.com/api/blog-posts - Get entry:
https://your-domain.com/api/blog-posts/{uuid} - Create entry:
POST https://your-domain.com/api/blog-posts
Public vs Private API
ElmapiCMS gives you control over whether your API requires API authentication for reading content.
Public API (GET requests only)
When Public API is enabled:
- ✅ Unauthenticated GET requests are allowed
- ✅ No token required for reading content
- ❌ POST, PUT, DELETE still require tokens with appropriate abilities
- ✅ Perfect for public blogs, documentation sites, or static site generators
Use case: A public blog where anyone can read content, but only authorized users can create or modify it.
Private API
When Public API is disabled:
- ❌ All requests require API authentication
- ✅ Token with
readability required for GET requests - ✅ More secure, suitable for private content or applications
Use case: A private application, internal documentation, or content that should only be accessible to authenticated users.
Important: Regardless of the Public API setting, POST, PUT, and DELETE requests always require tokens with the appropriate abilities (
create,update,delete).
Step 1: Access API Settings
-
Navigate to Your Project
- Log in to your ElmapiCMS admin panel
- Select the project where you want to configure API access
-
Open API Access Settings
- Click on API Access in the left sidebar
- You'll see the API Access page with:
- Project ID and Content API Endpoint
- Public API toggle
- List of existing tokens (if any)
-
Copy Your Project ID
- Click the copy button next to Project ID
- Save this value - you'll need it for all API requests
-
Note Your API Endpoint
- The Content API Endpoint is displayed
- This is your base URL for all API calls
Step 2: Create Your First API Token
-
Click "Create Token"
- This opens the token creation form
-
Enter Token Name
- Give your token a descriptive name (e.g., "Next.js Blog", "Mobile App", "Staging Environment")
- This helps you identify the token's purpose later
-
Select Token Abilities
- Choose one or more abilities based on what this token needs to do:
read: Allows GET requests to read contentcreate: Allows POST requests to create content and upload assetsupdate: Allows PUT/PATCH requests to update contentdelete: Allows DELETE requests to delete content and assets
- Choose one or more abilities based on what this token needs to do:
-
Create the Token
- Click Create to generate the token
- Important: Copy the token immediately - you won't be able to see it again!
- Store it securely (environment variables, password manager, etc.)
-
View Your Tokens
- The token appears in the tokens list with:
- Name
- Abilities (comma-separated list)
- Edit and Delete buttons
- The token appears in the tokens list with:
Step 3: Understanding Token Abilities
Token abilities define what actions a token can perform. Each ability corresponds to specific HTTP methods and endpoints.
Ability Matrix
| Ability | HTTP Methods | Endpoints | Use Case |
|---|---|---|---|
read | GET | All collection endpoints, asset endpoints | Reading content, fetching entries |
create | POST | Create entries, upload assets | Creating new content, uploading files |
update | PUT, PATCH | Update entries | Modifying existing content |
delete | DELETE | Delete entries, delete assets | Removing content or files |
Common Token Configurations
Read-Only Token (for Static Site Generators)
- Abilities:
readonly - Use case: Next.js, Gatsby, Nuxt.js builds that only fetch content
- Security: Minimal risk - can't modify content
Full Access Token (for Admin Applications)
- Abilities:
read,create,update,delete - Use case: Admin panels, content management tools
- Security: High risk - can do everything
Content Management Token (for Editors)
- Abilities:
read,create,update - Use case: Applications that create/edit content but shouldn't delete
- Security: Medium risk - can modify but not delete
Upload Token (for Media Management)
- Abilities:
read,create - Use case: Applications that only upload assets
- Security: Low risk - can only add, not modify or delete
Principle of Least Privilege
Always grant the minimum abilities needed for a token's purpose:
- ✅ A static site generator only needs
read - ✅ A content editor might need
read,create,update - ✅ Only admin tools should have
deleteability
Step 4: Using Tokens in API Requests
To authenticate API requests, include your token in the Authorization header using the Bearer token format.
Required Headers
Every authenticated API request needs these headers:
Accept: application/json
Authorization: Bearer YOUR_API_TOKEN
project-id: YOUR_PROJECT_UUID
Example: Using cURL
curl -X GET "https://your-domain.com/api/blog-posts" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "project-id: YOUR_PROJECT_UUID"
Example: Using Fetch (JavaScript)
const response = await fetch('https://your-domain.com/api/blog-posts', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer YOUR_API_TOKEN',
'project-id': 'YOUR_PROJECT_UUID'
}
});
const data = await response.json();
Example: Using Axios
import axios from 'axios';
const response = await axios.get('https://your-domain.com/api/blog-posts', {
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer YOUR_API_TOKEN',
'project-id': 'YOUR_PROJECT_UUID'
}
});
Example: Using PHP (Laravel)
use Illuminate\Support\Facades\Http;
$response = Http::withHeaders([
'Accept' => 'application/json',
'Authorization' => 'Bearer YOUR_API_TOKEN',
'project-id' => 'YOUR_PROJECT_UUID'
])->get('https://your-domain.com/api/blog-posts');
Public API Requests (No Token Required)
If Public API is enabled, you can make GET requests without a token:
// No Authorization header needed for GET requests
const response = await fetch('https://your-domain.com/api/blog-posts', {
method: 'GET',
headers: {
'Accept': 'application/json',
'project-id': 'YOUR_PROJECT_UUID' // Still required
}
});
Step 5: Using the JavaScript SDK
The easiest way to use API authentication with ElmapiCMS is through the official JavaScript SDK. It handles authentication headers automatically.
Installation
npm install @elmapicms/js-sdk
Creating a Client
import { createClient } from '@elmapicms/js-sdk';
const client = createClient(
'https://your-domain.com/api', // API endpoint
'YOUR_API_TOKEN', // Your token (optional if Public API is enabled)
'YOUR_PROJECT_UUID' // Project ID
);
Making Authenticated Requests
The SDK automatically includes authentication headers:
// Get entries (requires 'read' ability or Public API enabled)
const posts = await client.getEntries('blog-posts');
// Get single entry
const post = await client.getEntry('blog-posts', 'entry-uuid');
// Create entry (requires 'create' ability)
const newPost = await client.createEntry('blog-posts', {
locale: 'en',
state: 'published',
data: {
title: 'My New Post',
slug: 'my-new-post',
content: '<p>Post content...</p>'
}
});
// Update entry (requires 'update' ability)
const updatedPost = await client.updateEntry('blog-posts', 'entry-uuid', {
data: {
title: 'Updated Title'
}
});
// Delete entry (requires 'delete' ability)
await client.deleteEntry('blog-posts', 'entry-uuid');
Environment Variables Setup
Store your credentials securely using environment variables:
.env.local (Next.js, Nuxt.js, etc.):
ELMAPI_API_URL=https://your-domain.com/api
ELMAPI_API_KEY=your-api-token-here
ELMAPI_PROJECT_ID=your-project-uuid-here
Using environment variables:
import { createClient } from '@elmapicms/js-sdk';
const client = createClient(
process.env.ELMAPI_API_URL,
process.env.ELMAPI_API_KEY, // Can be empty string if Public API is enabled
process.env.ELMAPI_PROJECT_ID
);
Real-World Examples
Example 1: Public Blog (Public API Enabled)
Scenario: A public blog where anyone can read content, but only you can edit it.
Setup:
- Enable Public API in API Access settings
- Create a token with
read,create,updateabilities for your admin tools - Frontend can read without authentication
- Admin tools use the token for content management
Frontend (No Token):
// Public API enabled - no token needed for GET requests
const client = createClient(
'https://your-domain.com/api',
'', // Empty token - not needed for public reads
'YOUR_PROJECT_UUID'
);
const posts = await client.getEntries('blog-posts');
Admin Tool (With Token):
// Admin tool needs token for create/update
const adminClient = createClient(
'https://your-domain.com/api',
'YOUR_ADMIN_TOKEN', // Token with create/update abilities
'YOUR_PROJECT_UUID'
);
await adminClient.createEntry('blog-posts', { /* ... */ });
Example 2: Private Application (Public API Disabled)
Scenario: A private application where all content requires API authentication.
Setup:
- Disable Public API in API Access settings
- Create tokens with
readability for your application - All requests require API authentication
Application Code:
// All requests require API authentication
const client = createClient(
'https://your-domain.com/api',
'YOUR_READ_TOKEN', // Required - token with 'read' ability
'YOUR_PROJECT_UUID'
);
const posts = await client.getEntries('blog-posts');
Example 3: Static Site Generator (Read-Only Token)
Scenario: A Next.js site that builds at deploy time and only reads content.
Setup:
- Create a token with only
readability - Use it in your build process
- Store it as an environment variable in your deployment platform
Next.js API Client:
// lib/elmapi.ts
import { createClient } from '@elmapicms/js-sdk';
const client = createClient(
process.env.ELMAPI_API_URL!,
process.env.ELMAPI_API_KEY!, // Read-only token
process.env.ELMAPI_PROJECT_ID!
);
export async function getPosts() {
return await client.getEntries('blog-posts');
}
Environment Variables (Vercel, Netlify, etc.):
ELMAPI_API_URL=https://your-domain.com/api
ELMAPI_API_KEY=your-read-only-token
ELMAPI_PROJECT_ID=your-project-uuid
Example 4: Multi-Environment Setup
Scenario: Different tokens for development, staging, and production.
Setup:
- Create separate tokens for each environment:
- "Development" token
- "Staging" token
- "Production" token
- Use environment-specific tokens in each environment
Environment Configuration:
// Development
const devClient = createClient(
'http://localhost:8000/api',
process.env.ELMAPI_DEV_TOKEN,
process.env.ELMAPI_DEV_PROJECT_ID
);
// Production
const prodClient = createClient(
'https://api.yourdomain.com/api',
process.env.ELMAPI_PROD_TOKEN,
process.env.ELMAPI_PROD_PROJECT_ID
);
Security Best Practices
1. Use Separate Tokens for Different Purposes
Why: Limits damage if a token is compromised.
How:
- Create one token for your static site generator (read-only)
- Create another for your admin panel (full access)
- Create separate tokens for staging and production
2. Follow the Principle of Least Privilege
Why: Minimizes risk by granting only necessary permissions.
How:
- Only grant abilities the token actually needs
- Use read-only tokens when possible
- Avoid giving
deleteability unless absolutely necessary
3. Store Tokens Securely
Why: Prevents unauthorized access if your code is exposed.
How:
- Never commit tokens to version control
- Use environment variables
- Use secret management services (Vercel, Netlify, AWS Secrets Manager)
- Rotate tokens regularly
4. Use Different Tokens Per Environment
Why: Limits impact if one environment is compromised.
How:
- Create separate tokens for development, staging, and production
- Use different project IDs if possible
- Never use production tokens in development
5. Regularly Rotate Tokens
Why: Reduces risk from compromised tokens.
How:
- Delete old tokens when creating new ones
- Rotate tokens every 90 days (or as your security policy requires)
- Update tokens in all applications when rotating
6. Monitor Token Usage
Why: Helps detect unauthorized access.
How:
- Review token list regularly
- Delete unused tokens
- Use descriptive token names to track usage
7. Enable Public API Only When Needed
Why: Reduces attack surface.
How:
- Disable Public API for private applications
- Only enable it for truly public content
- Remember: POST/PUT/DELETE always require tokens
Troubleshooting
Problem: "401 Unauthorized" Error
Possible causes:
- Missing or invalid token
- Token doesn't have required ability
- Public API disabled but no token provided
Solutions:
- Verify token is included in
Authorization: Bearer YOUR_TOKENheader - Check token has the required ability (read, create, update, delete)
- If Public API is disabled, ensure token is provided for GET requests
- Verify token hasn't been deleted or revoked
Problem: "403 Forbidden" Error
Possible causes:
- Token doesn't have the required ability
- Trying to perform action token isn't authorized for
Solutions:
- Check token abilities in API Access settings
- Verify token has the ability needed for the operation:
- GET requests need
readability - POST requests need
createability - PUT/PATCH requests need
updateability - DELETE requests need
deleteability
- GET requests need
- Edit token to add required abilities if needed
Problem: "404 Not Found" Error
Possible causes:
- Incorrect project ID
- Wrong API endpoint URL
- Collection doesn't exist
Solutions:
- Verify
project-idheader matches your project's UUID - Check API endpoint URL is correct
- Ensure collection slug is correct
- Verify you're accessing the right project
Problem: Token Works in Development but Not Production
Possible causes:
- Different project IDs
- Different API endpoints
- Environment variables not set correctly
Solutions:
- Verify environment variables are set in production
- Check API endpoint URL is correct for production
- Ensure project ID matches production project
- Verify token exists in production project's API Access settings
Problem: Public API Not Working
Possible causes:
- Public API toggle is disabled
- Making POST/PUT/DELETE requests (always require tokens)
Solutions:
- Enable Public API toggle in API Access settings
- Remember: Public API only applies to GET requests
- POST, PUT, DELETE always require tokens regardless of Public API setting
Next Steps
Now that you understand API authentication in ElmapiCMS, you can:
- Create Your First Token - Set up API authentication for your application
- Configure Public API - Decide whether to allow unauthenticated reads
- Set Up Environment Variables - Securely store your credentials
- Use the JavaScript SDK - Simplify API authentication in your applications
- Implement Multi-Environment Setup - Use different tokens for dev/staging/prod
- Read the API Documentation - Explore the Content API Reference for detailed endpoint documentation
Conclusion
API authentication is a fundamental aspect of securing your ElmapiCMS API. By understanding how to:
- Create and manage API tokens
- Configure token abilities
- Use tokens in API requests
- Follow security best practices
You can build secure applications that properly control access to your content. Whether you're building a public blog or a private application, ElmapiCMS's flexible API authentication system gives you the control you need.
Ready to get started? Create your first API token, configure your API authentication, and start building secure applications with ElmapiCMS!
Need help? Check out the ElmapiCMS Documentation or reach out to [email protected].
